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>
32 #include <gnutls_datum.h>
35 get_extension (ASN1_TYPE asn
, const char *root
,
36 const char *extension_id
, int indx
,
37 gnutls_datum_t
* ret
, unsigned int *_critical
)
40 char name
[ASN1_MAX_NAME_SIZE
], name2
[ASN1_MAX_NAME_SIZE
];
42 char str_critical
[10];
56 snprintf (name
, sizeof (name
), "%s.?%u", root
, k
);
58 len
= sizeof (str
) - 1;
59 result
= asn1_read_value (asn
, name
, str
, &len
);
64 if (result
== ASN1_ELEMENT_NOT_FOUND
)
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
)
83 else if (result
!= ASN1_SUCCESS
)
86 return _gnutls_asn2err (result
);
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
)
109 else if (result
!= ASN1_SUCCESS
)
112 return _gnutls_asn2err (result
);
115 if (str_critical
[0] == 'T')
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
);
132 ret
->data
= value
.data
;
133 ret
->size
= value
.size
;
136 *_critical
= critical
;
147 if (result
== ASN1_ELEMENT_NOT_FOUND
)
149 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
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
162 * Critical will be either 0 or 1.
164 * If the extension does not exist, GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
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
193 get_extension_oid (ASN1_TYPE asn
, const char *root
,
194 int indx
, void *oid
, size_t * sizeof_oid
)
197 char name
[ASN1_MAX_NAME_SIZE
], name2
[ASN1_MAX_NAME_SIZE
];
200 int indx_counter
= 0;
207 snprintf (name
, sizeof (name
), "%s.?%u", root
, k
);
209 len
= sizeof (str
) - 1;
210 result
= asn1_read_value (asn
, name
, str
, &len
);
215 if (result
== ASN1_ELEMENT_NOT_FOUND
)
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
)
234 else if (result
!= ASN1_SUCCESS
)
237 return _gnutls_asn2err (result
);
242 if (indx
== indx_counter
++)
244 len
= strlen (extnID
) + 1;
246 if (*sizeof_oid
< (unsigned) len
)
250 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
253 memcpy (oid
, extnID
, len
);
254 *sizeof_oid
= len
- 1;
265 if (result
== ASN1_ELEMENT_NOT_FOUND
)
267 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
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
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
,
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
,
298 /* This function will attempt to set the requested extension in
299 * the given X509v3 certificate.
301 * Critical will be either 0 or 1.
304 add_extension (ASN1_TYPE asn
, const char *root
, const char *extension_id
,
305 const gnutls_datum_t
* ext_data
, unsigned int critical
)
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
)
319 return _gnutls_asn2err (result
);
323 snprintf (name
, sizeof (name
), "%s.?LAST.extnID", root
);
325 snprintf (name
, sizeof (name
), "?LAST.extnID");
327 result
= asn1_write_value (asn
, name
, extension_id
, 1);
328 if (result
!= ASN1_SUCCESS
)
331 return _gnutls_asn2err (result
);
340 snprintf (name
, sizeof (name
), "%s.?LAST.critical", root
);
342 snprintf (name
, sizeof (name
), "?LAST.critical");
344 result
= asn1_write_value (asn
, name
, str
, 1);
345 if (result
!= ASN1_SUCCESS
)
348 return _gnutls_asn2err (result
);
352 snprintf (name
, sizeof (name
), "%s.?LAST.extnValue", root
);
354 snprintf (name
, sizeof (name
), "?LAST.extnValue");
356 result
= _gnutls_x509_write_value (asn
, name
, ext_data
, 0);
366 /* Overwrite the given extension (using the index)
367 * index here starts from one.
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
];
378 snprintf (name
, sizeof (name
), "%s.?%u", root
, indx
);
380 snprintf (name
, sizeof (name
), "?%u", indx
);
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
)
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);
411 set_extension (ASN1_TYPE asn
, const char *root
,
413 const gnutls_datum_t
* ext_data
, unsigned int critical
)
417 char name
[ASN1_MAX_NAME_SIZE
], name2
[ASN1_MAX_NAME_SIZE
];
420 /* Find the index of the given extension.
428 snprintf (name
, sizeof (name
), "%s.?%u", root
, k
);
430 snprintf (name
, sizeof (name
), "?%u", k
);
432 len
= sizeof (extnID
) - 1;
433 result
= asn1_read_value (asn
, name
, extnID
, &len
);
438 if (result
== ASN1_ELEMENT_NOT_FOUND
)
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
)
457 else if (result
!= ASN1_SUCCESS
)
460 return _gnutls_asn2err (result
);
465 if (strcmp (extnID
, ext_id
) == 0)
467 /* extension was found
469 return overwrite_extension (asn
, root
, k
, ext_data
, critical
);
478 if (result
== ASN1_ELEMENT_NOT_FOUND
)
480 return add_extension (asn
, root
, ext_id
, ext_data
, critical
);
485 return _gnutls_asn2err (result
);
492 /* This function will attempt to overwrite the requested extension with
495 * Critical will be either 0 or 1.
498 _gnutls_x509_crt_set_extension (gnutls_x509_crt_t cert
,
500 const gnutls_datum_t
* ext_data
,
501 unsigned int critical
)
503 return set_extension (cert
->cert
, "tbsCertificate.extensions", ext_id
,
508 _gnutls_x509_crl_set_extension (gnutls_x509_crl_t crl
,
510 const gnutls_datum_t
* ext_data
,
511 unsigned int critical
)
513 return set_extension (crl
->crl
, "tbsCertList.crlExtensions", ext_id
,
518 _gnutls_x509_crq_set_extension (gnutls_x509_crq_t crq
,
520 const gnutls_datum_t
* ext_data
,
521 unsigned int critical
)
523 unsigned char *extensions
= NULL
;
524 size_t extensions_size
= 0;
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
)
537 return GNUTLS_E_MEMORY_ERROR
;
540 result
= gnutls_x509_crq_get_attribute_by_oid (crq
,
541 "1.2.840.113549.1.9.14",
547 if (result
== GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
)
554 gnutls_free (extensions
);
559 result
= asn1_create_element (_gnutls_get_pkix (), "PKIX1.Extensions", &c2
);
560 if (result
!= ASN1_SUCCESS
)
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
)
574 asn1_delete_structure (&c2
);
575 return _gnutls_asn2err (result
);
579 result
= set_extension (c2
, "", ext_id
, ext_data
, critical
);
583 asn1_delete_structure (&c2
);
587 result
= _gnutls_x509_der_encode (c2
, "", &der
, 0);
589 asn1_delete_structure (&c2
);
597 result
= gnutls_x509_crq_set_attribute_by_oid (crq
, "1.2.840.113549.1.9.14",
599 gnutls_free (der
.data
);
610 /* Here we only extract the KeyUsage field, from the DER encoded
614 _gnutls_x509_ext_extract_keyUsage (uint16_t * keyUsage
,
615 uint8_t * extnValue
, int extnValueLen
)
617 ASN1_TYPE ext
= ASN1_TYPE_EMPTY
;
624 if ((result
= asn1_create_element
625 (_gnutls_get_pkix (), "PKIX1.KeyUsage", &ext
)) != ASN1_SUCCESS
)
628 return _gnutls_asn2err (result
);
631 result
= asn1_der_decoding (&ext
, extnValue
, extnValueLen
, NULL
);
633 if (result
!= ASN1_SUCCESS
)
636 asn1_delete_structure (&ext
);
637 return _gnutls_asn2err (result
);
641 result
= asn1_read_value (ext
, "", str
, &len
);
642 if (result
!= ASN1_SUCCESS
)
645 asn1_delete_structure (&ext
);
649 *keyUsage
= str
[0] | (str
[1] << 8);
651 asn1_delete_structure (&ext
);
656 /* extract the basicConstraints from the DER encoded extension
659 _gnutls_x509_ext_extract_basicConstraints (unsigned int *CA
,
660 int *pathLenConstraint
,
664 ASN1_TYPE ext
= ASN1_TYPE_EMPTY
;
668 if ((result
= asn1_create_element
669 (_gnutls_get_pkix (), "PKIX1.BasicConstraints", &ext
)) != ASN1_SUCCESS
)
672 return _gnutls_asn2err (result
);
675 result
= asn1_der_decoding (&ext
, extnValue
, extnValueLen
, NULL
);
676 if (result
!= ASN1_SUCCESS
)
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
)
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)
706 asn1_delete_structure (&ext
);
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
;
731 asn1_create_element (_gnutls_get_pkix (), "PKIX1.BasicConstraints", &ext
);
732 if (result
!= ASN1_SUCCESS
)
735 return _gnutls_asn2err (result
);
738 result
= asn1_write_value (ext
, "cA", str
, 1);
739 if (result
!= ASN1_SUCCESS
)
742 asn1_delete_structure (&ext
);
743 return _gnutls_asn2err (result
);
746 if (pathLenConstraint
< 0)
748 result
= asn1_write_value (ext
, "pathLenConstraint", NULL
, 0);
750 result
= _gnutls_asn2err (result
);
753 result
= _gnutls_x509_write_uint32 (ext
, "pathLenConstraint",
758 asn1_delete_structure (&ext
);
762 result
= _gnutls_x509_der_encode (ext
, "", der_ext
, 0);
764 asn1_delete_structure (&ext
);
775 /* extract an INTEGER from the DER encoded extension
778 _gnutls_x509_ext_extract_number (uint8_t * number
,
780 uint8_t * extnValue
, int extnValueLen
)
782 ASN1_TYPE ext
= ASN1_TYPE_EMPTY
;
784 int nr_size
= *_nr_size
;
786 /* here it doesn't matter so much that we use CertificateSerialNumber. It is equal
789 if ((result
= asn1_create_element
790 (_gnutls_get_pkix (), "PKIX1.CertificateSerialNumber",
791 &ext
)) != ASN1_SUCCESS
)
794 return _gnutls_asn2err (result
);
797 result
= asn1_der_decoding (&ext
, extnValue
, extnValueLen
, NULL
);
798 if (result
!= ASN1_SUCCESS
)
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
);
815 asn1_delete_structure (&ext
);
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
;
830 asn1_create_element (_gnutls_get_pkix (), "PKIX1.CertificateSerialNumber",
832 if (result
!= ASN1_SUCCESS
)
835 return _gnutls_asn2err (result
);
838 result
= asn1_write_value (ext
, "", number
, nr_size
);
839 if (result
!= ASN1_SUCCESS
)
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
);
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
;
869 result
= asn1_create_element (_gnutls_get_pkix (), "PKIX1.KeyUsage", &ext
);
870 if (result
!= ASN1_SUCCESS
)
873 return _gnutls_asn2err (result
);
876 str
[0] = usage
& 0xff;
879 result
= asn1_write_value (ext
, "", str
, 9);
880 if (result
!= ASN1_SUCCESS
)
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
);
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
)
909 result
= asn1_write_value (ext
, ext_name
, "NEW", 1);
910 if (result
!= ASN1_SUCCESS
)
913 return _gnutls_asn2err (result
);
918 case GNUTLS_SAN_DNSNAME
:
921 case GNUTLS_SAN_RFC822NAME
:
925 str
= "uniformResourceIdentifier";
927 case GNUTLS_SAN_IPADDRESS
:
932 return GNUTLS_E_INTERNAL_ERROR
;
935 if (ext_name
[0] == 0)
937 _gnutls_str_cpy (name
, sizeof (name
), "?LAST");
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
)
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
)
959 asn1_delete_structure (&ext
);
960 return _gnutls_asn2err (result
);
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
;
980 asn1_create_element (_gnutls_get_pkix (), "PKIX1.GeneralNames", &ext
);
981 if (result
!= ASN1_SUCCESS
)
984 return _gnutls_asn2err (result
);
987 if (prev_der_ext
!= NULL
&& prev_der_ext
->data
!= NULL
988 && prev_der_ext
->size
!= 0)
991 asn1_der_decoding (&ext
, prev_der_ext
->data
, prev_der_ext
->size
,
994 if (result
!= ASN1_SUCCESS
)
997 asn1_delete_structure (&ext
);
998 return _gnutls_asn2err (result
);
1002 result
= write_new_general_name (ext
, "", type
, data
, data_size
);
1006 asn1_delete_structure (&ext
);
1010 result
= _gnutls_x509_der_encode (ext
, "", der_ext
, 0);
1012 asn1_delete_structure (&ext
);
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
;
1033 asn1_create_element (_gnutls_get_pkix (),
1034 "PKIX1.SubjectKeyIdentifier", &ext
);
1035 if (result
!= ASN1_SUCCESS
)
1038 return _gnutls_asn2err (result
);
1041 result
= asn1_write_value (ext
, "", id
, id_size
);
1042 if (result
!= ASN1_SUCCESS
)
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
);
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
;
1072 asn1_create_element (_gnutls_get_pkix (),
1073 "PKIX1.AuthorityKeyIdentifier", &ext
);
1074 if (result
!= ASN1_SUCCESS
)
1077 return _gnutls_asn2err (result
);
1080 result
= asn1_write_value (ext
, "keyIdentifier", id
, id_size
);
1081 if (result
!= ASN1_SUCCESS
)
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
);
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 };
1122 reasons
[0] = reason_flags
& 0xff;
1123 reasons
[1] = reason_flags
>> 8;
1126 asn1_create_element (_gnutls_get_pkix (),
1127 "PKIX1.CRLDistributionPoints", &ext
);
1128 if (result
!= ASN1_SUCCESS
)
1131 result
= _gnutls_asn2err (result
);
1135 result
= asn1_write_value (ext
, "", "NEW", 1);
1136 if (result
!= ASN1_SUCCESS
)
1139 result
= _gnutls_asn2err (result
);
1145 result
= asn1_write_value (ext
, "?LAST.reasons", reasons
, 9);
1146 if (result
!= ASN1_SUCCESS
)
1149 result
= _gnutls_asn2err (result
);
1155 result
= asn1_write_value (ext
, "?LAST.reasons", NULL
, 0);
1156 if (result
!= ASN1_SUCCESS
)
1159 result
= _gnutls_asn2err (result
);
1164 result
= asn1_write_value (ext
, "?LAST.cRLIssuer", NULL
, 0);
1165 if (result
!= ASN1_SUCCESS
)
1168 result
= _gnutls_asn2err (result
);
1172 /* When used as type CHOICE.
1174 result
= asn1_write_value (ext
, "?LAST.distributionPoint", "fullName", 1);
1175 if (result
!= ASN1_SUCCESS
)
1178 result
= _gnutls_asn2err (result
);
1183 /* only needed in old code (where defined as SEQUENCE OF) */
1184 asn1_write_value (ext
,
1185 "?LAST.distributionPoint.nameRelativeToCRLIssuer",
1190 write_new_general_name (ext
, "?LAST.distributionPoint.fullName",
1191 type
, data
, data_size
);
1198 result
= _gnutls_x509_der_encode (ext
, "", der_ext
, 0);
1209 _gnutls_free_datum (&gnames
);
1210 asn1_delete_structure (&ext
);
1215 /* extract the proxyCertInfo from the DER encoded extension
1218 _gnutls_x509_ext_extract_proxyCertInfo (int *pathLenConstraint
,
1219 char **policyLanguage
,
1221 size_t * sizeof_policy
,
1222 uint8_t * extnValue
, int extnValueLen
)
1224 ASN1_TYPE ext
= ASN1_TYPE_EMPTY
;
1226 gnutls_datum_t value
;
1228 if ((result
= asn1_create_element
1229 (_gnutls_get_pkix (), "PKIX1.ProxyCertInfo", &ext
)) != ASN1_SUCCESS
)
1232 return _gnutls_asn2err (result
);
1235 result
= asn1_der_decoding (&ext
, extnValue
, extnValueLen
, NULL
);
1236 if (result
!= ASN1_SUCCESS
)
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",
1261 asn1_delete_structure (&ext
);
1266 *policyLanguage
= gnutls_strdup ((char*)value
.data
);
1268 result
= _gnutls_x509_read_value (ext
, "proxyPolicy.policy", &value
);
1269 if (result
== GNUTLS_E_ASN1_ELEMENT_NOT_FOUND
)
1276 else if (result
< 0)
1279 asn1_delete_structure (&ext
);
1285 *policy
= (char*)value
.data
;
1287 *sizeof_policy
= value
.size
;
1290 asn1_delete_structure (&ext
);
1295 /* generate the proxyCertInfo in a DER encoded extension
1298 _gnutls_x509_ext_gen_proxyCertInfo (int pathLenConstraint
,
1299 const char *policyLanguage
,
1301 size_t sizeof_policy
,
1302 gnutls_datum_t
* der_ext
)
1304 ASN1_TYPE ext
= ASN1_TYPE_EMPTY
;
1307 result
= asn1_create_element (_gnutls_get_pkix (),
1308 "PKIX1.ProxyCertInfo", &ext
);
1309 if (result
!= ASN1_SUCCESS
)
1312 return _gnutls_asn2err (result
);
1315 if (pathLenConstraint
< 0)
1317 result
= asn1_write_value (ext
, "pCPathLenConstraint", NULL
, 0);
1319 result
= _gnutls_asn2err (result
);
1322 result
= _gnutls_x509_write_uint32 (ext
, "pCPathLenConstraint",
1327 asn1_delete_structure (&ext
);
1331 result
= asn1_write_value (ext
, "proxyPolicy.policyLanguage",
1336 asn1_delete_structure (&ext
);
1337 return _gnutls_asn2err (result
);
1340 result
= asn1_write_value (ext
, "proxyPolicy.policy",
1341 policy
, sizeof_policy
);
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
);