aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/https/x509/x509_write.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/https/x509/x509_write.c')
-rw-r--r--src/daemon/https/x509/x509_write.c1095
1 files changed, 0 insertions, 1095 deletions
diff --git a/src/daemon/https/x509/x509_write.c b/src/daemon/https/x509/x509_write.c
deleted file mode 100644
index 342e117d..00000000
--- a/src/daemon/https/x509/x509_write.c
+++ /dev/null
@@ -1,1095 +0,0 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This file contains functions to handle X.509 certificate generation.
26 */
27
28#include <gnutls_int.h>
29
30#ifdef ENABLE_PKI
31
32#include <gnutls_datum.h>
33#include <gnutls_global.h>
34#include <gnutls_errors.h>
35#include <common.h>
36#include <gnutls_x509.h>
37#include <x509_b64.h>
38#include <crq.h>
39#include <dn.h>
40#include <mpi.h>
41#include <sign.h>
42#include <extensions.h>
43#include <libtasn1.h>
44
45static void disable_optional_stuff (gnutls_x509_crt_t cert);
46
47/**
48 * gnutls_x509_crt_set_dn_by_oid - This function will set the Certificate request subject's distinguished name
49 * @crt: should contain a gnutls_x509_crt_t structure
50 * @oid: holds an Object Identifier in a null terminated string
51 * @raw_flag: must be 0, or 1 if the data are DER encoded
52 * @name: a pointer to the name
53 * @sizeof_name: holds the size of @name
54 *
55 * This function will set the part of the name of the Certificate subject, specified
56 * by the given OID. The input string should be ASCII or UTF-8 encoded.
57 *
58 * Some helper macros with popular OIDs can be found in gnutls/x509.h
59 * With this function you can only set the known OIDs. You can test
60 * for known OIDs using gnutls_x509_dn_oid_known(). For OIDs that are
61 * not known (by gnutls) you should properly DER encode your data, and
62 * call this function with raw_flag set.
63 *
64 * Returns 0 on success.
65 *
66 **/
67int
68gnutls_x509_crt_set_dn_by_oid (gnutls_x509_crt_t crt, const char *oid,
69 unsigned int raw_flag, const void *name,
70 unsigned int sizeof_name)
71{
72 if (sizeof_name == 0 || name == NULL || crt == NULL)
73 {
74 return GNUTLS_E_INVALID_REQUEST;
75 }
76
77 return _gnutls_x509_set_dn_oid (crt->cert, "tbsCertificate.subject",
78 oid, raw_flag, name, sizeof_name);
79}
80
81/**
82 * gnutls_x509_crt_set_issuer_dn_by_oid - This function will set the Certificate request issuer's distinguished name
83 * @crt: should contain a gnutls_x509_crt_t structure
84 * @oid: holds an Object Identifier in a null terminated string
85 * @raw_flag: must be 0, or 1 if the data are DER encoded
86 * @name: a pointer to the name
87 * @sizeof_name: holds the size of @name
88 *
89 * This function will set the part of the name of the Certificate issuer, specified
90 * by the given OID. The input string should be ASCII or UTF-8 encoded.
91 *
92 * Some helper macros with popular OIDs can be found in gnutls/x509.h
93 * With this function you can only set the known OIDs. You can test
94 * for known OIDs using gnutls_x509_dn_oid_known(). For OIDs that are
95 * not known (by gnutls) you should properly DER encode your data, and
96 * call this function with raw_flag set.
97 *
98 * Normally you do not need to call this function, since the signing
99 * operation will copy the signer's name as the issuer of the certificate.
100 *
101 * Returns 0 on success.
102 *
103 **/
104int
105gnutls_x509_crt_set_issuer_dn_by_oid (gnutls_x509_crt_t crt,
106 const char *oid,
107 unsigned int raw_flag,
108 const void *name,
109 unsigned int sizeof_name)
110{
111 if (sizeof_name == 0 || name == NULL || crt == NULL)
112 {
113 return GNUTLS_E_INVALID_REQUEST;
114 }
115
116 return _gnutls_x509_set_dn_oid (crt->cert, "tbsCertificate.issuer", oid,
117 raw_flag, name, sizeof_name);
118}
119
120/**
121 * gnutls_x509_crt_set_proxy_dn - Set Proxy Certificate subject's distinguished name
122 * @crt: a gnutls_x509_crt_t structure with the new proxy cert
123 * @eecrt: the end entity certificate that will be issuing the proxy
124 * @raw_flag: must be 0, or 1 if the CN is DER encoded
125 * @name: a pointer to the CN name, may be NULL (but MUST then be added later)
126 * @sizeof_name: holds the size of @name
127 *
128 * This function will set the subject in @crt to the end entity's
129 * @eecrt subject name, and add a single Common Name component @name
130 * of size @sizeof_name. This corresponds to the required proxy
131 * certificate naming style. Note that if @name is %NULL, you MUST
132 * set it later by using gnutls_x509_crt_set_dn_by_oid() or similar.
133 *
134 * Returns 0 on success.
135 *
136 **/
137int
138gnutls_x509_crt_set_proxy_dn (gnutls_x509_crt_t crt, gnutls_x509_crt_t eecrt,
139 unsigned int raw_flag, const void *name,
140 unsigned int sizeof_name)
141{
142 int result;
143
144 if (crt == NULL || eecrt == NULL)
145 {
146 return GNUTLS_E_INVALID_REQUEST;
147 }
148
149 result = asn1_copy_node (crt->cert, "tbsCertificate.subject",
150 eecrt->cert, "tbsCertificate.subject");
151 if (result != ASN1_SUCCESS)
152 {
153 gnutls_assert ();
154 return mhd_gtls_asn2err (result);
155 }
156
157 if (name && sizeof_name)
158 {
159 return _gnutls_x509_set_dn_oid (crt->cert, "tbsCertificate.subject",
160 GNUTLS_OID_X520_COMMON_NAME,
161 raw_flag, name, sizeof_name);
162 }
163
164 return 0;
165}
166
167/**
168 * gnutls_x509_crt_set_version - This function will set the Certificate request version
169 * @crt: should contain a gnutls_x509_crt_t structure
170 * @version: holds the version number. For X.509v1 certificates must be 1.
171 *
172 * This function will set the version of the certificate. This must
173 * be one for X.509 version 1, and so on. Plain certificates without
174 * extensions must have version set to one.
175 *
176 * To create well-formed certificates, you must specify version 3 if
177 * you use any certificate extensions. Extensions are created by
178 * functions such as gnutls_x509_crt_set_subject_alternative_name or
179 * gnutls_x509_crt_set_key_usage.
180 *
181 * Returns 0 on success.
182 *
183 **/
184int
185gnutls_x509_crt_set_version (gnutls_x509_crt_t crt, unsigned int version)
186{
187 int result;
188 unsigned char null = version;
189
190 if (crt == NULL)
191 {
192 gnutls_assert ();
193 return GNUTLS_E_INVALID_REQUEST;
194 }
195
196 if (null > 0)
197 null--;
198
199 result = asn1_write_value (crt->cert, "tbsCertificate.version", &null, 1);
200 if (result != ASN1_SUCCESS)
201 {
202 gnutls_assert ();
203 return mhd_gtls_asn2err (result);
204 }
205
206 return 0;
207}
208
209/**
210 * gnutls_x509_crt_set_key - This function will associate the Certificate with a key
211 * @crt: should contain a gnutls_x509_crt_t structure
212 * @key: holds a private key
213 *
214 * This function will set the public parameters from the given private key to the
215 * certificate. Only RSA keys are currently supported.
216 *
217 * Returns 0 on success.
218 *
219 **/
220int
221gnutls_x509_crt_set_key (gnutls_x509_crt_t crt, gnutls_x509_privkey_t key)
222{
223 int result;
224
225 if (crt == NULL)
226 {
227 gnutls_assert ();
228 return GNUTLS_E_INVALID_REQUEST;
229 }
230
231 result = _gnutls_x509_encode_and_copy_PKI_params (crt->cert,
232 "tbsCertificate.subjectPublicKeyInfo",
233 key->pk_algorithm,
234 key->params,
235 key->params_size);
236
237 if (result < 0)
238 {
239 gnutls_assert ();
240 return result;
241 }
242
243 return 0;
244}
245
246/**
247 * gnutls_x509_crt_set_crq - This function will associate the Certificate with a request
248 * @crt: should contain a gnutls_x509_crt_t structure
249 * @crq: holds a certificate request
250 *
251 * This function will set the name and public parameters from the given certificate request to the
252 * certificate. Only RSA keys are currently supported.
253 *
254 * Returns 0 on success.
255 *
256 **/
257int
258gnutls_x509_crt_set_crq (gnutls_x509_crt_t crt, gnutls_x509_crq_t crq)
259{
260 int result;
261 int pk_algorithm;
262
263 if (crt == NULL || crq == NULL)
264 {
265 gnutls_assert ();
266 return GNUTLS_E_INVALID_REQUEST;
267 }
268
269 pk_algorithm = gnutls_x509_crq_get_pk_algorithm (crq, NULL);
270
271 result = asn1_copy_node (crt->cert, "tbsCertificate.subject",
272 crq->crq, "certificationRequestInfo.subject");
273 if (result != ASN1_SUCCESS)
274 {
275 gnutls_assert ();
276 return mhd_gtls_asn2err (result);
277 }
278
279 result =
280 asn1_copy_node (crt->cert, "tbsCertificate.subjectPublicKeyInfo",
281 crq->crq, "certificationRequestInfo.subjectPKInfo");
282 if (result != ASN1_SUCCESS)
283 {
284 gnutls_assert ();
285 return mhd_gtls_asn2err (result);
286 }
287
288 return 0;
289}
290
291/**
292 * gnutls_x509_crt_set_extension_by_oid - This function will set an arbitrary extension
293 * @crt: should contain a gnutls_x509_crt_t structure
294 * @oid: holds an Object Identified in null terminated string
295 * @buf: a pointer to a DER encoded data
296 * @sizeof_buf: holds the size of @buf
297 * @critical: should be non zero if the extension is to be marked as critical
298 *
299 * This function will set an the extension, by the specified OID, in the certificate.
300 * The extension data should be binary data DER encoded.
301 *
302 * Returns 0 on success and a negative value in case of an error.
303 *
304 **/
305int
306gnutls_x509_crt_set_extension_by_oid (gnutls_x509_crt_t crt,
307 const char *oid, const void *buf,
308 size_t sizeof_buf,
309 unsigned int critical)
310{
311 int result;
312 gnutls_datum_t der_data;
313
314 der_data.data = (void *) buf;
315 der_data.size = sizeof_buf;
316
317 if (crt == NULL)
318 {
319 gnutls_assert ();
320 return GNUTLS_E_INVALID_REQUEST;
321 }
322
323 result = _gnutls_x509_crt_set_extension (crt, oid, &der_data, critical);
324 if (result < 0)
325 {
326 gnutls_assert ();
327 return result;
328 }
329
330 crt->use_extensions = 1;
331
332 return 0;
333
334}
335
336/**
337 * gnutls_x509_crt_set_basic_constraints - This function will set the basicConstraints extension
338 * @crt: should contain a gnutls_x509_crt_t structure
339 * @ca: true(1) or false(0). Depending on the Certificate authority status.
340 * @pathLenConstraint: non-negative values indicate maximum length of path,
341 * and negative values indicate that the pathLenConstraints field should
342 * not be present.
343 *
344 * This function will set the basicConstraints certificate extension.
345 *
346 * Returns 0 on success.
347 *
348 **/
349int
350gnutls_x509_crt_set_basic_constraints (gnutls_x509_crt_t crt,
351 unsigned int ca, int pathLenConstraint)
352{
353 int result;
354 gnutls_datum_t der_data;
355
356 if (crt == NULL)
357 {
358 gnutls_assert ();
359 return GNUTLS_E_INVALID_REQUEST;
360 }
361
362 /* generate the extension.
363 */
364 result = _gnutls_x509_ext_gen_basicConstraints (ca, pathLenConstraint,
365 &der_data);
366 if (result < 0)
367 {
368 gnutls_assert ();
369 return result;
370 }
371
372 result = _gnutls_x509_crt_set_extension (crt, "2.5.29.19", &der_data, 1);
373
374 _gnutls_free_datum (&der_data);
375
376 if (result < 0)
377 {
378 gnutls_assert ();
379 return result;
380 }
381
382 crt->use_extensions = 1;
383
384 return 0;
385}
386
387/**
388 * gnutls_x509_crt_set_ca_status - This function will set the basicConstraints extension
389 * @crt: should contain a gnutls_x509_crt_t structure
390 * @ca: true(1) or false(0). Depending on the Certificate authority status.
391 *
392 * This function will set the basicConstraints certificate extension.
393 * Use gnutls_x509_crt_set_basic_constraints() if you want to control
394 * the pathLenConstraint field too.
395 *
396 * Returns 0 on success.
397 *
398 **/
399int
400gnutls_x509_crt_set_ca_status (gnutls_x509_crt_t crt, unsigned int ca)
401{
402 return gnutls_x509_crt_set_basic_constraints (crt, ca, -1);
403}
404
405/**
406 * gnutls_x509_crt_set_key_usage - This function will set the keyUsage extension
407 * @crt: should contain a gnutls_x509_crt_t structure
408 * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
409 *
410 * This function will set the keyUsage certificate extension.
411 *
412 * Returns 0 on success.
413 *
414 **/
415int
416gnutls_x509_crt_set_key_usage (gnutls_x509_crt_t crt, unsigned int usage)
417{
418 int result;
419 gnutls_datum_t der_data;
420
421 if (crt == NULL)
422 {
423 gnutls_assert ();
424 return GNUTLS_E_INVALID_REQUEST;
425 }
426
427 /* generate the extension.
428 */
429 result = _gnutls_x509_ext_gen_keyUsage ((uint16_t) usage, &der_data);
430 if (result < 0)
431 {
432 gnutls_assert ();
433 return result;
434 }
435
436 result = _gnutls_x509_crt_set_extension (crt, "2.5.29.15", &der_data, 1);
437
438 _gnutls_free_datum (&der_data);
439
440 if (result < 0)
441 {
442 gnutls_assert ();
443 return result;
444 }
445
446 crt->use_extensions = 1;
447
448 return 0;
449}
450
451/**
452 * gnutls_x509_crt_set_subject_alternative_name - This function will set the subject Alternative Name
453 * @crt: should contain a gnutls_x509_crt_t structure
454 * @type: is one of the gnutls_x509_subject_alt_name_t enumerations
455 * @data_string: The data to be set
456 *
457 * This function will set the subject alternative name certificate extension.
458 *
459 * Returns 0 on success.
460 *
461 **/
462int
463gnutls_x509_crt_set_subject_alternative_name (gnutls_x509_crt_t crt,
464 gnutls_x509_subject_alt_name_t
465 type, const char *data_string)
466{
467 int result;
468 gnutls_datum_t der_data;
469 gnutls_datum_t dnsname;
470 unsigned int critical;
471
472 if (crt == NULL)
473 {
474 gnutls_assert ();
475 return GNUTLS_E_INVALID_REQUEST;
476 }
477
478 /* Check if the extension already exists.
479 */
480 result =
481 _gnutls_x509_crt_get_extension (crt, "2.5.29.17", 0, &dnsname, &critical);
482
483 if (result >= 0)
484 _gnutls_free_datum (&dnsname);
485 if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
486 {
487 gnutls_assert ();
488 return GNUTLS_E_INVALID_REQUEST;
489 }
490
491 /* generate the extension.
492 */
493 result =
494 _gnutls_x509_ext_gen_subject_alt_name (type, data_string, &der_data);
495 if (result < 0)
496 {
497 gnutls_assert ();
498 return result;
499 }
500
501 result = _gnutls_x509_crt_set_extension (crt, "2.5.29.17", &der_data, 0);
502
503 _gnutls_free_datum (&der_data);
504
505 if (result < 0)
506 {
507 gnutls_assert ();
508 return result;
509 }
510
511 crt->use_extensions = 1;
512
513 return 0;
514}
515
516/**
517 * gnutls_x509_crt_set_proxy - Set the proxyCertInfo extension
518 * @crt: should contain a gnutls_x509_crt_t structure
519 * @pathLenConstraint: non-negative values indicate maximum length of path,
520 * and negative values indicate that the pathLenConstraints field should
521 * not be present.
522 * @policyLanguage: OID describing the language of @policy.
523 * @policy: opaque byte array with policy language, can be %NULL
524 * @sizeof_policy: size of @policy.
525 *
526 * This function will set the proxyCertInfo extension.
527 *
528 * Returns 0 on success.
529 *
530 **/
531int
532gnutls_x509_crt_set_proxy (gnutls_x509_crt_t crt,
533 int pathLenConstraint,
534 const char *policyLanguage,
535 const char *policy, size_t sizeof_policy)
536{
537 int result;
538 gnutls_datum_t der_data;
539
540 if (crt == NULL)
541 {
542 gnutls_assert ();
543 return GNUTLS_E_INVALID_REQUEST;
544 }
545
546 /* generate the extension.
547 */
548 result = _gnutls_x509_ext_gen_proxyCertInfo (pathLenConstraint,
549 policyLanguage,
550 policy, sizeof_policy,
551 &der_data);
552 if (result < 0)
553 {
554 gnutls_assert ();
555 return result;
556 }
557
558 result = _gnutls_x509_crt_set_extension (crt, "1.3.6.1.5.5.7.1.14",
559 &der_data, 1);
560
561 _gnutls_free_datum (&der_data);
562
563 if (result < 0)
564 {
565 gnutls_assert ();
566 return result;
567 }
568
569 crt->use_extensions = 1;
570
571 return 0;
572}
573
574/**
575 * gnutls_x509_crt_sign2 - This function will sign a certificate with a key
576 * @crt: should contain a gnutls_x509_crt_t structure
577 * @issuer: is the certificate of the certificate issuer
578 * @issuer_key: holds the issuer's private key
579 * @dig: The message digest to use. GNUTLS_DIG_SHA1 is the safe choice unless you know what you're doing.
580 * @flags: must be 0
581 *
582 * This function will sign the certificate with the issuer's private key, and
583 * will copy the issuer's information into the certificate.
584 *
585 * This must be the last step in a certificate generation since all
586 * the previously set parameters are now signed.
587 *
588 * Returns 0 on success.
589 *
590 **/
591int
592gnutls_x509_crt_sign2 (gnutls_x509_crt_t crt, gnutls_x509_crt_t issuer,
593 gnutls_x509_privkey_t issuer_key,
594 enum MHD_GNUTLS_HashAlgorithm dig, unsigned int flags)
595{
596 int result;
597
598 if (crt == NULL || issuer == NULL || issuer_key == NULL)
599 {
600 gnutls_assert ();
601 return GNUTLS_E_INVALID_REQUEST;
602 }
603
604 /* disable all the unneeded OPTIONAL fields.
605 */
606 disable_optional_stuff (crt);
607
608 result = _gnutls_x509_pkix_sign (crt->cert, "tbsCertificate",
609 dig, issuer, issuer_key);
610 if (result < 0)
611 {
612 gnutls_assert ();
613 return result;
614 }
615
616 return 0;
617}
618
619/**
620 * gnutls_x509_crt_sign - This function will sign a certificate with a key
621 * @crt: should contain a gnutls_x509_crt_t structure
622 * @issuer: is the certificate of the certificate issuer
623 * @issuer_key: holds the issuer's private key
624 *
625 * This function is the same a gnutls_x509_crt_sign2() with no flags, and
626 * SHA1 as the hash algorithm.
627 *
628 * Returns 0 on success.
629 *
630 **/
631int
632gnutls_x509_crt_sign (gnutls_x509_crt_t crt, gnutls_x509_crt_t issuer,
633 gnutls_x509_privkey_t issuer_key)
634{
635 return gnutls_x509_crt_sign2 (crt, issuer, issuer_key, MHD_GNUTLS_MAC_SHA1,
636 0);
637}
638
639/**
640 * gnutls_x509_crt_set_activation_time - This function will set the Certificate's activation time
641 * @cert: should contain a gnutls_x509_crt_t structure
642 * @act_time: The actual time
643 *
644 * This function will set the time this Certificate was or will be activated.
645 *
646 * Returns 0 on success, or a negative value in case of an error.
647 *
648 **/
649int
650gnutls_x509_crt_set_activation_time (gnutls_x509_crt_t cert, time_t act_time)
651{
652 if (cert == NULL)
653 {
654 gnutls_assert ();
655 return GNUTLS_E_INVALID_REQUEST;
656 }
657
658 return _gnutls_x509_set_time (cert->cert,
659 "tbsCertificate.validity.notBefore",
660 act_time);
661}
662
663/**
664 * gnutls_x509_crt_set_expiration_time - This function will set the Certificate's expiration time
665 * @cert: should contain a gnutls_x509_crt_t structure
666 * @exp_time: The actual time
667 *
668 * This function will set the time this Certificate will expire.
669 *
670 * Returns 0 on success, or a negative value in case of an error.
671 *
672 **/
673int
674gnutls_x509_crt_set_expiration_time (gnutls_x509_crt_t cert, time_t exp_time)
675{
676 if (cert == NULL)
677 {
678 gnutls_assert ();
679 return GNUTLS_E_INVALID_REQUEST;
680 }
681 return _gnutls_x509_set_time (cert->cert,
682 "tbsCertificate.validity.notAfter", exp_time);
683}
684
685/**
686 * gnutls_x509_crt_set_serial - This function will set the certificate's serial number
687 * @cert: should contain a gnutls_x509_crt_t structure
688 * @serial: The serial number
689 * @serial_size: Holds the size of the serial field.
690 *
691 * This function will set the X.509 certificate's serial number.
692 * Serial is not always a 32 or 64bit number. Some CAs use
693 * large serial numbers, thus it may be wise to handle it as something
694 * opaque.
695 *
696 * Returns 0 on success, or a negative value in case of an error.
697 *
698 **/
699int
700gnutls_x509_crt_set_serial (gnutls_x509_crt_t cert, const void *serial,
701 size_t serial_size)
702{
703 int ret;
704
705 if (cert == NULL)
706 {
707 gnutls_assert ();
708 return GNUTLS_E_INVALID_REQUEST;
709 }
710
711 ret =
712 asn1_write_value (cert->cert, "tbsCertificate.serialNumber", serial,
713 serial_size);
714 if (ret != ASN1_SUCCESS)
715 {
716 gnutls_assert ();
717 return mhd_gtls_asn2err (ret);
718 }
719
720 return 0;
721
722}
723
724/* If OPTIONAL fields have not been initialized then
725 * disable them.
726 */
727static void
728disable_optional_stuff (gnutls_x509_crt_t cert)
729{
730
731 asn1_write_value (cert->cert, "tbsCertificate.issuerUniqueID", NULL, 0);
732
733 asn1_write_value (cert->cert, "tbsCertificate.subjectUniqueID", NULL, 0);
734
735 if (cert->use_extensions == 0)
736 {
737 _gnutls_x509_log ("Disabling X.509 extensions.\n");
738 asn1_write_value (cert->cert, "tbsCertificate.extensions", NULL, 0);
739 }
740
741 return;
742}
743
744/**
745 * gnutls_x509_crt_set_crl_dist_points - This function will set the CRL dist points
746 * @crt: should contain a gnutls_x509_crt_t structure
747 * @type: is one of the gnutls_x509_subject_alt_name_t enumerations
748 * @data_string: The data to be set
749 * @reason_flags: revocation reasons
750 *
751 * This function will set the CRL distribution points certificate extension.
752 *
753 * Returns 0 on success.
754 *
755 **/
756int
757gnutls_x509_crt_set_crl_dist_points (gnutls_x509_crt_t crt,
758 gnutls_x509_subject_alt_name_t
759 type, const void *data_string,
760 unsigned int reason_flags)
761{
762 int result;
763 gnutls_datum_t der_data;
764 gnutls_datum_t oldname;
765 unsigned int critical;
766
767 if (crt == NULL)
768 {
769 gnutls_assert ();
770 return GNUTLS_E_INVALID_REQUEST;
771 }
772
773 /* Check if the extension already exists.
774 */
775 result =
776 _gnutls_x509_crt_get_extension (crt, "2.5.29.31", 0, &oldname, &critical);
777
778 if (result >= 0)
779 _gnutls_free_datum (&oldname);
780 if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
781 {
782 gnutls_assert ();
783 return GNUTLS_E_INVALID_REQUEST;
784 }
785
786 /* generate the extension.
787 */
788 result =
789 _gnutls_x509_ext_gen_crl_dist_points (type, data_string,
790 reason_flags, &der_data);
791 if (result < 0)
792 {
793 gnutls_assert ();
794 return result;
795 }
796
797 result = _gnutls_x509_crt_set_extension (crt, "2.5.29.31", &der_data, 0);
798
799 _gnutls_free_datum (&der_data);
800
801 if (result < 0)
802 {
803 gnutls_assert ();
804 return result;
805 }
806
807 crt->use_extensions = 1;
808
809 return 0;
810}
811
812/**
813 * gnutls_x509_crt_cpy_crl_dist_points - This function will copy the CRL dist points
814 * @dst: should contain a gnutls_x509_crt_t structure
815 * @src: the certificate where the dist points will be copied from
816 *
817 * This function will copy the CRL distribution points certificate
818 * extension, from the source to the destination certificate.
819 * This may be useful to copy from a CA certificate to issued ones.
820 *
821 * Returns 0 on success.
822 *
823 **/
824int
825gnutls_x509_crt_cpy_crl_dist_points (gnutls_x509_crt_t dst,
826 gnutls_x509_crt_t src)
827{
828 int result;
829 gnutls_datum_t der_data;
830 unsigned int critical;
831
832 if (dst == NULL || src == NULL)
833 {
834 gnutls_assert ();
835 return GNUTLS_E_INVALID_REQUEST;
836 }
837
838 /* Check if the extension already exists.
839 */
840 result =
841 _gnutls_x509_crt_get_extension (src, "2.5.29.31", 0, &der_data,
842 &critical);
843 if (result < 0)
844 {
845 gnutls_assert ();
846 return result;
847 }
848
849 result =
850 _gnutls_x509_crt_set_extension (dst, "2.5.29.31", &der_data, critical);
851 _gnutls_free_datum (&der_data);
852
853 if (result < 0)
854 {
855 gnutls_assert ();
856 return result;
857 }
858
859 dst->use_extensions = 1;
860
861 return 0;
862}
863
864/**
865 * gnutls_x509_crt_set_subject_key_id - This function will set the certificate's subject key id
866 * @cert: should contain a gnutls_x509_crt_t structure
867 * @id: The key ID
868 * @id_size: Holds the size of the serial field.
869 *
870 * This function will set the X.509 certificate's subject key ID extension.
871 *
872 * Returns 0 on success, or a negative value in case of an error.
873 *
874 **/
875int
876gnutls_x509_crt_set_subject_key_id (gnutls_x509_crt_t cert,
877 const void *id, size_t id_size)
878{
879 int result;
880 gnutls_datum_t old_id, der_data;
881 unsigned int critical;
882
883 if (cert == NULL)
884 {
885 gnutls_assert ();
886 return GNUTLS_E_INVALID_REQUEST;
887 }
888
889 /* Check if the extension already exists.
890 */
891 result =
892 _gnutls_x509_crt_get_extension (cert, "2.5.29.14", 0, &old_id, &critical);
893
894 if (result >= 0)
895 _gnutls_free_datum (&old_id);
896 if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
897 {
898 gnutls_assert ();
899 return GNUTLS_E_INVALID_REQUEST;
900 }
901
902 /* generate the extension.
903 */
904 result = _gnutls_x509_ext_gen_key_id (id, id_size, &der_data);
905 if (result < 0)
906 {
907 gnutls_assert ();
908 return result;
909 }
910
911 result = _gnutls_x509_crt_set_extension (cert, "2.5.29.14", &der_data, 0);
912
913 _gnutls_free_datum (&der_data);
914
915 if (result < 0)
916 {
917 gnutls_assert ();
918 return result;
919 }
920
921 cert->use_extensions = 1;
922
923 return 0;
924}
925
926/**
927 * gnutls_x509_crt_set_authority_key_id - This function will set the certificate authority's key id
928 * @cert: should contain a gnutls_x509_crt_t structure
929 * @id: The key ID
930 * @id_size: Holds the size of the serial field.
931 *
932 * This function will set the X.509 certificate's authority key ID extension.
933 * Only the keyIdentifier field can be set with this function.
934 *
935 * Returns 0 on success, or a negative value in case of an error.
936 *
937 **/
938int
939gnutls_x509_crt_set_authority_key_id (gnutls_x509_crt_t cert,
940 const void *id, size_t id_size)
941{
942 int result;
943 gnutls_datum_t old_id, der_data;
944 unsigned int critical;
945
946 if (cert == NULL)
947 {
948 gnutls_assert ();
949 return GNUTLS_E_INVALID_REQUEST;
950 }
951
952 /* Check if the extension already exists.
953 */
954 result =
955 _gnutls_x509_crt_get_extension (cert, "2.5.29.35", 0, &old_id, &critical);
956
957 if (result >= 0)
958 _gnutls_free_datum (&old_id);
959 if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
960 {
961 gnutls_assert ();
962 return GNUTLS_E_INVALID_REQUEST;
963 }
964
965 /* generate the extension.
966 */
967 result = _gnutls_x509_ext_gen_auth_key_id (id, id_size, &der_data);
968 if (result < 0)
969 {
970 gnutls_assert ();
971 return result;
972 }
973
974 result = _gnutls_x509_crt_set_extension (cert, "2.5.29.35", &der_data, 0);
975
976 _gnutls_free_datum (&der_data);
977
978 if (result < 0)
979 {
980 gnutls_assert ();
981 return result;
982 }
983
984 cert->use_extensions = 1;
985
986 return 0;
987}
988
989/**
990 * gnutls_x509_crt_set_key_purpose_oid - This function sets the Certificate's key purpose OIDs
991 * @cert: should contain a gnutls_x509_crt_t structure
992 * @oid: a pointer to a null terminated string that holds the OID
993 * @critical: Whether this extension will be critical or not
994 *
995 * This function will set the key purpose OIDs of the Certificate.
996 * These are stored in the Extended Key Usage extension (2.5.29.37)
997 * See the GNUTLS_KP_* definitions for human readable names.
998 *
999 * Subsequent calls to this function will append OIDs to the OID list.
1000 *
1001 * On success 0 is returned.
1002 *
1003 **/
1004int
1005gnutls_x509_crt_set_key_purpose_oid (gnutls_x509_crt_t cert,
1006 const void *oid, unsigned int critical)
1007{
1008 int result;
1009 gnutls_datum_t old_id, der_data;
1010 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1011
1012 if (cert == NULL)
1013 {
1014 gnutls_assert ();
1015 return GNUTLS_E_INVALID_REQUEST;
1016 }
1017
1018 result = asn1_create_element
1019 (_gnutls_get_pkix (), "PKIX1.ExtKeyUsageSyntax", &c2);
1020 if (result != ASN1_SUCCESS)
1021 {
1022 gnutls_assert ();
1023 return mhd_gtls_asn2err (result);
1024 }
1025
1026 /* Check if the extension already exists.
1027 */
1028 result =
1029 _gnutls_x509_crt_get_extension (cert, "2.5.29.37", 0, &old_id, NULL);
1030
1031 if (result >= 0)
1032 {
1033 /* decode it.
1034 */
1035 result = asn1_der_decoding (&c2, old_id.data, old_id.size, NULL);
1036 _gnutls_free_datum (&old_id);
1037
1038 if (result != ASN1_SUCCESS)
1039 {
1040 gnutls_assert ();
1041 asn1_delete_structure (&c2);
1042 return mhd_gtls_asn2err (result);
1043 }
1044
1045 }
1046
1047 /* generate the extension.
1048 */
1049 /* 1. create a new element.
1050 */
1051 result = asn1_write_value (c2, "", "NEW", 1);
1052 if (result != ASN1_SUCCESS)
1053 {
1054 gnutls_assert ();
1055 asn1_delete_structure (&c2);
1056 return mhd_gtls_asn2err (result);
1057 }
1058
1059 /* 2. Add the OID.
1060 */
1061 result = asn1_write_value (c2, "?LAST", oid, 1);
1062 if (result != ASN1_SUCCESS)
1063 {
1064 gnutls_assert ();
1065 asn1_delete_structure (&c2);
1066 return mhd_gtls_asn2err (result);
1067 }
1068
1069 result = _gnutls_x509_der_encode (c2, "", &der_data, 0);
1070 asn1_delete_structure (&c2);
1071
1072 if (result != ASN1_SUCCESS)
1073 {
1074 gnutls_assert ();
1075 return mhd_gtls_asn2err (result);
1076 }
1077
1078 result = _gnutls_x509_crt_set_extension (cert, "2.5.29.37",
1079 &der_data, critical);
1080
1081 _gnutls_free_datum (&der_data);
1082
1083 if (result < 0)
1084 {
1085 gnutls_assert ();
1086 return result;
1087 }
1088
1089 cert->use_extensions = 1;
1090
1091 return 0;
1092
1093}
1094
1095#endif /* ENABLE_PKI */