2 * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010 Free Software
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS.
9 * The GnuTLS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
26 /* Functions that relate to the X.509 extension parsing.
29 #include <gnutls_int.h>
30 #include <gnutls_errors.h>
31 #include <gnutls_global.h>
35 #include <gnutls_datum.h>
38 get_extension (ASN1_TYPE asn, const char *root,
39 const char *extension_id, int indx,
40 gnutls_datum_t * ret, unsigned int *_critical)
43 char name[ASN1_MAX_NAME_SIZE], name2[ASN1_MAX_NAME_SIZE];
45 char str_critical[10];
59 snprintf (name, sizeof (name), "%s.?%u", root, k);
61 len = sizeof (str) - 1;
62 result = asn1_read_value (asn, name, str, &len);
67 if (result == ASN1_ELEMENT_NOT_FOUND)
75 _gnutls_str_cpy (name2, sizeof (name2), name);
76 _gnutls_str_cat (name2, sizeof (name2), ".extnID");
78 len = sizeof (extnID) - 1;
79 result = asn1_read_value (asn, name2, extnID, &len);
81 if (result == ASN1_ELEMENT_NOT_FOUND)
86 else if (result != ASN1_SUCCESS)
89 return _gnutls_asn2err (result);
94 if (strcmp (extnID, extension_id) == 0 && indx == indx_counter++)
96 /* extension was found
99 /* read the critical status.
101 _gnutls_str_cpy (name2, sizeof (name2), name);
102 _gnutls_str_cat (name2, sizeof (name2), ".critical");
104 len = sizeof (str_critical);
105 result = asn1_read_value (asn, name2, str_critical, &len);
107 if (result == ASN1_ELEMENT_NOT_FOUND)
112 else if (result != ASN1_SUCCESS)
115 return _gnutls_asn2err (result);
118 if (str_critical[0] == 'T')
125 _gnutls_str_cpy (name2, sizeof (name2), name);
126 _gnutls_str_cat (name2, sizeof (name2), ".extnValue");
128 result = _gnutls_x509_read_value (asn, name2, &value, 0);
135 ret->data = value.data;
136 ret->size = value.size;
139 *_critical = critical;
150 if (result == ASN1_ELEMENT_NOT_FOUND)
152 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
157 return _gnutls_asn2err (result);
161 /* This function will attempt to return the requested extension found in
162 * the given X509v3 certificate. The return value is allocated and stored into
165 * Critical will be either 0 or 1.
167 * If the extension does not exist, GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
171 _gnutls_x509_crt_get_extension (gnutls_x509_crt_t cert,
172 const char *extension_id, int indx,
173 gnutls_datum_t * ret, unsigned int *_critical)
175 return get_extension (cert->cert, "tbsCertificate.extensions", extension_id,
176 indx, ret, _critical);
180 _gnutls_x509_crl_get_extension (gnutls_x509_crl_t crl,
181 const char *extension_id, int indx,
182 gnutls_datum_t * ret, unsigned int *_critical)
184 return get_extension (crl->crl, "tbsCertList.crlExtensions", extension_id,
185 indx, ret, _critical);
189 /* This function will attempt to return the requested extension OID found in
190 * the given X509v3 certificate.
192 * If you have passed the last extension, GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
196 get_extension_oid (ASN1_TYPE asn, const char *root,
197 int indx, void *oid, size_t * sizeof_oid)
200 char name[ASN1_MAX_NAME_SIZE], name2[ASN1_MAX_NAME_SIZE];
203 int indx_counter = 0;
210 snprintf (name, sizeof (name), "%s.?%u", root, k);
212 len = sizeof (str) - 1;
213 result = asn1_read_value (asn, name, str, &len);
218 if (result == ASN1_ELEMENT_NOT_FOUND)
226 _gnutls_str_cpy (name2, sizeof (name2), name);
227 _gnutls_str_cat (name2, sizeof (name2), ".extnID");
229 len = sizeof (extnID) - 1;
230 result = asn1_read_value (asn, name2, extnID, &len);
232 if (result == ASN1_ELEMENT_NOT_FOUND)
237 else if (result != ASN1_SUCCESS)
240 return _gnutls_asn2err (result);
245 if (indx == indx_counter++)
247 len = strlen (extnID) + 1;
249 if (*sizeof_oid < (unsigned) len)
253 return GNUTLS_E_SHORT_MEMORY_BUFFER;
256 memcpy (oid, extnID, len);
257 *sizeof_oid = len - 1;
268 if (result == ASN1_ELEMENT_NOT_FOUND)
270 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
275 return _gnutls_asn2err (result);
279 /* This function will attempt to return the requested extension OID found in
280 * the given X509v3 certificate.
282 * If you have passed the last extension, GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
286 _gnutls_x509_crt_get_extension_oid (gnutls_x509_crt_t cert,
287 int indx, void *oid, size_t * sizeof_oid)
289 return get_extension_oid (cert->cert, "tbsCertificate.extensions", indx,
294 _gnutls_x509_crl_get_extension_oid (gnutls_x509_crl_t crl,
295 int indx, void *oid, size_t * sizeof_oid)
297 return get_extension_oid (crl->crl, "tbsCertList.crlExtensions", indx, oid,
301 /* This function will attempt to set the requested extension in
302 * the given X509v3 certificate.
304 * Critical will be either 0 or 1.
307 add_extension (ASN1_TYPE asn, const char *root, const char *extension_id,
308 const gnutls_datum_t * ext_data, unsigned int critical)
312 char name[ASN1_MAX_NAME_SIZE];
314 snprintf (name, sizeof (name), "%s", root);
316 /* Add a new extension in the list.
318 result = asn1_write_value (asn, name, "NEW", 1);
319 if (result != ASN1_SUCCESS)
322 return _gnutls_asn2err (result);
326 snprintf (name, sizeof (name), "%s.?LAST.extnID", root);
328 snprintf (name, sizeof (name), "?LAST.extnID");
330 result = asn1_write_value (asn, name, extension_id, 1);
331 if (result != ASN1_SUCCESS)
334 return _gnutls_asn2err (result);
343 snprintf (name, sizeof (name), "%s.?LAST.critical", root);
345 snprintf (name, sizeof (name), "?LAST.critical");
347 result = asn1_write_value (asn, name, str, 1);
348 if (result != ASN1_SUCCESS)
351 return _gnutls_asn2err (result);
355 snprintf (name, sizeof (name), "%s.?LAST.extnValue", root);
357 snprintf (name, sizeof (name), "?LAST.extnValue");
359 result = _gnutls_x509_write_value (asn, name, ext_data, 0);
369 /* Overwrite the given extension (using the index)
370 * index here starts from one.
373 overwrite_extension (ASN1_TYPE asn, const char *root, unsigned int indx,
374 const gnutls_datum_t * ext_data, unsigned int critical)
376 char name[ASN1_MAX_NAME_SIZE], name2[ASN1_MAX_NAME_SIZE];
381 snprintf (name, sizeof (name), "%s.?%u", root, indx);
383 snprintf (name, sizeof (name), "?%u", indx);
390 _gnutls_str_cpy (name2, sizeof (name2), name);
391 _gnutls_str_cat (name2, sizeof (name2), ".critical");
393 result = asn1_write_value (asn, name2, str, 1);
394 if (result != ASN1_SUCCESS)
397 return _gnutls_asn2err (result);
400 _gnutls_str_cpy (name2, sizeof (name2), name);
401 _gnutls_str_cat (name2, sizeof (name2), ".extnValue");
403 result = _gnutls_x509_write_value (asn, name2, ext_data, 0);
414 set_extension (ASN1_TYPE asn, const char *root,
416 const gnutls_datum_t * ext_data, unsigned int critical)
420 char name[ASN1_MAX_NAME_SIZE], name2[ASN1_MAX_NAME_SIZE];
423 /* Find the index of the given extension.
431 snprintf (name, sizeof (name), "%s.?%u", root, k);
433 snprintf (name, sizeof (name), "?%u", k);
435 len = sizeof (extnID) - 1;
436 result = asn1_read_value (asn, name, extnID, &len);
441 if (result == ASN1_ELEMENT_NOT_FOUND)
449 _gnutls_str_cpy (name2, sizeof (name2), name);
450 _gnutls_str_cat (name2, sizeof (name2), ".extnID");
452 len = sizeof (extnID) - 1;
453 result = asn1_read_value (asn, name2, extnID, &len);
455 if (result == ASN1_ELEMENT_NOT_FOUND)
460 else if (result != ASN1_SUCCESS)
463 return _gnutls_asn2err (result);
468 if (strcmp (extnID, ext_id) == 0)
470 /* extension was found
472 return overwrite_extension (asn, root, k, ext_data, critical);
481 if (result == ASN1_ELEMENT_NOT_FOUND)
483 return add_extension (asn, root, ext_id, ext_data, critical);
488 return _gnutls_asn2err (result);
495 /* This function will attempt to overwrite the requested extension with
498 * Critical will be either 0 or 1.
501 _gnutls_x509_crt_set_extension (gnutls_x509_crt_t cert,
503 const gnutls_datum_t * ext_data,
504 unsigned int critical)
506 return set_extension (cert->cert, "tbsCertificate.extensions", ext_id,
511 _gnutls_x509_crl_set_extension (gnutls_x509_crl_t crl,
513 const gnutls_datum_t * ext_data,
514 unsigned int critical)
516 return set_extension (crl->crl, "tbsCertList.crlExtensions", ext_id,
522 _gnutls_x509_crq_set_extension (gnutls_x509_crq_t crq,
524 const gnutls_datum_t * ext_data,
525 unsigned int critical)
527 unsigned char *extensions = NULL;
528 size_t extensions_size = 0;
533 result = gnutls_x509_crq_get_attribute_by_oid (crq, "1.2.840.113549.1.9.14",
534 0, NULL, &extensions_size);
535 if (result == GNUTLS_E_SHORT_MEMORY_BUFFER)
537 extensions = gnutls_malloc (extensions_size);
538 if (extensions == NULL)
541 return GNUTLS_E_MEMORY_ERROR;
544 result = gnutls_x509_crq_get_attribute_by_oid (crq,
545 "1.2.840.113549.1.9.14",
551 if (result == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
558 gnutls_free (extensions);
563 result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.Extensions", &c2);
564 if (result != ASN1_SUCCESS)
567 gnutls_free (extensions);
568 return _gnutls_asn2err (result);
571 if (extensions_size > 0)
573 result = asn1_der_decoding (&c2, extensions, extensions_size, NULL);
574 gnutls_free (extensions);
575 if (result != ASN1_SUCCESS)
578 asn1_delete_structure (&c2);
579 return _gnutls_asn2err (result);
583 result = set_extension (c2, "", ext_id, ext_data, critical);
587 asn1_delete_structure (&c2);
591 result = _gnutls_x509_der_encode (c2, "", &der, 0);
593 asn1_delete_structure (&c2);
601 result = gnutls_x509_crq_set_attribute_by_oid (crq, "1.2.840.113549.1.9.14",
603 gnutls_free (der.data);
616 /* Here we only extract the KeyUsage field, from the DER encoded
620 _gnutls_x509_ext_extract_keyUsage (uint16_t * keyUsage,
621 opaque * extnValue, int extnValueLen)
623 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
630 if ((result = asn1_create_element
631 (_gnutls_get_pkix (), "PKIX1.KeyUsage", &ext)) != ASN1_SUCCESS)
634 return _gnutls_asn2err (result);
637 result = asn1_der_decoding (&ext, extnValue, extnValueLen, NULL);
639 if (result != ASN1_SUCCESS)
642 asn1_delete_structure (&ext);
643 return _gnutls_asn2err (result);
647 result = asn1_read_value (ext, "", str, &len);
648 if (result != ASN1_SUCCESS)
651 asn1_delete_structure (&ext);
655 *keyUsage = str[0] | (str[1] << 8);
657 asn1_delete_structure (&ext);
662 /* extract the basicConstraints from the DER encoded extension
665 _gnutls_x509_ext_extract_basicConstraints (int *CA,
666 int *pathLenConstraint,
670 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
674 if ((result = asn1_create_element
675 (_gnutls_get_pkix (), "PKIX1.BasicConstraints", &ext)) != ASN1_SUCCESS)
678 return _gnutls_asn2err (result);
681 result = asn1_der_decoding (&ext, extnValue, extnValueLen, NULL);
682 if (result != ASN1_SUCCESS)
685 asn1_delete_structure (&ext);
686 return _gnutls_asn2err (result);
689 if (pathLenConstraint)
691 result = _gnutls_x509_read_uint (ext, "pathLenConstraint",
693 if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
694 *pathLenConstraint = -1;
695 else if (result != GNUTLS_E_SUCCESS)
698 asn1_delete_structure (&ext);
699 return _gnutls_asn2err (result);
703 /* the default value of cA is false.
705 len = sizeof (str) - 1;
706 result = asn1_read_value (ext, "cA", str, &len);
707 if (result == ASN1_SUCCESS && strcmp (str, "TRUE") == 0)
712 asn1_delete_structure (&ext);
717 /* generate the basicConstraints in a DER encoded extension
718 * Use 0 or 1 (TRUE) for CA.
719 * Use negative values for pathLenConstraint to indicate that the field
720 * should not be present, >= 0 to indicate set values.
723 _gnutls_x509_ext_gen_basicConstraints (int CA,
724 int pathLenConstraint,
725 gnutls_datum_t * der_ext)
727 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
737 asn1_create_element (_gnutls_get_pkix (), "PKIX1.BasicConstraints", &ext);
738 if (result != ASN1_SUCCESS)
741 return _gnutls_asn2err (result);
744 result = asn1_write_value (ext, "cA", str, 1);
745 if (result != ASN1_SUCCESS)
748 asn1_delete_structure (&ext);
749 return _gnutls_asn2err (result);
752 if (pathLenConstraint < 0)
754 result = asn1_write_value (ext, "pathLenConstraint", NULL, 0);
756 result = _gnutls_asn2err (result);
759 result = _gnutls_x509_write_uint32 (ext, "pathLenConstraint",
764 asn1_delete_structure (&ext);
768 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
770 asn1_delete_structure (&ext);
781 /* extract an INTEGER from the DER encoded extension
784 _gnutls_x509_ext_extract_number (opaque * number,
786 opaque * extnValue, int extnValueLen)
788 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
790 int nr_size = *_nr_size;
792 /* here it doesn't matter so much that we use CertificateSerialNumber. It is equal
795 if ((result = asn1_create_element
796 (_gnutls_get_pkix (), "PKIX1.CertificateSerialNumber",
797 &ext)) != ASN1_SUCCESS)
800 return _gnutls_asn2err (result);
803 result = asn1_der_decoding (&ext, extnValue, extnValueLen, NULL);
804 if (result != ASN1_SUCCESS)
807 asn1_delete_structure (&ext);
808 return _gnutls_asn2err (result);
811 /* the default value of cA is false.
813 result = asn1_read_value (ext, "", number, &nr_size);
814 if (result != ASN1_SUCCESS)
815 result = _gnutls_asn2err (result);
821 asn1_delete_structure (&ext);
826 /* generate an INTEGER in a DER encoded extension
829 _gnutls_x509_ext_gen_number (const opaque * number, size_t nr_size,
830 gnutls_datum_t * der_ext)
832 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
836 asn1_create_element (_gnutls_get_pkix (), "PKIX1.CertificateSerialNumber",
838 if (result != ASN1_SUCCESS)
841 return _gnutls_asn2err (result);
844 result = asn1_write_value (ext, "", number, nr_size);
845 if (result != ASN1_SUCCESS)
848 asn1_delete_structure (&ext);
849 return _gnutls_asn2err (result);
852 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
854 asn1_delete_structure (&ext);
865 /* generate the keyUsage in a DER encoded extension
866 * Use an ORed SEQUENCE of GNUTLS_KEY_* for usage.
869 _gnutls_x509_ext_gen_keyUsage (uint16_t usage, gnutls_datum_t * der_ext)
871 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
875 result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.KeyUsage", &ext);
876 if (result != ASN1_SUCCESS)
879 return _gnutls_asn2err (result);
882 str[0] = usage & 0xff;
885 result = asn1_write_value (ext, "", str, 9);
886 if (result != ASN1_SUCCESS)
889 asn1_delete_structure (&ext);
890 return _gnutls_asn2err (result);
893 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
895 asn1_delete_structure (&ext);
907 write_new_general_name (ASN1_TYPE ext, const char *ext_name,
908 gnutls_x509_subject_alt_name_t type,
909 const void *data, unsigned int data_size)
915 result = asn1_write_value (ext, ext_name, "NEW", 1);
916 if (result != ASN1_SUCCESS)
919 return _gnutls_asn2err (result);
924 case GNUTLS_SAN_DNSNAME:
927 case GNUTLS_SAN_RFC822NAME:
931 str = "uniformResourceIdentifier";
933 case GNUTLS_SAN_IPADDRESS:
938 return GNUTLS_E_INTERNAL_ERROR;
941 if (ext_name[0] == 0)
943 _gnutls_str_cpy (name, sizeof (name), "?LAST");
947 _gnutls_str_cpy (name, sizeof (name), ext_name);
948 _gnutls_str_cat (name, sizeof (name), ".?LAST");
951 result = asn1_write_value (ext, name, str, 1);
952 if (result != ASN1_SUCCESS)
955 return _gnutls_asn2err (result);
958 _gnutls_str_cat (name, sizeof (name), ".");
959 _gnutls_str_cat (name, sizeof (name), str);
961 result = asn1_write_value (ext, name, data, data_size);
962 if (result != ASN1_SUCCESS)
965 asn1_delete_structure (&ext);
966 return _gnutls_asn2err (result);
972 /* Convert the given name to GeneralNames in a DER encoded extension.
973 * This is the same as subject alternative name.
976 _gnutls_x509_ext_gen_subject_alt_name (gnutls_x509_subject_alt_name_t
977 type, const void *data,
978 unsigned int data_size,
979 gnutls_datum_t * prev_der_ext,
980 gnutls_datum_t * der_ext)
982 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
986 asn1_create_element (_gnutls_get_pkix (), "PKIX1.GeneralNames", &ext);
987 if (result != ASN1_SUCCESS)
990 return _gnutls_asn2err (result);
993 if (prev_der_ext != NULL && prev_der_ext->data != NULL
994 && prev_der_ext->size != 0)
997 asn1_der_decoding (&ext, prev_der_ext->data, prev_der_ext->size,
1000 if (result != ASN1_SUCCESS)
1003 asn1_delete_structure (&ext);
1004 return _gnutls_asn2err (result);
1008 result = write_new_general_name (ext, "", type, data, data_size);
1012 asn1_delete_structure (&ext);
1016 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
1018 asn1_delete_structure (&ext);
1029 /* generate the SubjectKeyID in a DER encoded extension
1032 _gnutls_x509_ext_gen_key_id (const void *id, size_t id_size,
1033 gnutls_datum_t * der_ext)
1035 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
1039 asn1_create_element (_gnutls_get_pkix (),
1040 "PKIX1.SubjectKeyIdentifier", &ext);
1041 if (result != ASN1_SUCCESS)
1044 return _gnutls_asn2err (result);
1047 result = asn1_write_value (ext, "", id, id_size);
1048 if (result != ASN1_SUCCESS)
1051 asn1_delete_structure (&ext);
1052 return _gnutls_asn2err (result);
1055 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
1057 asn1_delete_structure (&ext);
1068 /* generate the AuthorityKeyID in a DER encoded extension
1071 _gnutls_x509_ext_gen_auth_key_id (const void *id, size_t id_size,
1072 gnutls_datum_t * der_ext)
1074 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
1078 asn1_create_element (_gnutls_get_pkix (),
1079 "PKIX1.AuthorityKeyIdentifier", &ext);
1080 if (result != ASN1_SUCCESS)
1083 return _gnutls_asn2err (result);
1086 result = asn1_write_value (ext, "keyIdentifier", id, id_size);
1087 if (result != ASN1_SUCCESS)
1090 asn1_delete_structure (&ext);
1091 return _gnutls_asn2err (result);
1094 asn1_write_value (ext, "authorityCertIssuer", NULL, 0);
1095 asn1_write_value (ext, "authorityCertSerialNumber", NULL, 0);
1097 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
1099 asn1_delete_structure (&ext);
1111 /* Creates and encodes the CRL Distribution points. data_string should be a name
1112 * and type holds the type of the name.
1113 * reason_flags should be an or'ed sequence of GNUTLS_CRL_REASON_*.
1117 _gnutls_x509_ext_gen_crl_dist_points (gnutls_x509_subject_alt_name_t
1118 type, const void *data,
1119 unsigned int data_size,
1120 unsigned int reason_flags,
1121 gnutls_datum_t * der_ext)
1123 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
1124 gnutls_datum_t gnames = { NULL, 0 };
1128 reasons[0] = reason_flags & 0xff;
1129 reasons[1] = reason_flags >> 8;
1132 asn1_create_element (_gnutls_get_pkix (),
1133 "PKIX1.CRLDistributionPoints", &ext);
1134 if (result != ASN1_SUCCESS)
1137 result = _gnutls_asn2err (result);
1141 result = asn1_write_value (ext, "", "NEW", 1);
1142 if (result != ASN1_SUCCESS)
1145 result = _gnutls_asn2err (result);
1151 result = asn1_write_value (ext, "?LAST.reasons", reasons, 9);
1152 if (result != ASN1_SUCCESS)
1155 result = _gnutls_asn2err (result);
1161 result = asn1_write_value (ext, "?LAST.reasons", NULL, 0);
1162 if (result != ASN1_SUCCESS)
1165 result = _gnutls_asn2err (result);
1170 result = asn1_write_value (ext, "?LAST.cRLIssuer", NULL, 0);
1171 if (result != ASN1_SUCCESS)
1174 result = _gnutls_asn2err (result);
1178 /* When used as type CHOICE.
1180 result = asn1_write_value (ext, "?LAST.distributionPoint", "fullName", 1);
1181 if (result != ASN1_SUCCESS)
1184 result = _gnutls_asn2err (result);
1189 /* only needed in old code (where defined as SEQUENCE OF) */
1190 asn1_write_value (ext,
1191 "?LAST.distributionPoint.nameRelativeToCRLIssuer",
1196 write_new_general_name (ext, "?LAST.distributionPoint.fullName",
1197 type, data, data_size);
1204 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
1215 _gnutls_free_datum (&gnames);
1216 asn1_delete_structure (&ext);
1221 /* extract the proxyCertInfo from the DER encoded extension
1224 _gnutls_x509_ext_extract_proxyCertInfo (int *pathLenConstraint,
1225 char **policyLanguage,
1227 size_t * sizeof_policy,
1228 opaque * extnValue, int extnValueLen)
1230 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
1232 gnutls_datum_t value;
1234 if ((result = asn1_create_element
1235 (_gnutls_get_pkix (), "PKIX1.ProxyCertInfo", &ext)) != ASN1_SUCCESS)
1238 return _gnutls_asn2err (result);
1241 result = asn1_der_decoding (&ext, extnValue, extnValueLen, NULL);
1242 if (result != ASN1_SUCCESS)
1245 asn1_delete_structure (&ext);
1246 return _gnutls_asn2err (result);
1249 if (pathLenConstraint)
1251 result = _gnutls_x509_read_uint (ext, "pCPathLenConstraint",
1253 if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1254 *pathLenConstraint = -1;
1255 else if (result != GNUTLS_E_SUCCESS)
1257 asn1_delete_structure (&ext);
1258 return _gnutls_asn2err (result);
1262 result = _gnutls_x509_read_value (ext, "proxyPolicy.policyLanguage",
1267 asn1_delete_structure (&ext);
1272 *policyLanguage = gnutls_strdup (value.data);
1274 result = _gnutls_x509_read_value (ext, "proxyPolicy.policy", &value, 0);
1275 if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1282 else if (result < 0)
1285 asn1_delete_structure (&ext);
1291 *policy = value.data;
1293 *sizeof_policy = value.size;
1296 asn1_delete_structure (&ext);
1301 /* generate the proxyCertInfo in a DER encoded extension
1304 _gnutls_x509_ext_gen_proxyCertInfo (int pathLenConstraint,
1305 const char *policyLanguage,
1307 size_t sizeof_policy,
1308 gnutls_datum_t * der_ext)
1310 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
1313 result = asn1_create_element (_gnutls_get_pkix (),
1314 "PKIX1.ProxyCertInfo", &ext);
1315 if (result != ASN1_SUCCESS)
1318 return _gnutls_asn2err (result);
1321 if (pathLenConstraint < 0)
1323 result = asn1_write_value (ext, "pCPathLenConstraint", NULL, 0);
1325 result = _gnutls_asn2err (result);
1328 result = _gnutls_x509_write_uint32 (ext, "pCPathLenConstraint",
1333 asn1_delete_structure (&ext);
1337 result = asn1_write_value (ext, "proxyPolicy.policyLanguage",
1342 asn1_delete_structure (&ext);
1343 return _gnutls_asn2err (result);
1346 result = asn1_write_value (ext, "proxyPolicy.policy",
1347 policy, sizeof_policy);
1351 asn1_delete_structure (&ext);
1352 return _gnutls_asn2err (result);
1355 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
1357 asn1_delete_structure (&ext);