Use the new asn1_read_node_value()
[gnutls.git] / lib / x509 / extensions.c
bloba429bfea278ad29c0d5545115a642888809eecd9
1 /*
2 * Copyright (C) 2003-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS 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 3 of
11 * the License, or (at your option) any later version.
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.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 /* Functions that relate to the X.509 extension parsing.
26 #include <gnutls_int.h>
27 #include <gnutls_errors.h>
28 #include <gnutls_global.h>
29 #include <libtasn1.h>
30 #include <common.h>
31 #include <x509_int.h>
32 #include <gnutls_datum.h>
34 int
35 get_extension (ASN1_TYPE asn, const char *root,
36 const char *extension_id, int indx,
37 gnutls_datum_t * ret, unsigned int *_critical)
39 int k, result, len;
40 char name[ASN1_MAX_NAME_SIZE], name2[ASN1_MAX_NAME_SIZE];
41 char str[1024];
42 char str_critical[10];
43 int critical = 0;
44 char extnID[128];
45 gnutls_datum_t value;
46 int indx_counter = 0;
48 ret->data = NULL;
49 ret->size = 0;
51 k = 0;
54 k++;
56 snprintf (name, sizeof (name), "%s.?%u", root, k);
58 len = sizeof (str) - 1;
59 result = asn1_read_value (asn, name, str, &len);
61 /* move to next
64 if (result == ASN1_ELEMENT_NOT_FOUND)
66 break;
72 _gnutls_str_cpy (name2, sizeof (name2), name);
73 _gnutls_str_cat (name2, sizeof (name2), ".extnID");
75 len = sizeof (extnID) - 1;
76 result = asn1_read_value (asn, name2, extnID, &len);
78 if (result == ASN1_ELEMENT_NOT_FOUND)
80 gnutls_assert ();
81 break;
83 else if (result != ASN1_SUCCESS)
85 gnutls_assert ();
86 return _gnutls_asn2err (result);
89 /* Handle Extension
91 if (strcmp (extnID, extension_id) == 0 && indx == indx_counter++)
93 /* extension was found
96 /* read the critical status.
98 _gnutls_str_cpy (name2, sizeof (name2), name);
99 _gnutls_str_cat (name2, sizeof (name2), ".critical");
101 len = sizeof (str_critical);
102 result = asn1_read_value (asn, name2, str_critical, &len);
104 if (result == ASN1_ELEMENT_NOT_FOUND)
106 gnutls_assert ();
107 break;
109 else if (result != ASN1_SUCCESS)
111 gnutls_assert ();
112 return _gnutls_asn2err (result);
115 if (str_critical[0] == 'T')
116 critical = 1;
117 else
118 critical = 0;
120 /* read the value.
122 _gnutls_str_cpy (name2, sizeof (name2), name);
123 _gnutls_str_cat (name2, sizeof (name2), ".extnValue");
125 result = _gnutls_x509_read_value (asn, name2, &value, 0);
126 if (result < 0)
128 gnutls_assert ();
129 return result;
132 ret->data = value.data;
133 ret->size = value.size;
135 if (_critical)
136 *_critical = critical;
138 return 0;
143 while (0);
145 while (1);
147 if (result == ASN1_ELEMENT_NOT_FOUND)
149 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
151 else
153 gnutls_assert ();
154 return _gnutls_asn2err (result);
158 /* This function will attempt to return the requested extension found in
159 * the given X509v3 certificate. The return value is allocated and stored into
160 * ret.
162 * Critical will be either 0 or 1.
164 * If the extension does not exist, GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
165 * be returned.
168 _gnutls_x509_crt_get_extension (gnutls_x509_crt_t cert,
169 const char *extension_id, int indx,
170 gnutls_datum_t * ret, unsigned int *_critical)
172 return get_extension (cert->cert, "tbsCertificate.extensions", extension_id,
173 indx, ret, _critical);
177 _gnutls_x509_crl_get_extension (gnutls_x509_crl_t crl,
178 const char *extension_id, int indx,
179 gnutls_datum_t * ret, unsigned int *_critical)
181 return get_extension (crl->crl, "tbsCertList.crlExtensions", extension_id,
182 indx, ret, _critical);
186 /* This function will attempt to return the requested extension OID found in
187 * the given X509v3 certificate.
189 * If you have passed the last extension, GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
190 * be returned.
192 static int
193 get_extension_oid (ASN1_TYPE asn, const char *root,
194 int indx, void *oid, size_t * sizeof_oid)
196 int k, result, len;
197 char name[ASN1_MAX_NAME_SIZE], name2[ASN1_MAX_NAME_SIZE];
198 char str[1024];
199 char extnID[128];
200 int indx_counter = 0;
202 k = 0;
205 k++;
207 snprintf (name, sizeof (name), "%s.?%u", root, k);
209 len = sizeof (str) - 1;
210 result = asn1_read_value (asn, name, str, &len);
212 /* move to next
215 if (result == ASN1_ELEMENT_NOT_FOUND)
217 break;
223 _gnutls_str_cpy (name2, sizeof (name2), name);
224 _gnutls_str_cat (name2, sizeof (name2), ".extnID");
226 len = sizeof (extnID) - 1;
227 result = asn1_read_value (asn, name2, extnID, &len);
229 if (result == ASN1_ELEMENT_NOT_FOUND)
231 gnutls_assert ();
232 break;
234 else if (result != ASN1_SUCCESS)
236 gnutls_assert ();
237 return _gnutls_asn2err (result);
240 /* Handle Extension
242 if (indx == indx_counter++)
244 len = strlen (extnID) + 1;
246 if (*sizeof_oid < (unsigned) len)
248 *sizeof_oid = len;
249 gnutls_assert ();
250 return GNUTLS_E_SHORT_MEMORY_BUFFER;
253 memcpy (oid, extnID, len);
254 *sizeof_oid = len - 1;
256 return 0;
261 while (0);
263 while (1);
265 if (result == ASN1_ELEMENT_NOT_FOUND)
267 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
269 else
271 gnutls_assert ();
272 return _gnutls_asn2err (result);
276 /* This function will attempt to return the requested extension OID found in
277 * the given X509v3 certificate.
279 * If you have passed the last extension, GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
280 * be returned.
283 _gnutls_x509_crt_get_extension_oid (gnutls_x509_crt_t cert,
284 int indx, void *oid, size_t * sizeof_oid)
286 return get_extension_oid (cert->cert, "tbsCertificate.extensions", indx,
287 oid, sizeof_oid);
291 _gnutls_x509_crl_get_extension_oid (gnutls_x509_crl_t crl,
292 int indx, void *oid, size_t * sizeof_oid)
294 return get_extension_oid (crl->crl, "tbsCertList.crlExtensions", indx, oid,
295 sizeof_oid);
298 /* This function will attempt to set the requested extension in
299 * the given X509v3 certificate.
301 * Critical will be either 0 or 1.
303 static int
304 add_extension (ASN1_TYPE asn, const char *root, const char *extension_id,
305 const gnutls_datum_t * ext_data, unsigned int critical)
307 int result;
308 const char *str;
309 char name[ASN1_MAX_NAME_SIZE];
311 snprintf (name, sizeof (name), "%s", root);
313 /* Add a new extension in the list.
315 result = asn1_write_value (asn, name, "NEW", 1);
316 if (result != ASN1_SUCCESS)
318 gnutls_assert ();
319 return _gnutls_asn2err (result);
322 if (root[0] != 0)
323 snprintf (name, sizeof (name), "%s.?LAST.extnID", root);
324 else
325 snprintf (name, sizeof (name), "?LAST.extnID");
327 result = asn1_write_value (asn, name, extension_id, 1);
328 if (result != ASN1_SUCCESS)
330 gnutls_assert ();
331 return _gnutls_asn2err (result);
334 if (critical == 0)
335 str = "FALSE";
336 else
337 str = "TRUE";
339 if (root[0] != 0)
340 snprintf (name, sizeof (name), "%s.?LAST.critical", root);
341 else
342 snprintf (name, sizeof (name), "?LAST.critical");
344 result = asn1_write_value (asn, name, str, 1);
345 if (result != ASN1_SUCCESS)
347 gnutls_assert ();
348 return _gnutls_asn2err (result);
351 if (root[0] != 0)
352 snprintf (name, sizeof (name), "%s.?LAST.extnValue", root);
353 else
354 snprintf (name, sizeof (name), "?LAST.extnValue");
356 result = _gnutls_x509_write_value (asn, name, ext_data, 0);
357 if (result < 0)
359 gnutls_assert ();
360 return result;
363 return 0;
366 /* Overwrite the given extension (using the index)
367 * index here starts from one.
369 static int
370 overwrite_extension (ASN1_TYPE asn, const char *root, unsigned int indx,
371 const gnutls_datum_t * ext_data, unsigned int critical)
373 char name[ASN1_MAX_NAME_SIZE], name2[ASN1_MAX_NAME_SIZE];
374 const char *str;
375 int result;
377 if (root[0] != 0)
378 snprintf (name, sizeof (name), "%s.?%u", root, indx);
379 else
380 snprintf (name, sizeof (name), "?%u", indx);
382 if (critical == 0)
383 str = "FALSE";
384 else
385 str = "TRUE";
387 _gnutls_str_cpy (name2, sizeof (name2), name);
388 _gnutls_str_cat (name2, sizeof (name2), ".critical");
390 result = asn1_write_value (asn, name2, str, 1);
391 if (result != ASN1_SUCCESS)
393 gnutls_assert ();
394 return _gnutls_asn2err (result);
397 _gnutls_str_cpy (name2, sizeof (name2), name);
398 _gnutls_str_cat (name2, sizeof (name2), ".extnValue");
400 result = _gnutls_x509_write_value (asn, name2, ext_data, 0);
401 if (result < 0)
403 gnutls_assert ();
404 return result;
407 return 0;
411 set_extension (ASN1_TYPE asn, const char *root,
412 const char *ext_id,
413 const gnutls_datum_t * ext_data, unsigned int critical)
415 int result;
416 int k, len;
417 char name[ASN1_MAX_NAME_SIZE], name2[ASN1_MAX_NAME_SIZE];
418 char extnID[128];
420 /* Find the index of the given extension.
422 k = 0;
425 k++;
427 if (root[0] != 0)
428 snprintf (name, sizeof (name), "%s.?%u", root, k);
429 else
430 snprintf (name, sizeof (name), "?%u", k);
432 len = sizeof (extnID) - 1;
433 result = asn1_read_value (asn, name, extnID, &len);
435 /* move to next
438 if (result == ASN1_ELEMENT_NOT_FOUND)
440 break;
446 _gnutls_str_cpy (name2, sizeof (name2), name);
447 _gnutls_str_cat (name2, sizeof (name2), ".extnID");
449 len = sizeof (extnID) - 1;
450 result = asn1_read_value (asn, name2, extnID, &len);
452 if (result == ASN1_ELEMENT_NOT_FOUND)
454 gnutls_assert ();
455 break;
457 else if (result != ASN1_SUCCESS)
459 gnutls_assert ();
460 return _gnutls_asn2err (result);
463 /* Handle Extension
465 if (strcmp (extnID, ext_id) == 0)
467 /* extension was found
469 return overwrite_extension (asn, root, k, ext_data, critical);
474 while (0);
476 while (1);
478 if (result == ASN1_ELEMENT_NOT_FOUND)
480 return add_extension (asn, root, ext_id, ext_data, critical);
482 else
484 gnutls_assert ();
485 return _gnutls_asn2err (result);
489 return 0;
492 /* This function will attempt to overwrite the requested extension with
493 * the given one.
495 * Critical will be either 0 or 1.
498 _gnutls_x509_crt_set_extension (gnutls_x509_crt_t cert,
499 const char *ext_id,
500 const gnutls_datum_t * ext_data,
501 unsigned int critical)
503 return set_extension (cert->cert, "tbsCertificate.extensions", ext_id,
504 ext_data, critical);
508 _gnutls_x509_crl_set_extension (gnutls_x509_crl_t crl,
509 const char *ext_id,
510 const gnutls_datum_t * ext_data,
511 unsigned int critical)
513 return set_extension (crl->crl, "tbsCertList.crlExtensions", ext_id,
514 ext_data, critical);
518 _gnutls_x509_crq_set_extension (gnutls_x509_crq_t crq,
519 const char *ext_id,
520 const gnutls_datum_t * ext_data,
521 unsigned int critical)
523 unsigned char *extensions = NULL;
524 size_t extensions_size = 0;
525 gnutls_datum_t der;
526 ASN1_TYPE c2;
527 int result;
529 result = gnutls_x509_crq_get_attribute_by_oid (crq, "1.2.840.113549.1.9.14",
530 0, NULL, &extensions_size);
531 if (result == GNUTLS_E_SHORT_MEMORY_BUFFER)
533 extensions = gnutls_malloc (extensions_size);
534 if (extensions == NULL)
536 gnutls_assert ();
537 return GNUTLS_E_MEMORY_ERROR;
540 result = gnutls_x509_crq_get_attribute_by_oid (crq,
541 "1.2.840.113549.1.9.14",
542 0, extensions,
543 &extensions_size);
545 if (result < 0)
547 if (result == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
549 extensions_size = 0;
551 else
553 gnutls_assert ();
554 gnutls_free (extensions);
555 return result;
559 result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.Extensions", &c2);
560 if (result != ASN1_SUCCESS)
562 gnutls_assert ();
563 gnutls_free (extensions);
564 return _gnutls_asn2err (result);
567 if (extensions_size > 0)
569 result = asn1_der_decoding (&c2, extensions, extensions_size, NULL);
570 gnutls_free (extensions);
571 if (result != ASN1_SUCCESS)
573 gnutls_assert ();
574 asn1_delete_structure (&c2);
575 return _gnutls_asn2err (result);
579 result = set_extension (c2, "", ext_id, ext_data, critical);
580 if (result < 0)
582 gnutls_assert ();
583 asn1_delete_structure (&c2);
584 return result;
587 result = _gnutls_x509_der_encode (c2, "", &der, 0);
589 asn1_delete_structure (&c2);
591 if (result < 0)
593 gnutls_assert ();
594 return result;
597 result = gnutls_x509_crq_set_attribute_by_oid (crq, "1.2.840.113549.1.9.14",
598 der.data, der.size);
599 gnutls_free (der.data);
600 if (result < 0)
602 gnutls_assert ();
603 return result;
607 return 0;
610 /* Here we only extract the KeyUsage field, from the DER encoded
611 * extension.
614 _gnutls_x509_ext_extract_keyUsage (uint16_t * keyUsage,
615 uint8_t * extnValue, int extnValueLen)
617 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
618 int len, result;
619 uint8_t str[2];
621 str[0] = str[1] = 0;
622 *keyUsage = 0;
624 if ((result = asn1_create_element
625 (_gnutls_get_pkix (), "PKIX1.KeyUsage", &ext)) != ASN1_SUCCESS)
627 gnutls_assert ();
628 return _gnutls_asn2err (result);
631 result = asn1_der_decoding (&ext, extnValue, extnValueLen, NULL);
633 if (result != ASN1_SUCCESS)
635 gnutls_assert ();
636 asn1_delete_structure (&ext);
637 return _gnutls_asn2err (result);
640 len = sizeof (str);
641 result = asn1_read_value (ext, "", str, &len);
642 if (result != ASN1_SUCCESS)
644 gnutls_assert ();
645 asn1_delete_structure (&ext);
646 return 0;
649 *keyUsage = str[0] | (str[1] << 8);
651 asn1_delete_structure (&ext);
653 return 0;
656 /* extract the basicConstraints from the DER encoded extension
659 _gnutls_x509_ext_extract_basicConstraints (unsigned int *CA,
660 int *pathLenConstraint,
661 uint8_t * extnValue,
662 int extnValueLen)
664 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
665 char str[128];
666 int len, result;
668 if ((result = asn1_create_element
669 (_gnutls_get_pkix (), "PKIX1.BasicConstraints", &ext)) != ASN1_SUCCESS)
671 gnutls_assert ();
672 return _gnutls_asn2err (result);
675 result = asn1_der_decoding (&ext, extnValue, extnValueLen, NULL);
676 if (result != ASN1_SUCCESS)
678 gnutls_assert ();
679 asn1_delete_structure (&ext);
680 return _gnutls_asn2err (result);
683 if (pathLenConstraint)
685 result = _gnutls_x509_read_uint (ext, "pathLenConstraint",
686 (unsigned int*)pathLenConstraint);
687 if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
688 *pathLenConstraint = -1;
689 else if (result != GNUTLS_E_SUCCESS)
691 gnutls_assert ();
692 asn1_delete_structure (&ext);
693 return _gnutls_asn2err (result);
697 /* the default value of cA is false.
699 len = sizeof (str) - 1;
700 result = asn1_read_value (ext, "cA", str, &len);
701 if (result == ASN1_SUCCESS && strcmp (str, "TRUE") == 0)
702 *CA = 1;
703 else
704 *CA = 0;
706 asn1_delete_structure (&ext);
708 return 0;
711 /* generate the basicConstraints in a DER encoded extension
712 * Use 0 or 1 (TRUE) for CA.
713 * Use negative error codes for pathLenConstraint to indicate that the field
714 * should not be present, >= 0 to indicate set values.
717 _gnutls_x509_ext_gen_basicConstraints (int CA,
718 int pathLenConstraint,
719 gnutls_datum_t * der_ext)
721 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
722 const char *str;
723 int result;
725 if (CA == 0)
726 str = "FALSE";
727 else
728 str = "TRUE";
730 result =
731 asn1_create_element (_gnutls_get_pkix (), "PKIX1.BasicConstraints", &ext);
732 if (result != ASN1_SUCCESS)
734 gnutls_assert ();
735 return _gnutls_asn2err (result);
738 result = asn1_write_value (ext, "cA", str, 1);
739 if (result != ASN1_SUCCESS)
741 gnutls_assert ();
742 asn1_delete_structure (&ext);
743 return _gnutls_asn2err (result);
746 if (pathLenConstraint < 0)
748 result = asn1_write_value (ext, "pathLenConstraint", NULL, 0);
749 if (result < 0)
750 result = _gnutls_asn2err (result);
752 else
753 result = _gnutls_x509_write_uint32 (ext, "pathLenConstraint",
754 pathLenConstraint);
755 if (result < 0)
757 gnutls_assert ();
758 asn1_delete_structure (&ext);
759 return result;
762 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
764 asn1_delete_structure (&ext);
766 if (result < 0)
768 gnutls_assert ();
769 return result;
772 return 0;
775 /* extract an INTEGER from the DER encoded extension
778 _gnutls_x509_ext_extract_number (uint8_t * number,
779 size_t * _nr_size,
780 uint8_t * extnValue, int extnValueLen)
782 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
783 int result;
784 int nr_size = *_nr_size;
786 /* here it doesn't matter so much that we use CertificateSerialNumber. It is equal
787 * to using INTEGER.
789 if ((result = asn1_create_element
790 (_gnutls_get_pkix (), "PKIX1.CertificateSerialNumber",
791 &ext)) != ASN1_SUCCESS)
793 gnutls_assert ();
794 return _gnutls_asn2err (result);
797 result = asn1_der_decoding (&ext, extnValue, extnValueLen, NULL);
798 if (result != ASN1_SUCCESS)
800 gnutls_assert ();
801 asn1_delete_structure (&ext);
802 return _gnutls_asn2err (result);
805 /* the default value of cA is false.
807 result = asn1_read_value (ext, "", number, &nr_size);
808 if (result != ASN1_SUCCESS)
809 result = _gnutls_asn2err (result);
810 else
811 result = 0;
813 *_nr_size = nr_size;
815 asn1_delete_structure (&ext);
817 return result;
820 /* generate an INTEGER in a DER encoded extension
823 _gnutls_x509_ext_gen_number (const uint8_t * number, size_t nr_size,
824 gnutls_datum_t * der_ext)
826 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
827 int result;
829 result =
830 asn1_create_element (_gnutls_get_pkix (), "PKIX1.CertificateSerialNumber",
831 &ext);
832 if (result != ASN1_SUCCESS)
834 gnutls_assert ();
835 return _gnutls_asn2err (result);
838 result = asn1_write_value (ext, "", number, nr_size);
839 if (result != ASN1_SUCCESS)
841 gnutls_assert ();
842 asn1_delete_structure (&ext);
843 return _gnutls_asn2err (result);
846 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
848 asn1_delete_structure (&ext);
850 if (result < 0)
852 gnutls_assert ();
853 return result;
856 return 0;
859 /* generate the keyUsage in a DER encoded extension
860 * Use an ORed SEQUENCE of GNUTLS_KEY_* for usage.
863 _gnutls_x509_ext_gen_keyUsage (uint16_t usage, gnutls_datum_t * der_ext)
865 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
866 int result;
867 uint8_t str[2];
869 result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.KeyUsage", &ext);
870 if (result != ASN1_SUCCESS)
872 gnutls_assert ();
873 return _gnutls_asn2err (result);
876 str[0] = usage & 0xff;
877 str[1] = usage >> 8;
879 result = asn1_write_value (ext, "", str, 9);
880 if (result != ASN1_SUCCESS)
882 gnutls_assert ();
883 asn1_delete_structure (&ext);
884 return _gnutls_asn2err (result);
887 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
889 asn1_delete_structure (&ext);
891 if (result < 0)
893 gnutls_assert ();
894 return result;
897 return 0;
900 static int
901 write_new_general_name (ASN1_TYPE ext, const char *ext_name,
902 gnutls_x509_subject_alt_name_t type,
903 const void *data, unsigned int data_size)
905 const char *str;
906 int result;
907 char name[128];
909 result = asn1_write_value (ext, ext_name, "NEW", 1);
910 if (result != ASN1_SUCCESS)
912 gnutls_assert ();
913 return _gnutls_asn2err (result);
916 switch (type)
918 case GNUTLS_SAN_DNSNAME:
919 str = "dNSName";
920 break;
921 case GNUTLS_SAN_RFC822NAME:
922 str = "rfc822Name";
923 break;
924 case GNUTLS_SAN_URI:
925 str = "uniformResourceIdentifier";
926 break;
927 case GNUTLS_SAN_IPADDRESS:
928 str = "iPAddress";
929 break;
930 default:
931 gnutls_assert ();
932 return GNUTLS_E_INTERNAL_ERROR;
935 if (ext_name[0] == 0)
936 { /* no dot */
937 _gnutls_str_cpy (name, sizeof (name), "?LAST");
939 else
941 _gnutls_str_cpy (name, sizeof (name), ext_name);
942 _gnutls_str_cat (name, sizeof (name), ".?LAST");
945 result = asn1_write_value (ext, name, str, 1);
946 if (result != ASN1_SUCCESS)
948 gnutls_assert ();
949 return _gnutls_asn2err (result);
952 _gnutls_str_cat (name, sizeof (name), ".");
953 _gnutls_str_cat (name, sizeof (name), str);
955 result = asn1_write_value (ext, name, data, data_size);
956 if (result != ASN1_SUCCESS)
958 gnutls_assert ();
959 asn1_delete_structure (&ext);
960 return _gnutls_asn2err (result);
963 return 0;
966 /* Convert the given name to GeneralNames in a DER encoded extension.
967 * This is the same as subject alternative name.
970 _gnutls_x509_ext_gen_subject_alt_name (gnutls_x509_subject_alt_name_t
971 type, const void *data,
972 unsigned int data_size,
973 gnutls_datum_t * prev_der_ext,
974 gnutls_datum_t * der_ext)
976 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
977 int result;
979 result =
980 asn1_create_element (_gnutls_get_pkix (), "PKIX1.GeneralNames", &ext);
981 if (result != ASN1_SUCCESS)
983 gnutls_assert ();
984 return _gnutls_asn2err (result);
987 if (prev_der_ext != NULL && prev_der_ext->data != NULL
988 && prev_der_ext->size != 0)
990 result =
991 asn1_der_decoding (&ext, prev_der_ext->data, prev_der_ext->size,
992 NULL);
994 if (result != ASN1_SUCCESS)
996 gnutls_assert ();
997 asn1_delete_structure (&ext);
998 return _gnutls_asn2err (result);
1002 result = write_new_general_name (ext, "", type, data, data_size);
1003 if (result < 0)
1005 gnutls_assert ();
1006 asn1_delete_structure (&ext);
1007 return result;
1010 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
1012 asn1_delete_structure (&ext);
1014 if (result < 0)
1016 gnutls_assert ();
1017 return result;
1020 return 0;
1023 /* generate the SubjectKeyID in a DER encoded extension
1026 _gnutls_x509_ext_gen_key_id (const void *id, size_t id_size,
1027 gnutls_datum_t * der_ext)
1029 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
1030 int result;
1032 result =
1033 asn1_create_element (_gnutls_get_pkix (),
1034 "PKIX1.SubjectKeyIdentifier", &ext);
1035 if (result != ASN1_SUCCESS)
1037 gnutls_assert ();
1038 return _gnutls_asn2err (result);
1041 result = asn1_write_value (ext, "", id, id_size);
1042 if (result != ASN1_SUCCESS)
1044 gnutls_assert ();
1045 asn1_delete_structure (&ext);
1046 return _gnutls_asn2err (result);
1049 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
1051 asn1_delete_structure (&ext);
1053 if (result < 0)
1055 gnutls_assert ();
1056 return result;
1059 return 0;
1062 /* generate the AuthorityKeyID in a DER encoded extension
1065 _gnutls_x509_ext_gen_auth_key_id (const void *id, size_t id_size,
1066 gnutls_datum_t * der_ext)
1068 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
1069 int result;
1071 result =
1072 asn1_create_element (_gnutls_get_pkix (),
1073 "PKIX1.AuthorityKeyIdentifier", &ext);
1074 if (result != ASN1_SUCCESS)
1076 gnutls_assert ();
1077 return _gnutls_asn2err (result);
1080 result = asn1_write_value (ext, "keyIdentifier", id, id_size);
1081 if (result != ASN1_SUCCESS)
1083 gnutls_assert ();
1084 asn1_delete_structure (&ext);
1085 return _gnutls_asn2err (result);
1088 asn1_write_value (ext, "authorityCertIssuer", NULL, 0);
1089 asn1_write_value (ext, "authorityCertSerialNumber", NULL, 0);
1091 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
1093 asn1_delete_structure (&ext);
1095 if (result < 0)
1097 gnutls_assert ();
1098 return result;
1101 return 0;
1105 /* Creates and encodes the CRL Distribution points. data_string should be a name
1106 * and type holds the type of the name.
1107 * reason_flags should be an or'ed sequence of GNUTLS_CRL_REASON_*.
1111 _gnutls_x509_ext_gen_crl_dist_points (gnutls_x509_subject_alt_name_t
1112 type, const void *data,
1113 unsigned int data_size,
1114 unsigned int reason_flags,
1115 gnutls_datum_t * der_ext)
1117 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
1118 gnutls_datum_t gnames = { NULL, 0 };
1119 int result;
1120 uint8_t reasons[2];
1122 reasons[0] = reason_flags & 0xff;
1123 reasons[1] = reason_flags >> 8;
1125 result =
1126 asn1_create_element (_gnutls_get_pkix (),
1127 "PKIX1.CRLDistributionPoints", &ext);
1128 if (result != ASN1_SUCCESS)
1130 gnutls_assert ();
1131 result = _gnutls_asn2err (result);
1132 goto cleanup;
1135 result = asn1_write_value (ext, "", "NEW", 1);
1136 if (result != ASN1_SUCCESS)
1138 gnutls_assert ();
1139 result = _gnutls_asn2err (result);
1140 goto cleanup;
1143 if (reason_flags)
1145 result = asn1_write_value (ext, "?LAST.reasons", reasons, 9);
1146 if (result != ASN1_SUCCESS)
1148 gnutls_assert ();
1149 result = _gnutls_asn2err (result);
1150 goto cleanup;
1153 else
1155 result = asn1_write_value (ext, "?LAST.reasons", NULL, 0);
1156 if (result != ASN1_SUCCESS)
1158 gnutls_assert ();
1159 result = _gnutls_asn2err (result);
1160 goto cleanup;
1164 result = asn1_write_value (ext, "?LAST.cRLIssuer", NULL, 0);
1165 if (result != ASN1_SUCCESS)
1167 gnutls_assert ();
1168 result = _gnutls_asn2err (result);
1169 goto cleanup;
1172 /* When used as type CHOICE.
1174 result = asn1_write_value (ext, "?LAST.distributionPoint", "fullName", 1);
1175 if (result != ASN1_SUCCESS)
1177 gnutls_assert ();
1178 result = _gnutls_asn2err (result);
1179 goto cleanup;
1182 #if 0
1183 /* only needed in old code (where defined as SEQUENCE OF) */
1184 asn1_write_value (ext,
1185 "?LAST.distributionPoint.nameRelativeToCRLIssuer",
1186 NULL, 0);
1187 #endif
1189 result =
1190 write_new_general_name (ext, "?LAST.distributionPoint.fullName",
1191 type, data, data_size);
1192 if (result < 0)
1194 gnutls_assert ();
1195 goto cleanup;
1198 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
1200 if (result < 0)
1202 gnutls_assert ();
1203 goto cleanup;
1206 result = 0;
1208 cleanup:
1209 _gnutls_free_datum (&gnames);
1210 asn1_delete_structure (&ext);
1212 return result;
1215 /* extract the proxyCertInfo from the DER encoded extension
1218 _gnutls_x509_ext_extract_proxyCertInfo (int *pathLenConstraint,
1219 char **policyLanguage,
1220 char **policy,
1221 size_t * sizeof_policy,
1222 uint8_t * extnValue, int extnValueLen)
1224 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
1225 int result;
1226 gnutls_datum_t value;
1228 if ((result = asn1_create_element
1229 (_gnutls_get_pkix (), "PKIX1.ProxyCertInfo", &ext)) != ASN1_SUCCESS)
1231 gnutls_assert ();
1232 return _gnutls_asn2err (result);
1235 result = asn1_der_decoding (&ext, extnValue, extnValueLen, NULL);
1236 if (result != ASN1_SUCCESS)
1238 gnutls_assert ();
1239 asn1_delete_structure (&ext);
1240 return _gnutls_asn2err (result);
1243 if (pathLenConstraint)
1245 result = _gnutls_x509_read_uint (ext, "pCPathLenConstraint",
1246 (unsigned int*)pathLenConstraint);
1247 if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1248 *pathLenConstraint = -1;
1249 else if (result != GNUTLS_E_SUCCESS)
1251 asn1_delete_structure (&ext);
1252 return _gnutls_asn2err (result);
1256 result = _gnutls_x509_read_value (ext, "proxyPolicy.policyLanguage",
1257 &value, 0);
1258 if (result < 0)
1260 gnutls_assert ();
1261 asn1_delete_structure (&ext);
1262 return result;
1265 if (policyLanguage)
1266 *policyLanguage = gnutls_strdup ((char*)value.data);
1268 result = _gnutls_x509_read_value (ext, "proxyPolicy.policy", &value, 0);
1269 if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1271 if (policy)
1272 *policy = NULL;
1273 if (sizeof_policy)
1274 *sizeof_policy = 0;
1276 else if (result < 0)
1278 gnutls_assert ();
1279 asn1_delete_structure (&ext);
1280 return result;
1282 else
1284 if (policy)
1285 *policy = (char*)value.data;
1286 if (sizeof_policy)
1287 *sizeof_policy = value.size;
1290 asn1_delete_structure (&ext);
1292 return 0;
1295 /* generate the proxyCertInfo in a DER encoded extension
1298 _gnutls_x509_ext_gen_proxyCertInfo (int pathLenConstraint,
1299 const char *policyLanguage,
1300 const char *policy,
1301 size_t sizeof_policy,
1302 gnutls_datum_t * der_ext)
1304 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
1305 int result;
1307 result = asn1_create_element (_gnutls_get_pkix (),
1308 "PKIX1.ProxyCertInfo", &ext);
1309 if (result != ASN1_SUCCESS)
1311 gnutls_assert ();
1312 return _gnutls_asn2err (result);
1315 if (pathLenConstraint < 0)
1317 result = asn1_write_value (ext, "pCPathLenConstraint", NULL, 0);
1318 if (result < 0)
1319 result = _gnutls_asn2err (result);
1321 else
1322 result = _gnutls_x509_write_uint32 (ext, "pCPathLenConstraint",
1323 pathLenConstraint);
1324 if (result < 0)
1326 gnutls_assert ();
1327 asn1_delete_structure (&ext);
1328 return result;
1331 result = asn1_write_value (ext, "proxyPolicy.policyLanguage",
1332 policyLanguage, 1);
1333 if (result < 0)
1335 gnutls_assert ();
1336 asn1_delete_structure (&ext);
1337 return _gnutls_asn2err (result);
1340 result = asn1_write_value (ext, "proxyPolicy.policy",
1341 policy, sizeof_policy);
1342 if (result < 0)
1344 gnutls_assert ();
1345 asn1_delete_structure (&ext);
1346 return _gnutls_asn2err (result);
1349 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
1351 asn1_delete_structure (&ext);
1353 if (result < 0)
1355 gnutls_assert ();
1356 return result;
1359 return 0;