2 * Copyright (C) 2003-2012 Free Software Foundation, Inc.
3 * Author: Nikos Mavrogiannopoulos, Simon Josefsson, Howard Chu
5 * This file is part of GnuTLS.
7 * The GnuTLS is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 3 of
10 * the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>
22 /* Functions on X.509 Certificate parsing
25 #include <gnutls_int.h>
26 #include <gnutls_datum.h>
27 #include <gnutls_global.h>
28 #include <gnutls_errors.h>
30 #include <gnutls_x509.h>
34 #include <gnutls_pk.h>
37 * gnutls_x509_crt_init:
38 * @cert: The structure to be initialized
40 * This function will initialize an X.509 certificate structure.
42 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
43 * negative error value.
46 gnutls_x509_crt_init (gnutls_x509_crt_t
* cert
)
48 gnutls_x509_crt_t tmp
= gnutls_calloc (1, sizeof (gnutls_x509_crt_int
));
52 return GNUTLS_E_MEMORY_ERROR
;
54 result
= asn1_create_element (_gnutls_get_pkix (),
55 "PKIX1.Certificate", &tmp
->cert
);
56 if (result
!= ASN1_SUCCESS
)
60 return _gnutls_asn2err (result
);
63 /* If you add anything here, be sure to check if it has to be added
64 to gnutls_x509_crt_import as well. */
68 return 0; /* success */
72 * _gnutls_x509_crt_cpy - This function copies a gnutls_x509_crt_t structure
73 * @dest: The structure where to copy
74 * @src: The structure to be copied
76 * This function will copy an X.509 certificate structure.
78 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
79 * negative error value.
82 _gnutls_x509_crt_cpy (gnutls_x509_crt_t dest
, gnutls_x509_crt_t src
)
89 ret
= gnutls_x509_crt_export (src
, GNUTLS_X509_FMT_DER
, NULL
, &der_size
);
90 if (ret
!= GNUTLS_E_SHORT_MEMORY_BUFFER
)
96 der
= gnutls_malloc (der_size
);
100 return GNUTLS_E_MEMORY_ERROR
;
103 ret
= gnutls_x509_crt_export (src
, GNUTLS_X509_FMT_DER
, der
, &der_size
);
113 ret
= gnutls_x509_crt_import (dest
, &tmp
, GNUTLS_X509_FMT_DER
);
127 * gnutls_x509_crt_deinit:
128 * @cert: The structure to be deinitialized
130 * This function will deinitialize a certificate structure.
133 gnutls_x509_crt_deinit (gnutls_x509_crt_t cert
)
139 asn1_delete_structure (&cert
->cert
);
145 * gnutls_x509_crt_import:
146 * @cert: The structure to store the parsed certificate.
147 * @data: The DER or PEM encoded certificate.
148 * @format: One of DER or PEM
150 * This function will convert the given DER or PEM encoded Certificate
151 * to the native gnutls_x509_crt_t format. The output will be stored
154 * If the Certificate is PEM encoded it should have a header of "X509
155 * CERTIFICATE", or "CERTIFICATE".
157 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
158 * negative error value.
161 gnutls_x509_crt_import (gnutls_x509_crt_t cert
,
162 const gnutls_datum_t
* data
,
163 gnutls_x509_crt_fmt_t format
)
165 int result
= 0, need_free
= 0;
166 gnutls_datum_t _data
;
171 return GNUTLS_E_INVALID_REQUEST
;
174 _data
.data
= data
->data
;
175 _data
.size
= data
->size
;
177 /* If the Certificate is in PEM format then decode it
179 if (format
== GNUTLS_X509_FMT_PEM
)
183 /* Try the first header */
185 _gnutls_fbase64_decode (PEM_X509_CERT2
, data
->data
, data
->size
, &out
);
189 /* try for the second header */
191 _gnutls_fbase64_decode (PEM_X509_CERT
, data
->data
,
197 result
= GNUTLS_E_INTERNAL_ERROR
;
211 /* Any earlier asn1_der_decoding will modify the ASN.1
212 structure, so we need to replace it with a fresh
214 asn1_delete_structure (&cert
->cert
);
216 result
= asn1_create_element (_gnutls_get_pkix (),
217 "PKIX1.Certificate", &cert
->cert
);
218 if (result
!= ASN1_SUCCESS
)
220 result
= _gnutls_asn2err (result
);
226 result
= asn1_der_decoding (&cert
->cert
, _data
.data
, _data
.size
, NULL
);
227 if (result
!= ASN1_SUCCESS
)
229 result
= _gnutls_asn2err (result
);
234 /* Since we do not want to disable any extension
236 cert
->use_extensions
= 1;
238 _gnutls_free_datum (&_data
);
244 _gnutls_free_datum (&_data
);
250 * gnutls_x509_crt_get_issuer_dn:
251 * @cert: should contain a #gnutls_x509_crt_t structure
252 * @buf: a pointer to a structure to hold the name (may be null)
253 * @buf_size: initially holds the size of @buf
255 * This function will copy the name of the Certificate issuer in the
256 * provided buffer. The name will be in the form
257 * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC4514. The output string
258 * will be ASCII or UTF-8 encoded, depending on the certificate data.
260 * If @buf is null then only the size will be filled.
262 * Returns: GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
263 * long enough, and in that case the @buf_size will be updated with
264 * the required size. On success 0 is returned.
267 gnutls_x509_crt_get_issuer_dn (gnutls_x509_crt_t cert
, char *buf
,
273 return GNUTLS_E_INVALID_REQUEST
;
276 return _gnutls_x509_parse_dn (cert
->cert
,
277 "tbsCertificate.issuer.rdnSequence", buf
,
282 * gnutls_x509_crt_get_issuer_dn_by_oid:
283 * @cert: should contain a #gnutls_x509_crt_t structure
284 * @oid: holds an Object Identified in null terminated string
285 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use (0) to get the first one.
286 * @raw_flag: If non (0) returns the raw DER data of the DN part.
287 * @buf: a pointer to a structure to hold the name (may be null)
288 * @buf_size: initially holds the size of @buf
290 * This function will extract the part of the name of the Certificate
291 * issuer specified by the given OID. The output, if the raw flag is not
292 * used, will be encoded as described in RFC4514. Thus a string that is
293 * ASCII or UTF-8 encoded, depending on the certificate data.
295 * Some helper macros with popular OIDs can be found in gnutls/x509.h
296 * If raw flag is (0), this function will only return known OIDs as
297 * text. Other OIDs will be DER encoded, as described in RFC4514 --
298 * in hex format with a '#' prefix. You can check about known OIDs
299 * using gnutls_x509_dn_oid_known().
301 * If @buf is null then only the size will be filled. If the @raw_flag
302 * is not specified the output is always null terminated, although the
303 * @buf_size will not include the null character.
305 * Returns: GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
306 * long enough, and in that case the @buf_size will be updated
307 * with the required size. On success 0 is returned.
310 gnutls_x509_crt_get_issuer_dn_by_oid (gnutls_x509_crt_t cert
,
311 const char *oid
, int indx
,
312 unsigned int raw_flag
, void *buf
,
318 return GNUTLS_E_INVALID_REQUEST
;
321 return _gnutls_x509_parse_dn_oid (cert
->cert
,
322 "tbsCertificate.issuer.rdnSequence",
323 oid
, indx
, raw_flag
, buf
, buf_size
);
327 * gnutls_x509_crt_get_issuer_dn_oid:
328 * @cert: should contain a #gnutls_x509_crt_t structure
329 * @indx: This specifies which OID to return. Use (0) to get the first one.
330 * @oid: a pointer to a buffer to hold the OID (may be null)
331 * @oid_size: initially holds the size of @oid
333 * This function will extract the OIDs of the name of the Certificate
334 * issuer specified by the given index.
336 * If @oid is null then only the size will be filled. The @oid
337 * returned will be null terminated, although @oid_size will not
338 * account for the trailing null.
340 * Returns: GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
341 * long enough, and in that case the @oid_size will be updated
342 * with the required size. On success 0 is returned.
345 gnutls_x509_crt_get_issuer_dn_oid (gnutls_x509_crt_t cert
,
346 int indx
, void *oid
, size_t * oid_size
)
351 return GNUTLS_E_INVALID_REQUEST
;
354 return _gnutls_x509_get_dn_oid (cert
->cert
,
355 "tbsCertificate.issuer.rdnSequence",
356 indx
, oid
, oid_size
);
360 * gnutls_x509_crt_get_dn:
361 * @cert: should contain a #gnutls_x509_crt_t structure
362 * @buf: a pointer to a structure to hold the name (may be null)
363 * @buf_size: initially holds the size of @buf
365 * This function will copy the name of the Certificate in the provided
366 * buffer. The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
367 * described in RFC4514. The output string will be ASCII or UTF-8
368 * encoded, depending on the certificate data.
370 * If @buf is null then only the size will be filled.
372 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
373 * long enough, and in that case the @buf_size will be updated
374 * with the required size. On success 0 is returned.
377 gnutls_x509_crt_get_dn (gnutls_x509_crt_t cert
, char *buf
,
383 return GNUTLS_E_INVALID_REQUEST
;
386 return _gnutls_x509_parse_dn (cert
->cert
,
387 "tbsCertificate.subject.rdnSequence", buf
,
392 * gnutls_x509_crt_get_dn_by_oid:
393 * @cert: should contain a #gnutls_x509_crt_t structure
394 * @oid: holds an Object Identified in null terminated string
395 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use (0) to get the first one.
396 * @raw_flag: If non (0) returns the raw DER data of the DN part.
397 * @buf: a pointer where the DN part will be copied (may be null).
398 * @buf_size: initially holds the size of @buf
400 * This function will extract the part of the name of the Certificate
401 * subject specified by the given OID. The output, if the raw flag is
402 * not used, will be encoded as described in RFC4514. Thus a string
403 * that is ASCII or UTF-8 encoded, depending on the certificate data.
405 * Some helper macros with popular OIDs can be found in gnutls/x509.h
406 * If raw flag is (0), this function will only return known OIDs as
407 * text. Other OIDs will be DER encoded, as described in RFC4514 --
408 * in hex format with a '#' prefix. You can check about known OIDs
409 * using gnutls_x509_dn_oid_known().
411 * If @buf is null then only the size will be filled. If the @raw_flag
412 * is not specified the output is always null terminated, although the
413 * @buf_size will not include the null character.
415 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
416 * not long enough, and in that case the *buf_size will be updated
417 * with the required size. On success 0 is returned.
420 gnutls_x509_crt_get_dn_by_oid (gnutls_x509_crt_t cert
, const char *oid
,
421 int indx
, unsigned int raw_flag
,
422 void *buf
, size_t * buf_size
)
427 return GNUTLS_E_INVALID_REQUEST
;
430 return _gnutls_x509_parse_dn_oid (cert
->cert
,
431 "tbsCertificate.subject.rdnSequence",
432 oid
, indx
, raw_flag
, buf
, buf_size
);
436 * gnutls_x509_crt_get_dn_oid:
437 * @cert: should contain a #gnutls_x509_crt_t structure
438 * @indx: This specifies which OID to return. Use (0) to get the first one.
439 * @oid: a pointer to a buffer to hold the OID (may be null)
440 * @oid_size: initially holds the size of @oid
442 * This function will extract the OIDs of the name of the Certificate
443 * subject specified by the given index.
445 * If @oid is null then only the size will be filled. The @oid
446 * returned will be null terminated, although @oid_size will not
447 * account for the trailing null.
449 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
450 * not long enough, and in that case the @oid_size will be updated
451 * with the required size. On success 0 is returned.
454 gnutls_x509_crt_get_dn_oid (gnutls_x509_crt_t cert
,
455 int indx
, void *oid
, size_t * oid_size
)
460 return GNUTLS_E_INVALID_REQUEST
;
463 return _gnutls_x509_get_dn_oid (cert
->cert
,
464 "tbsCertificate.subject.rdnSequence",
465 indx
, oid
, oid_size
);
469 * gnutls_x509_crt_get_signature_algorithm:
470 * @cert: should contain a #gnutls_x509_crt_t structure
472 * This function will return a value of the #gnutls_sign_algorithm_t
473 * enumeration that is the signature algorithm that has been used to
474 * sign this certificate.
476 * Returns: a #gnutls_sign_algorithm_t value, or a negative error code on
480 gnutls_x509_crt_get_signature_algorithm (gnutls_x509_crt_t cert
)
482 return _gnutls_x509_get_signature_algorithm(cert
->cert
, "signatureAlgorithm.algorithm");
486 * gnutls_x509_crt_get_signature:
487 * @cert: should contain a #gnutls_x509_crt_t structure
488 * @sig: a pointer where the signature part will be copied (may be null).
489 * @sizeof_sig: initially holds the size of @sig
491 * This function will extract the signature field of a certificate.
493 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
494 * negative error value. and a negative error code on error.
497 gnutls_x509_crt_get_signature (gnutls_x509_crt_t cert
,
498 char *sig
, size_t * sizeof_sig
)
507 return GNUTLS_E_INVALID_REQUEST
;
511 result
= asn1_read_value (cert
->cert
, "signature", NULL
, &len
);
512 if (result
!= ASN1_MEM_ERROR
)
515 return _gnutls_asn2err (result
);
522 return GNUTLS_E_CERTIFICATE_ERROR
;
527 if (*sizeof_sig
< (unsigned int) len
)
530 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
533 result
= asn1_read_value (cert
->cert
, "signature", sig
, &len
);
534 if (result
!= ASN1_SUCCESS
)
537 return _gnutls_asn2err (result
);
544 * gnutls_x509_crt_get_version:
545 * @cert: should contain a #gnutls_x509_crt_t structure
547 * This function will return the version of the specified Certificate.
549 * Returns: version of certificate, or a negative error code on error.
552 gnutls_x509_crt_get_version (gnutls_x509_crt_t cert
)
560 return GNUTLS_E_INVALID_REQUEST
;
563 len
= sizeof (version
);
565 asn1_read_value (cert
->cert
, "tbsCertificate.version", version
,
566 &len
)) != ASN1_SUCCESS
)
569 if (result
== ASN1_ELEMENT_NOT_FOUND
)
570 return 1; /* the DEFAULT version */
572 return _gnutls_asn2err (result
);
575 return (int) version
[0] + 1;
579 * gnutls_x509_crt_get_activation_time:
580 * @cert: should contain a #gnutls_x509_crt_t structure
582 * This function will return the time this Certificate was or will be
585 * Returns: activation time, or (time_t)-1 on error.
588 gnutls_x509_crt_get_activation_time (gnutls_x509_crt_t cert
)
596 return _gnutls_x509_get_time (cert
->cert
,
597 "tbsCertificate.validity.notBefore", 0);
601 * gnutls_x509_crt_get_expiration_time:
602 * @cert: should contain a #gnutls_x509_crt_t structure
604 * This function will return the time this Certificate was or will be
607 * Returns: expiration time, or (time_t)-1 on error.
610 gnutls_x509_crt_get_expiration_time (gnutls_x509_crt_t cert
)
618 return _gnutls_x509_get_time (cert
->cert
,
619 "tbsCertificate.validity.notAfter", 0);
623 * gnutls_x509_crt_get_private_key_usage_period:
624 * @cert: should contain a #gnutls_x509_crt_t structure
625 * @activation: The activation time
626 * @expiration: The expiration time
627 * @critical: the extension status
629 * This function will return the expiration and activation
630 * times of the private key of the certificate. It relies on
631 * the PKIX extension 2.5.29.16 being present.
633 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
634 * if the extension is not present, otherwise a negative error value.
637 gnutls_x509_crt_get_private_key_usage_period (gnutls_x509_crt_t cert
, time_t* activation
, time_t* expiration
,
638 unsigned int *critical
)
641 gnutls_datum_t der
= {NULL
, 0};
642 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
647 return GNUTLS_E_INVALID_REQUEST
;
651 _gnutls_x509_crt_get_extension (cert
, "2.5.29.16", 0, &der
,
654 return gnutls_assert_val(ret
);
656 if (der
.size
== 0 || der
.data
== NULL
)
657 return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
);
659 result
= asn1_create_element
660 (_gnutls_get_pkix (), "PKIX1.PrivateKeyUsagePeriod", &c2
);
661 if (result
!= ASN1_SUCCESS
)
664 ret
= _gnutls_asn2err (result
);
668 result
= asn1_der_decoding (&c2
, der
.data
, der
.size
, NULL
);
669 if (result
!= ASN1_SUCCESS
)
672 ret
= _gnutls_asn2err (result
);
677 *activation
= _gnutls_x509_get_time (c2
,
681 *expiration
= _gnutls_x509_get_time (c2
,
687 _gnutls_free_datum(&der
);
688 asn1_delete_structure (&c2
);
695 * gnutls_x509_crt_get_serial:
696 * @cert: should contain a #gnutls_x509_crt_t structure
697 * @result: The place where the serial number will be copied
698 * @result_size: Holds the size of the result field.
700 * This function will return the X.509 certificate's serial number.
701 * This is obtained by the X509 Certificate serialNumber field. Serial
702 * is not always a 32 or 64bit number. Some CAs use large serial
703 * numbers, thus it may be wise to handle it as something uint8_t.
705 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
706 * negative error value.
709 gnutls_x509_crt_get_serial (gnutls_x509_crt_t cert
, void *result
,
710 size_t * result_size
)
717 return GNUTLS_E_INVALID_REQUEST
;
722 asn1_read_value (cert
->cert
, "tbsCertificate.serialNumber", result
, &len
);
725 if (ret
!= ASN1_SUCCESS
)
728 return _gnutls_asn2err (ret
);
735 * gnutls_x509_crt_get_subject_key_id:
736 * @cert: should contain a #gnutls_x509_crt_t structure
737 * @ret: The place where the identifier will be copied
738 * @ret_size: Holds the size of the result field.
739 * @critical: will be non (0) if the extension is marked as critical (may be null)
741 * This function will return the X.509v3 certificate's subject key
742 * identifier. This is obtained by the X.509 Subject Key identifier
743 * extension field (2.5.29.14).
745 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
746 * if the extension is not present, otherwise a negative error value.
749 gnutls_x509_crt_get_subject_key_id (gnutls_x509_crt_t cert
, void *ret
,
750 size_t * ret_size
, unsigned int *critical
)
754 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
759 return GNUTLS_E_INVALID_REQUEST
;
764 memset (ret
, 0, *ret_size
);
769 _gnutls_x509_crt_get_extension (cert
, "2.5.29.14", 0, &id
,
775 if (id
.size
== 0 || id
.data
== NULL
)
778 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
781 result
= asn1_create_element
782 (_gnutls_get_pkix (), "PKIX1.SubjectKeyIdentifier", &c2
);
783 if (result
!= ASN1_SUCCESS
)
786 _gnutls_free_datum (&id
);
787 return _gnutls_asn2err (result
);
790 result
= asn1_der_decoding (&c2
, id
.data
, id
.size
, NULL
);
791 _gnutls_free_datum (&id
);
793 if (result
!= ASN1_SUCCESS
)
796 asn1_delete_structure (&c2
);
797 return _gnutls_asn2err (result
);
801 result
= asn1_read_value (c2
, "", ret
, &len
);
804 asn1_delete_structure (&c2
);
806 if (result
== ASN1_VALUE_NOT_FOUND
|| result
== ASN1_ELEMENT_NOT_FOUND
)
808 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
811 if (result
!= ASN1_SUCCESS
)
813 if (result
!= ASN1_MEM_ERROR
)
815 return _gnutls_asn2err (result
);
822 _get_authority_key_id (gnutls_x509_crt_t cert
, ASN1_TYPE
*c2
,
823 unsigned int *critical
)
828 *c2
= ASN1_TYPE_EMPTY
;
833 return GNUTLS_E_INVALID_REQUEST
;
837 _gnutls_x509_crt_get_extension (cert
, "2.5.29.35", 0, &id
,
840 return gnutls_assert_val(ret
);
843 if (id
.size
== 0 || id
.data
== NULL
)
846 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
849 ret
= asn1_create_element
850 (_gnutls_get_pkix (), "PKIX1.AuthorityKeyIdentifier", c2
);
851 if (ret
!= ASN1_SUCCESS
)
854 _gnutls_free_datum (&id
);
855 return _gnutls_asn2err (ret
);
858 ret
= asn1_der_decoding (c2
, id
.data
, id
.size
, NULL
);
859 _gnutls_free_datum (&id
);
861 if (ret
!= ASN1_SUCCESS
)
864 asn1_delete_structure (c2
);
865 return _gnutls_asn2err (ret
);
872 * gnutls_x509_crt_get_authority_key_gn_serial:
873 * @cert: should contain a #gnutls_x509_crt_t structure
874 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
875 * @alt: is the place where the alternative name will be copied to
876 * @alt_size: holds the size of alt.
877 * @alt_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
878 * @serial: buffer to store the serial number (may be null)
879 * @serial_size: Holds the size of the serial field (may be null)
880 * @critical: will be non (0) if the extension is marked as critical (may be null)
882 * This function will return the X.509 authority key
883 * identifier when stored as a general name (authorityCertIssuer)
886 * Because more than one general names might be stored
887 * @seq can be used as a counter to request them all until
888 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
890 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
891 * if the extension is not present, otherwise a negative error value.
896 gnutls_x509_crt_get_authority_key_gn_serial (gnutls_x509_crt_t cert
, unsigned int seq
, void *alt
,
897 size_t * alt_size
, unsigned int *alt_type
,
898 void* serial
, size_t *serial_size
,
899 unsigned int *critical
)
901 int ret
, result
, len
;
904 ret
= _get_authority_key_id(cert
, &c2
, critical
);
906 return gnutls_assert_val(ret
);
909 _gnutls_parse_general_name (c2
, "authorityCertIssuer", seq
, alt
, alt_size
, alt_type
,
913 ret
= gnutls_assert_val(ret
);
920 result
= asn1_read_value (c2
, "authorityCertSerialNumber", serial
, &len
);
926 ret
= _gnutls_asn2err(result
);
935 asn1_delete_structure (&c2
);
941 * gnutls_x509_crt_get_authority_key_id:
942 * @cert: should contain a #gnutls_x509_crt_t structure
943 * @id: The place where the identifier will be copied
944 * @id_size: Holds the size of the id field.
945 * @critical: will be non (0) if the extension is marked as critical (may be null)
947 * This function will return the X.509v3 certificate authority's key
948 * identifier. This is obtained by the X.509 Authority Key
949 * identifier extension field (2.5.29.35). Note that this function
950 * only returns the keyIdentifier field of the extension and
951 * %GNUTLS_E_X509_UNSUPPORTED_EXTENSION, if the extension contains
952 * the name and serial number of the certificate. In that case
953 * gnutls_x509_crt_get_authority_key_gn_serial() may be used.
955 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
956 * if the extension is not present, otherwise a negative error value.
959 gnutls_x509_crt_get_authority_key_id (gnutls_x509_crt_t cert
, void *id
,
961 unsigned int *critical
)
963 int ret
, result
, len
;
966 ret
= _get_authority_key_id(cert
, &c2
, critical
);
968 return gnutls_assert_val(ret
);
971 result
= asn1_read_value (c2
, "keyIdentifier", id
, &len
);
974 asn1_delete_structure (&c2
);
976 if (result
== ASN1_VALUE_NOT_FOUND
|| result
== ASN1_ELEMENT_NOT_FOUND
)
977 return gnutls_assert_val(GNUTLS_E_X509_UNSUPPORTED_EXTENSION
);
979 if (result
!= ASN1_SUCCESS
)
981 if (result
!= ASN1_MEM_ERROR
)
983 return _gnutls_asn2err (result
);
990 * gnutls_x509_crt_get_pk_algorithm:
991 * @cert: should contain a #gnutls_x509_crt_t structure
992 * @bits: if bits is non null it will hold the size of the parameters' in bits
994 * This function will return the public key algorithm of an X.509
997 * If bits is non null, it should have enough size to hold the parameters
998 * size in bits. For RSA the bits returned is the modulus.
999 * For DSA the bits returned are of the public
1002 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
1003 * success, or a negative error code on error.
1006 gnutls_x509_crt_get_pk_algorithm (gnutls_x509_crt_t cert
, unsigned int *bits
)
1013 return GNUTLS_E_INVALID_REQUEST
;
1020 _gnutls_x509_get_pk_algorithm (cert
->cert
,
1021 "tbsCertificate.subjectPublicKeyInfo",
1035 is_type_printable (int type
)
1037 if (type
== GNUTLS_SAN_DNSNAME
|| type
== GNUTLS_SAN_RFC822NAME
||
1038 type
== GNUTLS_SAN_URI
)
1044 #define XMPP_OID "1.3.6.1.5.5.7.8.5"
1046 /* returns the type and the name on success.
1047 * Type is also returned as a parameter in case of an error.
1050 _gnutls_parse_general_name (ASN1_TYPE src
, const char *src_name
,
1051 int seq
, void *name
, size_t * name_size
,
1052 unsigned int *ret_type
, int othername_oid
)
1055 char nptr
[ASN1_MAX_NAME_SIZE
];
1057 char choice_type
[128];
1058 gnutls_x509_subject_alt_name_t type
;
1060 seq
++; /* 0->1, 1->2 etc */
1062 if (src_name
[0] != 0)
1063 snprintf (nptr
, sizeof (nptr
), "%s.?%u", src_name
, seq
);
1065 snprintf (nptr
, sizeof (nptr
), "?%u", seq
);
1067 len
= sizeof (choice_type
);
1068 result
= asn1_read_value (src
, nptr
, choice_type
, &len
);
1070 if (result
== ASN1_VALUE_NOT_FOUND
|| result
== ASN1_ELEMENT_NOT_FOUND
)
1072 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1075 if (result
!= ASN1_SUCCESS
)
1078 return _gnutls_asn2err (result
);
1082 type
= _gnutls_x509_san_find_type (choice_type
);
1083 if (type
== (gnutls_x509_subject_alt_name_t
) - 1)
1086 return GNUTLS_E_X509_UNKNOWN_SAN
;
1092 if (type
== GNUTLS_SAN_OTHERNAME
)
1095 _gnutls_str_cat (nptr
, sizeof (nptr
), ".otherName.type-id");
1097 _gnutls_str_cat (nptr
, sizeof (nptr
), ".otherName.value");
1100 result
= asn1_read_value (src
, nptr
, name
, &len
);
1103 if (result
== ASN1_MEM_ERROR
)
1104 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
1106 if (result
!= ASN1_SUCCESS
)
1109 return _gnutls_asn2err (result
);
1114 if ((unsigned)len
> strlen (XMPP_OID
) && strcmp (name
, XMPP_OID
) == 0)
1115 type
= GNUTLS_SAN_OTHERNAME_XMPP
;
1121 if (src_name
[0] != 0)
1122 snprintf (nptr
, sizeof (nptr
), "%s.?%u.otherName.type-id",
1125 snprintf (nptr
, sizeof (nptr
), "?%u.otherName.type-id", seq
);
1128 result
= asn1_read_value (src
, nptr
, oid
, &len
);
1129 if (result
!= ASN1_SUCCESS
)
1132 return _gnutls_asn2err (result
);
1135 if ((unsigned)len
> strlen (XMPP_OID
) && strcmp (oid
, XMPP_OID
) == 0)
1137 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
1138 size_t orig_name_size
= *name_size
;
1140 result
= asn1_create_element
1141 (_gnutls_get_pkix (), "PKIX1.UTF8String", &c2
);
1142 if (result
!= ASN1_SUCCESS
)
1145 return _gnutls_asn2err (result
);
1148 result
= asn1_der_decoding (&c2
, name
, *name_size
, NULL
);
1149 if (result
!= ASN1_SUCCESS
)
1152 asn1_delete_structure (&c2
);
1153 return _gnutls_asn2err (result
);
1157 result
= asn1_read_value (c2
, "", name
, &len
);
1158 if (result
!= ASN1_SUCCESS
)
1161 asn1_delete_structure (&c2
);
1162 *name_size
= len
+ 1;
1163 return _gnutls_asn2err (result
);
1165 asn1_delete_structure (&c2
);
1167 if ((unsigned)len
+ 1 > orig_name_size
)
1170 *name_size
= len
+ 1;
1171 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
1175 /* null terminate it */
1176 ((char *) name
)[*name_size
] = 0;
1180 else if (type
== GNUTLS_SAN_DN
)
1182 _gnutls_str_cat (nptr
, sizeof (nptr
), ".directoryName");
1183 result
= _gnutls_x509_parse_dn (src
, nptr
, name
, name_size
);
1190 else if (othername_oid
)
1191 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1194 size_t orig_name_size
= *name_size
;
1196 _gnutls_str_cat (nptr
, sizeof (nptr
), ".");
1197 _gnutls_str_cat (nptr
, sizeof (nptr
), choice_type
);
1200 result
= asn1_read_value (src
, nptr
, name
, &len
);
1203 if (result
== ASN1_MEM_ERROR
)
1205 if (is_type_printable (type
))
1207 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
1210 if (result
!= ASN1_SUCCESS
)
1213 return _gnutls_asn2err (result
);
1216 if (is_type_printable (type
))
1219 if ((unsigned)len
+ 1 > orig_name_size
)
1223 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
1226 /* null terminate it */
1227 ((char *) name
)[*name_size
] = 0;
1236 get_alt_name (gnutls_x509_crt_t cert
, const char *extension_id
,
1237 unsigned int seq
, void *alt
,
1238 size_t * alt_size
, unsigned int *alt_type
,
1239 unsigned int *critical
, int othername_oid
)
1242 gnutls_datum_t dnsname
;
1243 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
1248 return GNUTLS_E_INVALID_REQUEST
;
1252 memset (alt
, 0, *alt_size
);
1257 _gnutls_x509_crt_get_extension (cert
, extension_id
, 0, &dnsname
,
1263 if (dnsname
.size
== 0 || dnsname
.data
== NULL
)
1266 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1269 if (strcmp ("2.5.29.17", extension_id
) == 0)
1270 result
= asn1_create_element (_gnutls_get_pkix (),
1271 "PKIX1.SubjectAltName", &c2
);
1272 else if (strcmp ("2.5.29.18", extension_id
) == 0)
1273 result
= asn1_create_element (_gnutls_get_pkix (),
1274 "PKIX1.IssuerAltName", &c2
);
1278 return GNUTLS_E_INTERNAL_ERROR
;
1281 if (result
!= ASN1_SUCCESS
)
1284 _gnutls_free_datum (&dnsname
);
1285 return _gnutls_asn2err (result
);
1288 result
= asn1_der_decoding (&c2
, dnsname
.data
, dnsname
.size
, NULL
);
1289 _gnutls_free_datum (&dnsname
);
1291 if (result
!= ASN1_SUCCESS
)
1294 asn1_delete_structure (&c2
);
1295 return _gnutls_asn2err (result
);
1299 _gnutls_parse_general_name (c2
, "", seq
, alt
, alt_size
, alt_type
,
1302 asn1_delete_structure (&c2
);
1314 * gnutls_x509_crt_get_subject_alt_name:
1315 * @cert: should contain a #gnutls_x509_crt_t structure
1316 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1317 * @san: is the place where the alternative name will be copied to
1318 * @san_size: holds the size of san.
1319 * @critical: will be non (0) if the extension is marked as critical (may be null)
1321 * This function retrieves the Alternative Name (2.5.29.17), contained
1322 * in the given certificate in the X509v3 Certificate Extensions.
1324 * When the SAN type is otherName, it will extract the data in the
1325 * otherName's value field, and %GNUTLS_SAN_OTHERNAME is returned.
1326 * You may use gnutls_x509_crt_get_subject_alt_othername_oid() to get
1327 * the corresponding OID and the "virtual" SAN types (e.g.,
1328 * %GNUTLS_SAN_OTHERNAME_XMPP).
1330 * If an otherName OID is known, the data will be decoded. Otherwise
1331 * the returned data will be DER encoded, and you will have to decode
1332 * it yourself. Currently, only the RFC 3920 id-on-xmppAddr SAN is
1335 * Returns: the alternative subject name type on success, one of the
1336 * enumerated #gnutls_x509_subject_alt_name_t. It will return
1337 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @san_size is not large enough to
1338 * hold the value. In that case @san_size will be updated with the
1339 * required size. If the certificate does not have an Alternative
1340 * name with the specified sequence number then
1341 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1344 gnutls_x509_crt_get_subject_alt_name (gnutls_x509_crt_t cert
,
1345 unsigned int seq
, void *san
,
1347 unsigned int *critical
)
1349 return get_alt_name (cert
, "2.5.29.17", seq
, san
, san_size
, NULL
, critical
,
1354 * gnutls_x509_crt_get_issuer_alt_name:
1355 * @cert: should contain a #gnutls_x509_crt_t structure
1356 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1357 * @ian: is the place where the alternative name will be copied to
1358 * @ian_size: holds the size of ian.
1359 * @critical: will be non (0) if the extension is marked as critical (may be null)
1361 * This function retrieves the Issuer Alternative Name (2.5.29.18),
1362 * contained in the given certificate in the X509v3 Certificate
1365 * When the SAN type is otherName, it will extract the data in the
1366 * otherName's value field, and %GNUTLS_SAN_OTHERNAME is returned.
1367 * You may use gnutls_x509_crt_get_subject_alt_othername_oid() to get
1368 * the corresponding OID and the "virtual" SAN types (e.g.,
1369 * %GNUTLS_SAN_OTHERNAME_XMPP).
1371 * If an otherName OID is known, the data will be decoded. Otherwise
1372 * the returned data will be DER encoded, and you will have to decode
1373 * it yourself. Currently, only the RFC 3920 id-on-xmppAddr Issuer
1374 * AltName is recognized.
1376 * Returns: the alternative issuer name type on success, one of the
1377 * enumerated #gnutls_x509_subject_alt_name_t. It will return
1378 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @ian_size is not large enough
1379 * to hold the value. In that case @ian_size will be updated with
1380 * the required size. If the certificate does not have an
1381 * Alternative name with the specified sequence number then
1382 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1387 gnutls_x509_crt_get_issuer_alt_name (gnutls_x509_crt_t cert
,
1388 unsigned int seq
, void *ian
,
1390 unsigned int *critical
)
1392 return get_alt_name (cert
, "2.5.29.18", seq
, ian
, ian_size
, NULL
, critical
,
1397 * gnutls_x509_crt_get_subject_alt_name2:
1398 * @cert: should contain a #gnutls_x509_crt_t structure
1399 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1400 * @san: is the place where the alternative name will be copied to
1401 * @san_size: holds the size of ret.
1402 * @san_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
1403 * @critical: will be non (0) if the extension is marked as critical (may be null)
1405 * This function will return the alternative names, contained in the
1406 * given certificate. It is the same as
1407 * gnutls_x509_crt_get_subject_alt_name() except for the fact that it
1408 * will return the type of the alternative name in @san_type even if
1409 * the function fails for some reason (i.e. the buffer provided is
1412 * Returns: the alternative subject name type on success, one of the
1413 * enumerated #gnutls_x509_subject_alt_name_t. It will return
1414 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @san_size is not large enough
1415 * to hold the value. In that case @san_size will be updated with
1416 * the required size. If the certificate does not have an
1417 * Alternative name with the specified sequence number then
1418 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1421 gnutls_x509_crt_get_subject_alt_name2 (gnutls_x509_crt_t cert
,
1422 unsigned int seq
, void *san
,
1424 unsigned int *san_type
,
1425 unsigned int *critical
)
1427 return get_alt_name (cert
, "2.5.29.17", seq
, san
, san_size
, san_type
,
1432 * gnutls_x509_crt_get_issuer_alt_name2:
1433 * @cert: should contain a #gnutls_x509_crt_t structure
1434 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1435 * @ian: is the place where the alternative name will be copied to
1436 * @ian_size: holds the size of ret.
1437 * @ian_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
1438 * @critical: will be non (0) if the extension is marked as critical (may be null)
1440 * This function will return the alternative names, contained in the
1441 * given certificate. It is the same as
1442 * gnutls_x509_crt_get_issuer_alt_name() except for the fact that it
1443 * will return the type of the alternative name in @ian_type even if
1444 * the function fails for some reason (i.e. the buffer provided is
1447 * Returns: the alternative issuer name type on success, one of the
1448 * enumerated #gnutls_x509_subject_alt_name_t. It will return
1449 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @ian_size is not large enough
1450 * to hold the value. In that case @ian_size will be updated with
1451 * the required size. If the certificate does not have an
1452 * Alternative name with the specified sequence number then
1453 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1459 gnutls_x509_crt_get_issuer_alt_name2 (gnutls_x509_crt_t cert
,
1460 unsigned int seq
, void *ian
,
1462 unsigned int *ian_type
,
1463 unsigned int *critical
)
1465 return get_alt_name (cert
, "2.5.29.18", seq
, ian
, ian_size
, ian_type
,
1470 * gnutls_x509_crt_get_subject_alt_othername_oid:
1471 * @cert: should contain a #gnutls_x509_crt_t structure
1472 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1473 * @oid: is the place where the otherName OID will be copied to
1474 * @oid_size: holds the size of ret.
1476 * This function will extract the type OID of an otherName Subject
1477 * Alternative Name, contained in the given certificate, and return
1478 * the type as an enumerated element.
1480 * This function is only useful if
1481 * gnutls_x509_crt_get_subject_alt_name() returned
1482 * %GNUTLS_SAN_OTHERNAME.
1484 * If @oid is null then only the size will be filled. The @oid
1485 * returned will be null terminated, although @oid_size will not
1486 * account for the trailing null.
1488 * Returns: the alternative subject name type on success, one of the
1489 * enumerated gnutls_x509_subject_alt_name_t. For supported OIDs, it
1490 * will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
1491 * e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
1492 * unknown OIDs. It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
1493 * @ian_size is not large enough to hold the value. In that case
1494 * @ian_size will be updated with the required size. If the
1495 * certificate does not have an Alternative name with the specified
1496 * sequence number and with the otherName type then
1497 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1500 gnutls_x509_crt_get_subject_alt_othername_oid (gnutls_x509_crt_t cert
,
1502 void *oid
, size_t * oid_size
)
1504 return get_alt_name (cert
, "2.5.29.17", seq
, oid
, oid_size
, NULL
, NULL
, 1);
1508 * gnutls_x509_crt_get_issuer_alt_othername_oid:
1509 * @cert: should contain a #gnutls_x509_crt_t structure
1510 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1511 * @ret: is the place where the otherName OID will be copied to
1512 * @ret_size: holds the size of ret.
1514 * This function will extract the type OID of an otherName Subject
1515 * Alternative Name, contained in the given certificate, and return
1516 * the type as an enumerated element.
1518 * If @oid is null then only the size will be filled. The @oid
1519 * returned will be null terminated, although @oid_size will not
1520 * account for the trailing null.
1522 * This function is only useful if
1523 * gnutls_x509_crt_get_issuer_alt_name() returned
1524 * %GNUTLS_SAN_OTHERNAME.
1526 * Returns: the alternative issuer name type on success, one of the
1527 * enumerated gnutls_x509_subject_alt_name_t. For supported OIDs, it
1528 * will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
1529 * e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
1530 * unknown OIDs. It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
1531 * @ret_size is not large enough to hold the value. In that case
1532 * @ret_size will be updated with the required size. If the
1533 * certificate does not have an Alternative name with the specified
1534 * sequence number and with the otherName type then
1535 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1540 gnutls_x509_crt_get_issuer_alt_othername_oid (gnutls_x509_crt_t cert
,
1542 void *ret
, size_t * ret_size
)
1544 return get_alt_name (cert
, "2.5.29.18", seq
, ret
, ret_size
, NULL
, NULL
, 1);
1548 * gnutls_x509_crt_get_basic_constraints:
1549 * @cert: should contain a #gnutls_x509_crt_t structure
1550 * @critical: will be non (0) if the extension is marked as critical
1551 * @ca: pointer to output integer indicating CA status, may be NULL,
1552 * value is 1 if the certificate CA flag is set, 0 otherwise.
1553 * @pathlen: pointer to output integer indicating path length (may be
1554 * NULL), non-negative error codes indicate a present pathLenConstraint
1555 * field and the actual value, -1 indicate that the field is absent.
1557 * This function will read the certificate's basic constraints, and
1558 * return the certificates CA status. It reads the basicConstraints
1559 * X.509 extension (2.5.29.19).
1561 * Returns: If the certificate is a CA a positive value will be
1562 * returned, or (0) if the certificate does not have CA flag set. A
1563 * negative error code may be returned in case of errors. If the
1564 * certificate does not contain the basicConstraints extension
1565 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1568 gnutls_x509_crt_get_basic_constraints (gnutls_x509_crt_t cert
,
1569 unsigned int *critical
,
1570 unsigned int *ca
, int *pathlen
)
1573 gnutls_datum_t basicConstraints
;
1574 unsigned int tmp_ca
;
1579 return GNUTLS_E_INVALID_REQUEST
;
1583 _gnutls_x509_crt_get_extension (cert
, "2.5.29.19", 0,
1584 &basicConstraints
, critical
)) < 0)
1589 if (basicConstraints
.size
== 0 || basicConstraints
.data
== NULL
)
1592 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1596 _gnutls_x509_ext_extract_basicConstraints (&tmp_ca
,
1598 basicConstraints
.data
,
1599 basicConstraints
.size
);
1602 _gnutls_free_datum (&basicConstraints
);
1614 * gnutls_x509_crt_get_ca_status:
1615 * @cert: should contain a #gnutls_x509_crt_t structure
1616 * @critical: will be non (0) if the extension is marked as critical
1618 * This function will return certificates CA status, by reading the
1619 * basicConstraints X.509 extension (2.5.29.19). If the certificate is
1620 * a CA a positive value will be returned, or (0) if the certificate
1621 * does not have CA flag set.
1623 * Use gnutls_x509_crt_get_basic_constraints() if you want to read the
1624 * pathLenConstraint field too.
1626 * Returns: A negative error code may be returned in case of parsing error.
1627 * If the certificate does not contain the basicConstraints extension
1628 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1631 gnutls_x509_crt_get_ca_status (gnutls_x509_crt_t cert
, unsigned int *critical
)
1635 return gnutls_x509_crt_get_basic_constraints (cert
, critical
, &ca
,
1640 * gnutls_x509_crt_get_key_usage:
1641 * @cert: should contain a #gnutls_x509_crt_t structure
1642 * @key_usage: where the key usage bits will be stored
1643 * @critical: will be non (0) if the extension is marked as critical
1645 * This function will return certificate's key usage, by reading the
1646 * keyUsage X.509 extension (2.5.29.15). The key usage value will ORed
1647 * values of the: %GNUTLS_KEY_DIGITAL_SIGNATURE,
1648 * %GNUTLS_KEY_NON_REPUDIATION, %GNUTLS_KEY_KEY_ENCIPHERMENT,
1649 * %GNUTLS_KEY_DATA_ENCIPHERMENT, %GNUTLS_KEY_KEY_AGREEMENT,
1650 * %GNUTLS_KEY_KEY_CERT_SIGN, %GNUTLS_KEY_CRL_SIGN,
1651 * %GNUTLS_KEY_ENCIPHER_ONLY, %GNUTLS_KEY_DECIPHER_ONLY.
1653 * Returns: the certificate key usage, or a negative error code in case of
1654 * parsing error. If the certificate does not contain the keyUsage
1655 * extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
1659 gnutls_x509_crt_get_key_usage (gnutls_x509_crt_t cert
,
1660 unsigned int *key_usage
,
1661 unsigned int *critical
)
1664 gnutls_datum_t keyUsage
;
1670 return GNUTLS_E_INVALID_REQUEST
;
1674 _gnutls_x509_crt_get_extension (cert
, "2.5.29.15", 0, &keyUsage
,
1680 if (keyUsage
.size
== 0 || keyUsage
.data
== NULL
)
1683 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1686 result
= _gnutls_x509_ext_extract_keyUsage (&_usage
, keyUsage
.data
,
1688 _gnutls_free_datum (&keyUsage
);
1690 *key_usage
= _usage
;
1702 * gnutls_x509_crt_get_proxy:
1703 * @cert: should contain a #gnutls_x509_crt_t structure
1704 * @critical: will be non (0) if the extension is marked as critical
1705 * @pathlen: pointer to output integer indicating path length (may be
1706 * NULL), non-negative error codes indicate a present pCPathLenConstraint
1707 * field and the actual value, -1 indicate that the field is absent.
1708 * @policyLanguage: output variable with OID of policy language
1709 * @policy: output variable with policy data
1710 * @sizeof_policy: output variable size of policy data
1712 * This function will get information from a proxy certificate. It
1713 * reads the ProxyCertInfo X.509 extension (1.3.6.1.5.5.7.1.14).
1715 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1716 * otherwise a negative error code is returned.
1719 gnutls_x509_crt_get_proxy (gnutls_x509_crt_t cert
,
1720 unsigned int *critical
,
1722 char **policyLanguage
,
1723 char **policy
, size_t * sizeof_policy
)
1726 gnutls_datum_t proxyCertInfo
;
1731 return GNUTLS_E_INVALID_REQUEST
;
1735 _gnutls_x509_crt_get_extension (cert
, "1.3.6.1.5.5.7.1.14", 0,
1736 &proxyCertInfo
, critical
)) < 0)
1741 if (proxyCertInfo
.size
== 0 || proxyCertInfo
.data
== NULL
)
1744 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1747 result
= _gnutls_x509_ext_extract_proxyCertInfo (pathlen
,
1752 proxyCertInfo
.size
);
1753 _gnutls_free_datum (&proxyCertInfo
);
1764 * gnutls_x509_crt_get_extension_by_oid:
1765 * @cert: should contain a #gnutls_x509_crt_t structure
1766 * @oid: holds an Object Identified in null terminated string
1767 * @indx: In case multiple same OIDs exist in the extensions, this specifies which to send. Use (0) to get the first one.
1768 * @buf: a pointer to a structure to hold the name (may be null)
1769 * @buf_size: initially holds the size of @buf
1770 * @critical: will be non (0) if the extension is marked as critical
1772 * This function will return the extension specified by the OID in the
1773 * certificate. The extensions will be returned as binary data DER
1774 * encoded, in the provided buffer.
1776 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1777 * otherwise a negative error code is returned. If the certificate does not
1778 * contain the specified extension
1779 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1782 gnutls_x509_crt_get_extension_by_oid (gnutls_x509_crt_t cert
,
1783 const char *oid
, int indx
,
1784 void *buf
, size_t * buf_size
,
1785 unsigned int *critical
)
1788 gnutls_datum_t output
;
1793 return GNUTLS_E_INVALID_REQUEST
;
1797 _gnutls_x509_crt_get_extension (cert
, oid
, indx
, &output
,
1804 if (output
.size
== 0 || output
.data
== NULL
)
1807 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1810 if (output
.size
> (unsigned int) *buf_size
)
1812 *buf_size
= output
.size
;
1813 _gnutls_free_datum (&output
);
1814 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
1817 *buf_size
= output
.size
;
1820 memcpy (buf
, output
.data
, output
.size
);
1822 _gnutls_free_datum (&output
);
1829 * gnutls_x509_crt_get_extension_oid:
1830 * @cert: should contain a #gnutls_x509_crt_t structure
1831 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
1832 * @oid: a pointer to a structure to hold the OID (may be null)
1833 * @oid_size: initially holds the size of @oid
1835 * This function will return the requested extension OID in the certificate.
1836 * The extension OID will be stored as a string in the provided buffer.
1838 * The @oid returned will be null terminated, although @oid_size will not
1839 * account for the trailing null.
1841 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1842 * otherwise a negative error code is returned. If you have reached the
1843 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1847 gnutls_x509_crt_get_extension_oid (gnutls_x509_crt_t cert
, int indx
,
1848 void *oid
, size_t * oid_size
)
1855 return GNUTLS_E_INVALID_REQUEST
;
1858 result
= _gnutls_x509_crt_get_extension_oid (cert
, indx
, oid
, oid_size
);
1869 * gnutls_x509_crt_get_extension_info:
1870 * @cert: should contain a #gnutls_x509_crt_t structure
1871 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
1872 * @oid: a pointer to a structure to hold the OID
1873 * @oid_size: initially holds the maximum size of @oid, on return
1874 * holds actual size of @oid.
1875 * @critical: output variable with critical flag, may be NULL.
1877 * This function will return the requested extension OID in the
1878 * certificate, and the critical flag for it. The extension OID will
1879 * be stored as a string in the provided buffer. Use
1880 * gnutls_x509_crt_get_extension_data() to extract the data.
1882 * If the buffer provided is not long enough to hold the output, then
1883 * @oid_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
1884 * returned. The @oid returned will be null terminated, although
1885 * @oid_size will not account for the trailing null.
1887 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1888 * otherwise a negative error code is returned. If you have reached the
1889 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1893 gnutls_x509_crt_get_extension_info (gnutls_x509_crt_t cert
, int indx
,
1894 void *oid
, size_t * oid_size
,
1895 unsigned int *critical
)
1898 char str_critical
[10];
1899 char name
[ASN1_MAX_NAME_SIZE
];
1905 return GNUTLS_E_INVALID_REQUEST
;
1908 snprintf (name
, sizeof (name
), "tbsCertificate.extensions.?%u.extnID",
1912 result
= asn1_read_value (cert
->cert
, name
, oid
, &len
);
1915 if (result
== ASN1_ELEMENT_NOT_FOUND
)
1916 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1917 else if (result
!= ASN1_SUCCESS
)
1920 return _gnutls_asn2err (result
);
1923 snprintf (name
, sizeof (name
), "tbsCertificate.extensions.?%u.critical",
1925 len
= sizeof (str_critical
);
1926 result
= asn1_read_value (cert
->cert
, name
, str_critical
, &len
);
1927 if (result
!= ASN1_SUCCESS
)
1930 return _gnutls_asn2err (result
);
1935 if (str_critical
[0] == 'T')
1946 * gnutls_x509_crt_get_extension_data:
1947 * @cert: should contain a #gnutls_x509_crt_t structure
1948 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
1949 * @data: a pointer to a structure to hold the data (may be null)
1950 * @sizeof_data: initially holds the size of @oid
1952 * This function will return the requested extension data in the
1953 * certificate. The extension data will be stored as a string in the
1956 * Use gnutls_x509_crt_get_extension_info() to extract the OID and
1957 * critical flag. Use gnutls_x509_crt_get_extension_by_oid() instead,
1958 * if you want to get data indexed by the extension OID rather than
1961 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1962 * otherwise a negative error code is returned. If you have reached the
1963 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1967 gnutls_x509_crt_get_extension_data (gnutls_x509_crt_t cert
, int indx
,
1968 void *data
, size_t * sizeof_data
)
1971 char name
[ASN1_MAX_NAME_SIZE
];
1976 return GNUTLS_E_INVALID_REQUEST
;
1979 snprintf (name
, sizeof (name
), "tbsCertificate.extensions.?%u.extnValue",
1983 result
= asn1_read_value (cert
->cert
, name
, data
, &len
);
1986 if (result
== ASN1_ELEMENT_NOT_FOUND
)
1987 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1988 else if (result
< 0)
1991 return _gnutls_asn2err (result
);
1998 _gnutls_x509_crt_get_raw_dn2 (gnutls_x509_crt_t cert
,
1999 const char *whom
, gnutls_datum_t
* start
)
2001 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
2004 gnutls_datum_t signed_data
= { NULL
, 0 };
2006 /* get the issuer of 'cert'
2009 asn1_create_element (_gnutls_get_pkix (), "PKIX1.TBSCertificate",
2010 &c2
)) != ASN1_SUCCESS
)
2013 return _gnutls_asn2err (result
);
2017 _gnutls_x509_get_signed_data (cert
->cert
, "tbsCertificate", &signed_data
);
2024 result
= asn1_der_decoding (&c2
, signed_data
.data
, signed_data
.size
, NULL
);
2025 if (result
!= ASN1_SUCCESS
)
2028 asn1_delete_structure (&c2
);
2029 result
= _gnutls_asn2err (result
);
2034 asn1_der_decoding_startEnd (c2
, signed_data
.data
, signed_data
.size
,
2035 whom
, &start1
, &end1
);
2037 if (result
!= ASN1_SUCCESS
)
2040 result
= _gnutls_asn2err (result
);
2044 len1
= end1
- start1
+ 1;
2046 _gnutls_set_datum (start
, &signed_data
.data
[start1
], len1
);
2051 asn1_delete_structure (&c2
);
2052 _gnutls_free_datum (&signed_data
);
2057 * gnutls_x509_crt_get_raw_issuer_dn:
2058 * @cert: should contain a #gnutls_x509_crt_t structure
2059 * @start: will hold the starting point of the DN
2061 * This function will return a pointer to the DER encoded DN structure
2062 * and the length. This points to allocated data that must be free'd using gnutls_free().
2064 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2065 * negative error value.or a negative error code on error.
2069 gnutls_x509_crt_get_raw_issuer_dn (gnutls_x509_crt_t cert
,
2070 gnutls_datum_t
* start
)
2072 return _gnutls_x509_crt_get_raw_dn2 (cert
, "issuer", start
);
2076 * gnutls_x509_crt_get_raw_dn:
2077 * @cert: should contain a #gnutls_x509_crt_t structure
2078 * @start: will hold the starting point of the DN
2080 * This function will return a pointer to the DER encoded DN structure and
2081 * the length. This points to allocated data that must be free'd using gnutls_free().
2083 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2084 * negative error value. or a negative error code on error.
2088 gnutls_x509_crt_get_raw_dn (gnutls_x509_crt_t cert
, gnutls_datum_t
* start
)
2090 return _gnutls_x509_crt_get_raw_dn2 (cert
, "subject", start
);
2094 get_dn (gnutls_x509_crt_t cert
, const char *whom
, gnutls_x509_dn_t
* dn
)
2096 *dn
= asn1_find_node (cert
->cert
, whom
);
2098 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND
;
2103 * gnutls_x509_crt_get_subject:
2104 * @cert: should contain a #gnutls_x509_crt_t structure
2105 * @dn: output variable with pointer to uint8_t DN.
2107 * Return the Certificate's Subject DN as an uint8_t data type. You
2108 * may use gnutls_x509_dn_get_rdn_ava() to decode the DN.
2110 * Note that @dn should be treated as constant. Because points
2111 * into the @cert object, you may not deallocate @cert
2112 * and continue to access @dn.
2114 * Returns: Returns 0 on success, or an error code.
2117 gnutls_x509_crt_get_subject (gnutls_x509_crt_t cert
, gnutls_x509_dn_t
* dn
)
2119 return get_dn (cert
, "tbsCertificate.subject.rdnSequence", dn
);
2123 * gnutls_x509_crt_get_issuer:
2124 * @cert: should contain a #gnutls_x509_crt_t structure
2125 * @dn: output variable with pointer to uint8_t DN
2127 * Return the Certificate's Issuer DN as an uint8_t data type. You may
2128 * use gnutls_x509_dn_get_rdn_ava() to decode the DN.
2130 * Note that @dn should be treated as constant. Because points
2131 * into the @cert object, you may not deallocate @cert
2132 * and continue to access @dn.
2134 * Returns: Returns 0 on success, or an error code.
2137 gnutls_x509_crt_get_issuer (gnutls_x509_crt_t cert
, gnutls_x509_dn_t
* dn
)
2139 return get_dn (cert
, "tbsCertificate.issuer.rdnSequence", dn
);
2143 * gnutls_x509_dn_get_rdn_ava:
2144 * @dn: input variable with uint8_t DN pointer
2145 * @irdn: index of RDN
2146 * @iava: index of AVA.
2147 * @ava: Pointer to structure which will hold output information.
2149 * Get pointers to data within the DN.
2151 * Note that @ava will contain pointers into the @dn structure, so you
2152 * should not modify any data or deallocate it. Note also that the DN
2153 * in turn points into the original certificate structure, and thus
2154 * you may not deallocate the certificate and continue to access @dn.
2156 * Returns: Returns 0 on success, or an error code.
2159 gnutls_x509_dn_get_rdn_ava (gnutls_x509_dn_t dn
,
2160 int irdn
, int iava
, gnutls_x509_ava_st
* ava
)
2162 ASN1_TYPE rdn
, elem
;
2163 ASN1_DATA_NODE vnode
;
2165 int lenlen
, remlen
, ret
;
2166 char rbuf
[ASN1_MAX_NAME_SIZE
];
2168 const unsigned char *ptr
;
2171 irdn
++; /* 0->1, 1->2 etc */
2173 snprintf (rbuf
, sizeof (rbuf
), "rdnSequence.?%d.?%d", irdn
, iava
);
2174 rdn
= asn1_find_node (dn
, rbuf
);
2178 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND
;
2181 snprintf (rbuf
, sizeof (rbuf
), "?%d.type", iava
);
2182 elem
= asn1_find_node (rdn
, rbuf
);
2186 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND
;
2189 ret
= asn1_read_node_value(elem
, &vnode
);
2190 if (ret
!= ASN1_SUCCESS
)
2193 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND
;
2196 ava
->oid
.data
= (void*)vnode
.value
;
2197 ava
->oid
.size
= vnode
.value_len
;
2199 snprintf (rbuf
, sizeof (rbuf
), "?%d.value", iava
);
2200 elem
= asn1_find_node (rdn
, rbuf
);
2204 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND
;
2207 ret
= asn1_read_node_value(elem
, &vnode
);
2208 if (ret
!= ASN1_SUCCESS
)
2211 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND
;
2213 /* The value still has the previous tag's length bytes, plus the
2214 * current value's tag and length bytes. Decode them.
2218 remlen
= vnode
.value_len
;
2219 len
= asn1_get_length_der (ptr
, remlen
, &lenlen
);
2223 return GNUTLS_E_ASN1_DER_ERROR
;
2228 ret
= asn1_get_tag_der (ptr
, remlen
, &cls
, &lenlen
, &ava
->value_tag
);
2232 return _gnutls_asn2err (ret
);
2241 tmp
= asn1_get_length_der (ptr
, remlen
, &lenlen
);
2245 return GNUTLS_E_ASN1_DER_ERROR
;
2247 ava
->value
.size
= tmp
;
2249 ava
->value
.data
= (void*)(ptr
+ lenlen
);
2255 * gnutls_x509_crt_get_fingerprint:
2256 * @cert: should contain a #gnutls_x509_crt_t structure
2257 * @algo: is a digest algorithm
2258 * @buf: a pointer to a structure to hold the fingerprint (may be null)
2259 * @buf_size: initially holds the size of @buf
2261 * This function will calculate and copy the certificate's fingerprint
2262 * in the provided buffer.
2264 * If the buffer is null then only the size will be filled.
2266 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
2267 * not long enough, and in that case the *buf_size will be updated
2268 * with the required size. On success 0 is returned.
2271 gnutls_x509_crt_get_fingerprint (gnutls_x509_crt_t cert
,
2272 gnutls_digest_algorithm_t algo
,
2273 void *buf
, size_t * buf_size
)
2280 if (buf_size
== 0 || cert
== NULL
)
2282 return GNUTLS_E_INVALID_REQUEST
;
2286 asn1_der_coding (cert
->cert
, "", NULL
, &cert_buf_size
, NULL
);
2288 cert_buf
= gnutls_malloc (cert_buf_size
);
2289 if (cert_buf
== NULL
)
2292 return GNUTLS_E_MEMORY_ERROR
;
2295 result
= asn1_der_coding (cert
->cert
, "", cert_buf
, &cert_buf_size
, NULL
);
2297 if (result
!= ASN1_SUCCESS
)
2300 gnutls_free (cert_buf
);
2301 return _gnutls_asn2err (result
);
2304 tmp
.data
= cert_buf
;
2305 tmp
.size
= cert_buf_size
;
2307 result
= gnutls_fingerprint (algo
, &tmp
, buf
, buf_size
);
2308 gnutls_free (cert_buf
);
2314 * gnutls_x509_crt_export:
2315 * @cert: Holds the certificate
2316 * @format: the format of output params. One of PEM or DER.
2317 * @output_data: will contain a certificate PEM or DER encoded
2318 * @output_data_size: holds the size of output_data (and will be
2319 * replaced by the actual size of parameters)
2321 * This function will export the certificate to DER or PEM format.
2323 * If the buffer provided is not long enough to hold the output, then
2324 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2327 * If the structure is PEM encoded, it will have a header
2328 * of "BEGIN CERTIFICATE".
2330 * Returns: In case of failure a negative error code will be
2331 * returned, and 0 on success.
2334 gnutls_x509_crt_export (gnutls_x509_crt_t cert
,
2335 gnutls_x509_crt_fmt_t format
, void *output_data
,
2336 size_t * output_data_size
)
2341 return GNUTLS_E_INVALID_REQUEST
;
2344 return _gnutls_x509_export_int (cert
->cert
, format
, "CERTIFICATE",
2345 output_data
, output_data_size
);
2349 _gnutls_get_key_id (gnutls_pk_algorithm_t pk
, gnutls_pk_params_st
* params
,
2350 unsigned char *output_data
,
2351 size_t * output_data_size
)
2354 gnutls_datum_t der
= { NULL
, 0 };
2355 const gnutls_digest_algorithm_t hash
= GNUTLS_DIG_SHA1
;
2356 unsigned int digest_len
= _gnutls_hash_get_algo_len(hash
);
2358 if (output_data
== NULL
|| *output_data_size
< digest_len
)
2361 *output_data_size
= digest_len
;
2362 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
2365 ret
= _gnutls_x509_encode_PKI_params(&der
, pk
, params
);
2367 return gnutls_assert_val(ret
);
2369 ret
= _gnutls_hash_fast(hash
, der
.data
, der
.size
, output_data
);
2375 *output_data_size
= digest_len
;
2381 _gnutls_free_datum (&der
);
2386 * gnutls_x509_crt_get_key_id:
2387 * @crt: Holds the certificate
2388 * @flags: should be 0 for now
2389 * @output_data: will contain the key ID
2390 * @output_data_size: holds the size of output_data (and will be
2391 * replaced by the actual size of parameters)
2393 * This function will return a unique ID the depends on the public
2394 * key parameters. This ID can be used in checking whether a
2395 * certificate corresponds to the given private key.
2397 * If the buffer provided is not long enough to hold the output, then
2398 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2399 * be returned. The output will normally be a SHA-1 hash output,
2400 * which is 20 bytes.
2402 * Returns: In case of failure a negative error code will be
2403 * returned, and 0 on success.
2406 gnutls_x509_crt_get_key_id (gnutls_x509_crt_t crt
, unsigned int flags
,
2407 unsigned char *output_data
,
2408 size_t * output_data_size
)
2411 gnutls_pk_params_st params
;
2416 return GNUTLS_E_INVALID_REQUEST
;
2419 pk
= gnutls_x509_crt_get_pk_algorithm (crt
, NULL
);
2426 ret
= _gnutls_x509_crt_get_mpis (crt
, ¶ms
);
2433 ret
= _gnutls_get_key_id(pk
, ¶ms
, output_data
, output_data_size
);
2435 gnutls_pk_params_release(¶ms
);
2441 /* This is exactly as gnutls_x509_crt_check_revocation() except that
2445 _gnutls_x509_crt_check_revocation (gnutls_x509_crt_t cert
,
2446 const gnutls_x509_crl_t
* crl_list
,
2447 int crl_list_length
,
2448 gnutls_verify_output_function func
)
2450 uint8_t serial
[128];
2451 uint8_t cert_serial
[128];
2452 size_t serial_size
, cert_serial_size
;
2453 int ncerts
, ret
, i
, j
;
2454 gnutls_datum_t dn1
, dn2
;
2459 return GNUTLS_E_INVALID_REQUEST
;
2462 for (j
= 0; j
< crl_list_length
; j
++)
2463 { /* do for all the crls */
2465 /* Step 1. check if issuer's DN match
2467 ret
= gnutls_x509_crl_get_raw_issuer_dn (crl_list
[j
], &dn1
);
2474 ret
= gnutls_x509_crt_get_raw_issuer_dn (cert
, &dn2
);
2481 ret
= _gnutls_x509_compare_raw_dn (&dn1
, &dn2
);
2482 _gnutls_free_datum (&dn1
);
2483 _gnutls_free_datum (&dn2
);
2486 /* issuers do not match so don't even
2492 /* Step 2. Read the certificate's serial number
2494 cert_serial_size
= sizeof (cert_serial
);
2495 ret
= gnutls_x509_crt_get_serial (cert
, cert_serial
, &cert_serial_size
);
2502 /* Step 3. cycle through the CRL serials and compare with
2503 * certificate serial we have.
2506 ncerts
= gnutls_x509_crl_get_crt_count (crl_list
[j
]);
2513 for (i
= 0; i
< ncerts
; i
++)
2515 serial_size
= sizeof (serial
);
2517 gnutls_x509_crl_get_crt_serial (crl_list
[j
], i
, serial
,
2518 &serial_size
, NULL
);
2526 if (serial_size
== cert_serial_size
)
2528 if (memcmp (serial
, cert_serial
, serial_size
) == 0)
2531 if (func
) func(cert
, NULL
, crl_list
[j
], GNUTLS_CERT_REVOKED
|GNUTLS_CERT_INVALID
);
2532 return 1; /* revoked! */
2536 if (func
) func(cert
, NULL
, crl_list
[j
], 0);
2539 return 0; /* not revoked. */
2544 * gnutls_x509_crt_check_revocation:
2545 * @cert: should contain a #gnutls_x509_crt_t structure
2546 * @crl_list: should contain a list of gnutls_x509_crl_t structures
2547 * @crl_list_length: the length of the crl_list
2549 * This function will return check if the given certificate is
2550 * revoked. It is assumed that the CRLs have been verified before.
2552 * Returns: 0 if the certificate is NOT revoked, and 1 if it is. A
2553 * negative error code is returned on error.
2556 gnutls_x509_crt_check_revocation (gnutls_x509_crt_t cert
,
2557 const gnutls_x509_crl_t
* crl_list
,
2558 int crl_list_length
)
2560 return _gnutls_x509_crt_check_revocation(cert
, crl_list
, crl_list_length
, NULL
);
2564 * gnutls_x509_crt_get_verify_algorithm:
2565 * @crt: Holds the certificate
2566 * @signature: contains the signature
2567 * @hash: The result of the call with the hash algorithm used for signature
2569 * This function will read the certifcate and the signed data to
2570 * determine the hash algorithm used to generate the signature.
2572 * Deprecated: Use gnutls_pubkey_get_verify_algorithm() instead.
2574 * Returns: the 0 if the hash algorithm is found. A negative error code is
2575 * returned on error.
2580 gnutls_x509_crt_get_verify_algorithm (gnutls_x509_crt_t crt
,
2581 const gnutls_datum_t
* signature
,
2582 gnutls_digest_algorithm_t
* hash
)
2584 gnutls_pk_params_st issuer_params
;
2590 return GNUTLS_E_INVALID_REQUEST
;
2593 ret
= _gnutls_x509_crt_get_mpis (crt
, &issuer_params
);
2600 ret
= _gnutls_x509_verify_algorithm (hash
,
2602 gnutls_x509_crt_get_pk_algorithm (crt
,
2606 /* release allocated mpis */
2607 gnutls_pk_params_release(&issuer_params
);
2615 * gnutls_x509_crt_get_preferred_hash_algorithm:
2616 * @crt: Holds the certificate
2617 * @hash: The result of the call with the hash algorithm used for signature
2618 * @mand: If non (0) it means that the algorithm MUST use this hash. May be NULL.
2620 * This function will read the certifcate and return the appropriate digest
2621 * algorithm to use for signing with this certificate. Some certificates (i.e.
2622 * DSA might not be able to sign without the preferred algorithm).
2624 * Deprecated: Please use gnutls_pubkey_get_preferred_hash_algorithm().
2626 * Returns: the 0 if the hash algorithm is found. A negative error code is
2627 * returned on error.
2632 gnutls_x509_crt_get_preferred_hash_algorithm (gnutls_x509_crt_t crt
,
2633 gnutls_digest_algorithm_t
*
2634 hash
, unsigned int *mand
)
2636 gnutls_pk_params_st issuer_params
;
2642 return GNUTLS_E_INVALID_REQUEST
;
2645 ret
= _gnutls_x509_crt_get_mpis (crt
, &issuer_params
);
2653 _gnutls_pk_get_hash_algorithm (gnutls_x509_crt_get_pk_algorithm
2654 (crt
, NULL
), &issuer_params
,
2657 /* release allocated mpis */
2658 gnutls_pk_params_release(&issuer_params
);
2664 * gnutls_x509_crt_verify_data:
2665 * @crt: Holds the certificate
2666 * @flags: should be 0 for now
2667 * @data: holds the data to be signed
2668 * @signature: contains the signature
2670 * This function will verify the given signed data, using the
2671 * parameters from the certificate.
2673 * Deprecated. Please use gnutls_pubkey_verify_data().
2675 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
2676 * is returned, and zero or positive code on success.
2679 gnutls_x509_crt_verify_data (gnutls_x509_crt_t crt
, unsigned int flags
,
2680 const gnutls_datum_t
* data
,
2681 const gnutls_datum_t
* signature
)
2688 return GNUTLS_E_INVALID_REQUEST
;
2691 result
= _gnutls_x509_verify_data (GNUTLS_DIG_UNKNOWN
, data
, signature
, crt
);
2702 * gnutls_x509_crt_verify_hash:
2703 * @crt: Holds the certificate
2704 * @flags: should be 0 for now
2705 * @hash: holds the hash digest to be verified
2706 * @signature: contains the signature
2708 * This function will verify the given signed digest, using the
2709 * parameters from the certificate.
2711 * Deprecated. Please use gnutls_pubkey_verify_data2() or gnutls_pubkey_verify_hash2().
2713 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
2714 * is returned, and zero or positive code on success.
2717 gnutls_x509_crt_verify_hash (gnutls_x509_crt_t crt
, unsigned int flags
,
2718 const gnutls_datum_t
* hash
,
2719 const gnutls_datum_t
* signature
)
2721 gnutls_pk_params_st params
;
2722 gnutls_digest_algorithm_t algo
;
2728 return GNUTLS_E_INVALID_REQUEST
;
2731 ret
= gnutls_x509_crt_get_verify_algorithm (crt
, signature
, &algo
);
2733 return gnutls_assert_val(ret
);
2735 /* Read the MPI parameters from the issuer's certificate.
2738 _gnutls_x509_crt_get_mpis (crt
, ¶ms
);
2746 pubkey_verify_hashed_data (gnutls_x509_crt_get_pk_algorithm (crt
, NULL
), algo
,
2747 hash
, signature
, ¶ms
);
2753 /* release all allocated MPIs
2755 gnutls_pk_params_release(¶ms
);
2761 * gnutls_x509_crt_get_crl_dist_points:
2762 * @cert: should contain a #gnutls_x509_crt_t structure
2763 * @seq: specifies the sequence number of the distribution point (0 for the first one, 1 for the second etc.)
2764 * @ret: is the place where the distribution point will be copied to
2765 * @ret_size: holds the size of ret.
2766 * @reason_flags: Revocation reasons flags.
2767 * @critical: will be non (0) if the extension is marked as critical (may be null)
2769 * This function retrieves the CRL distribution points (2.5.29.31),
2770 * contained in the given certificate in the X509v3 Certificate
2773 * @reason_flags should be an ORed sequence of
2774 * %GNUTLS_CRL_REASON_UNUSED, %GNUTLS_CRL_REASON_KEY_COMPROMISE,
2775 * %GNUTLS_CRL_REASON_CA_COMPROMISE,
2776 * %GNUTLS_CRL_REASON_AFFILIATION_CHANGED,
2777 * %GNUTLS_CRL_REASON_SUPERSEEDED,
2778 * %GNUTLS_CRL_REASON_CESSATION_OF_OPERATION,
2779 * %GNUTLS_CRL_REASON_CERTIFICATE_HOLD,
2780 * %GNUTLS_CRL_REASON_PRIVILEGE_WITHDRAWN,
2781 * %GNUTLS_CRL_REASON_AA_COMPROMISE, or (0) for all possible reasons.
2783 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER and updates @ret_size if
2784 * @ret_size is not enough to hold the distribution point, or the
2785 * type of the distribution point if everything was ok. The type is
2786 * one of the enumerated %gnutls_x509_subject_alt_name_t. If the
2787 * certificate does not have an Alternative name with the specified
2788 * sequence number then %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is
2792 gnutls_x509_crt_get_crl_dist_points (gnutls_x509_crt_t cert
,
2793 unsigned int seq
, void *ret
,
2795 unsigned int *reason_flags
,
2796 unsigned int *critical
)
2799 gnutls_datum_t dist_points
= { NULL
, 0 };
2800 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
2801 char name
[ASN1_MAX_NAME_SIZE
];
2803 gnutls_x509_subject_alt_name_t type
;
2809 return GNUTLS_E_INVALID_REQUEST
;
2812 if (*ret_size
> 0 && ret
)
2813 memset (ret
, 0, *ret_size
);
2821 _gnutls_x509_crt_get_extension (cert
, "2.5.29.31", 0, &dist_points
,
2828 if (dist_points
.size
== 0 || dist_points
.data
== NULL
)
2831 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
2834 result
= asn1_create_element
2835 (_gnutls_get_pkix (), "PKIX1.CRLDistributionPoints", &c2
);
2836 if (result
!= ASN1_SUCCESS
)
2839 _gnutls_free_datum (&dist_points
);
2840 return _gnutls_asn2err (result
);
2843 result
= asn1_der_decoding (&c2
, dist_points
.data
, dist_points
.size
, NULL
);
2844 _gnutls_free_datum (&dist_points
);
2846 if (result
!= ASN1_SUCCESS
)
2849 asn1_delete_structure (&c2
);
2850 return _gnutls_asn2err (result
);
2853 /* Return the different names from the first CRLDistr. point.
2854 * The whole thing is a mess.
2856 _gnutls_str_cpy (name
, sizeof (name
), "?1.distributionPoint.fullName");
2858 result
= _gnutls_parse_general_name (c2
, name
, seq
, ret
, ret_size
, NULL
, 0);
2861 asn1_delete_structure (&c2
);
2868 /* Read the CRL reasons.
2872 _gnutls_str_cpy (name
, sizeof (name
), "?1.reasons");
2874 reasons
[0] = reasons
[1] = 0;
2876 len
= sizeof (reasons
);
2877 result
= asn1_read_value (c2
, name
, reasons
, &len
);
2879 if (result
!= ASN1_VALUE_NOT_FOUND
&& result
!= ASN1_SUCCESS
)
2882 asn1_delete_structure (&c2
);
2883 return _gnutls_asn2err (result
);
2886 *reason_flags
= reasons
[0] | (reasons
[1] << 8);
2889 asn1_delete_structure (&c2
);
2895 * gnutls_x509_crt_get_key_purpose_oid:
2896 * @cert: should contain a #gnutls_x509_crt_t structure
2897 * @indx: This specifies which OID to return. Use (0) to get the first one.
2898 * @oid: a pointer to a buffer to hold the OID (may be null)
2899 * @oid_size: initially holds the size of @oid
2900 * @critical: output flag to indicate criticality of extension
2902 * This function will extract the key purpose OIDs of the Certificate
2903 * specified by the given index. These are stored in the Extended Key
2904 * Usage extension (2.5.29.37) See the GNUTLS_KP_* definitions for
2905 * human readable names.
2907 * If @oid is null then only the size will be filled. The @oid
2908 * returned will be null terminated, although @oid_size will not
2909 * account for the trailing null.
2911 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
2912 * not long enough, and in that case the *oid_size will be updated
2913 * with the required size. On success 0 is returned.
2916 gnutls_x509_crt_get_key_purpose_oid (gnutls_x509_crt_t cert
,
2917 int indx
, void *oid
, size_t * oid_size
,
2918 unsigned int *critical
)
2920 char tmpstr
[ASN1_MAX_NAME_SIZE
];
2923 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
2928 return GNUTLS_E_INVALID_REQUEST
;
2932 memset (oid
, 0, *oid_size
);
2937 _gnutls_x509_crt_get_extension (cert
, "2.5.29.37", 0, &id
,
2943 if (id
.size
== 0 || id
.data
== NULL
)
2946 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
2949 result
= asn1_create_element
2950 (_gnutls_get_pkix (), "PKIX1.ExtKeyUsageSyntax", &c2
);
2951 if (result
!= ASN1_SUCCESS
)
2954 _gnutls_free_datum (&id
);
2955 return _gnutls_asn2err (result
);
2958 result
= asn1_der_decoding (&c2
, id
.data
, id
.size
, NULL
);
2959 _gnutls_free_datum (&id
);
2961 if (result
!= ASN1_SUCCESS
)
2964 asn1_delete_structure (&c2
);
2965 return _gnutls_asn2err (result
);
2969 /* create a string like "?1"
2971 snprintf (tmpstr
, sizeof (tmpstr
), "?%u", indx
);
2974 result
= asn1_read_value (c2
, tmpstr
, oid
, &len
);
2977 asn1_delete_structure (&c2
);
2979 if (result
== ASN1_VALUE_NOT_FOUND
|| result
== ASN1_ELEMENT_NOT_FOUND
)
2981 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
2984 if (result
!= ASN1_SUCCESS
)
2987 return _gnutls_asn2err (result
);
2995 * gnutls_x509_crt_get_pk_rsa_raw:
2996 * @crt: Holds the certificate
2997 * @m: will hold the modulus
2998 * @e: will hold the public exponent
3000 * This function will export the RSA public key's parameters found in
3001 * the given structure. The new parameters will be allocated using
3002 * gnutls_malloc() and will be stored in the appropriate datum.
3004 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3007 gnutls_x509_crt_get_pk_rsa_raw (gnutls_x509_crt_t crt
,
3008 gnutls_datum_t
* m
, gnutls_datum_t
* e
)
3011 gnutls_pk_params_st params
;
3016 return GNUTLS_E_INVALID_REQUEST
;
3019 ret
= gnutls_x509_crt_get_pk_algorithm (crt
, NULL
);
3020 if (ret
!= GNUTLS_PK_RSA
)
3023 return GNUTLS_E_INVALID_REQUEST
;
3026 ret
= _gnutls_x509_crt_get_mpis (crt
, ¶ms
);
3033 ret
= _gnutls_mpi_dprint_lz (params
.params
[0], m
);
3040 ret
= _gnutls_mpi_dprint_lz (params
.params
[1], e
);
3044 _gnutls_free_datum (m
);
3051 gnutls_pk_params_release(¶ms
);
3056 * gnutls_x509_crt_get_pk_dsa_raw:
3057 * @crt: Holds the certificate
3058 * @p: will hold the p
3059 * @q: will hold the q
3060 * @g: will hold the g
3061 * @y: will hold the y
3063 * This function will export the DSA public key's parameters found in
3064 * the given certificate. The new parameters will be allocated using
3065 * gnutls_malloc() and will be stored in the appropriate datum.
3067 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3070 gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt
,
3071 gnutls_datum_t
* p
, gnutls_datum_t
* q
,
3072 gnutls_datum_t
* g
, gnutls_datum_t
* y
)
3075 gnutls_pk_params_st params
;
3080 return GNUTLS_E_INVALID_REQUEST
;
3083 ret
= gnutls_x509_crt_get_pk_algorithm (crt
, NULL
);
3084 if (ret
!= GNUTLS_PK_DSA
)
3087 return GNUTLS_E_INVALID_REQUEST
;
3090 ret
= _gnutls_x509_crt_get_mpis (crt
, ¶ms
);
3099 ret
= _gnutls_mpi_dprint_lz (params
.params
[0], p
);
3107 ret
= _gnutls_mpi_dprint_lz (params
.params
[1], q
);
3111 _gnutls_free_datum (p
);
3117 ret
= _gnutls_mpi_dprint_lz (params
.params
[2], g
);
3121 _gnutls_free_datum (p
);
3122 _gnutls_free_datum (q
);
3128 ret
= _gnutls_mpi_dprint_lz (params
.params
[3], y
);
3132 _gnutls_free_datum (p
);
3133 _gnutls_free_datum (g
);
3134 _gnutls_free_datum (q
);
3141 gnutls_pk_params_release(¶ms
);
3147 * gnutls_x509_crt_list_import2:
3148 * @certs: The structures to store the parsed certificate. Must not be initialized.
3149 * @size: It will contain the size of the list.
3150 * @data: The PEM encoded certificate.
3151 * @format: One of DER or PEM.
3152 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
3154 * This function will convert the given PEM encoded certificate list
3155 * to the native gnutls_x509_crt_t format. The output will be stored
3156 * in @certs. They will be automatically initialized.
3158 * If the Certificate is PEM encoded it should have a header of "X509
3159 * CERTIFICATE", or "CERTIFICATE".
3161 * Returns: the number of certificates read or a negative error value.
3166 gnutls_x509_crt_list_import2 (gnutls_x509_crt_t
** certs
,
3167 unsigned int * size
,
3168 const gnutls_datum_t
* data
,
3169 gnutls_x509_crt_fmt_t format
, unsigned int flags
)
3171 unsigned int init
= 1024;
3174 *certs
= gnutls_malloc(sizeof(gnutls_x509_crt_t
)*init
);
3178 return GNUTLS_E_MEMORY_ERROR
;
3181 ret
= gnutls_x509_crt_list_import(*certs
, &init
, data
, format
, GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED
);
3182 if (ret
== GNUTLS_E_SHORT_MEMORY_BUFFER
)
3184 *certs
= gnutls_realloc_fast(*certs
, sizeof(gnutls_x509_crt_t
)*init
);
3188 return GNUTLS_E_MEMORY_ERROR
;
3191 ret
= gnutls_x509_crt_list_import(*certs
, &init
, data
, format
, flags
);
3196 gnutls_free(*certs
);
3205 static int check_if_sorted(gnutls_x509_crt_t
* crt
, int nr
)
3207 char prev_dn
[MAX_DN
];
3209 size_t prev_dn_size
, dn_size
;
3212 /* check if the X.509 list is ordered */
3220 dn_size
= sizeof(dn
);
3221 ret
= gnutls_x509_crt_get_dn(crt
[i
], dn
, &dn_size
);
3224 ret
= gnutls_assert_val(ret
);
3228 if (dn_size
!= prev_dn_size
|| memcmp(dn
, prev_dn
, dn_size
) != 0)
3230 ret
= gnutls_assert_val(GNUTLS_E_CERTIFICATE_LIST_UNSORTED
);
3235 prev_dn_size
= sizeof(prev_dn
);
3236 ret
= gnutls_x509_crt_get_issuer_dn(crt
[i
], prev_dn
, &prev_dn_size
);
3239 ret
= gnutls_assert_val(ret
);
3253 * gnutls_x509_crt_list_import:
3254 * @certs: The structures to store the parsed certificate. Must not be initialized.
3255 * @cert_max: Initially must hold the maximum number of certs. It will be updated with the number of certs available.
3256 * @data: The PEM encoded certificate.
3257 * @format: One of DER or PEM.
3258 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
3260 * This function will convert the given PEM encoded certificate list
3261 * to the native gnutls_x509_crt_t format. The output will be stored
3262 * in @certs. They will be automatically initialized.
3264 * The flag %GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED will cause
3265 * import to fail if the certificates in the provided buffer are more
3266 * than the available structures. The %GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED
3267 * flag will cause the function to fail if the provided list is not
3268 * sorted from subject to issuer.
3270 * If the Certificate is PEM encoded it should have a header of "X509
3271 * CERTIFICATE", or "CERTIFICATE".
3273 * Returns: the number of certificates read or a negative error value.
3276 gnutls_x509_crt_list_import (gnutls_x509_crt_t
* certs
,
3277 unsigned int *cert_max
,
3278 const gnutls_datum_t
* data
,
3279 gnutls_x509_crt_fmt_t format
, unsigned int flags
)
3284 int ret
, nocopy
= 0;
3285 unsigned int count
= 0, j
;
3287 if (format
== GNUTLS_X509_FMT_DER
)
3292 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
3295 count
= 1; /* import only the first one */
3297 ret
= gnutls_x509_crt_init (&certs
[0]);
3304 ret
= gnutls_x509_crt_import (certs
[0], data
, format
);
3315 /* move to the certificate
3317 ptr
= memmem (data
->data
, data
->size
,
3318 PEM_CERT_SEP
, sizeof (PEM_CERT_SEP
) - 1);
3320 ptr
= memmem (data
->data
, data
->size
,
3321 PEM_CERT_SEP2
, sizeof (PEM_CERT_SEP2
) - 1);
3324 return gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_FOUND
);
3330 if (count
>= *cert_max
)
3332 if (!(flags
& GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED
))
3340 ret
= gnutls_x509_crt_init (&certs
[count
]);
3347 tmp
.data
= (void *) ptr
;
3348 tmp
.size
= data
->size
- (ptr
- (char *) data
->data
);
3351 gnutls_x509_crt_import (certs
[count
], &tmp
, GNUTLS_X509_FMT_PEM
);
3359 /* now we move ptr after the pem header
3362 /* find the next certificate (if any)
3364 size
= data
->size
- (ptr
- (char *) data
->data
);
3370 ptr2
= memmem (ptr
, size
, PEM_CERT_SEP
, sizeof (PEM_CERT_SEP
) - 1);
3372 ptr2
= memmem (ptr
, size
, PEM_CERT_SEP2
,
3373 sizeof (PEM_CERT_SEP2
) - 1);
3382 while (ptr
!= NULL
);
3386 if (flags
& GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED
)
3388 ret
= check_if_sorted(certs
, *cert_max
);
3399 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
3402 for (j
= 0; j
< count
; j
++)
3403 gnutls_x509_crt_deinit (certs
[j
]);
3408 * gnutls_x509_crt_get_subject_unique_id:
3409 * @crt: Holds the certificate
3410 * @buf: user allocated memory buffer, will hold the unique id
3411 * @buf_size: size of user allocated memory buffer (on input), will hold
3412 * actual size of the unique ID on return.
3414 * This function will extract the subjectUniqueID value (if present) for
3415 * the given certificate.
3417 * If the user allocated memory buffer is not large enough to hold the
3418 * full subjectUniqueID, then a GNUTLS_E_SHORT_MEMORY_BUFFER error will be
3419 * returned, and buf_size will be set to the actual length.
3421 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3424 gnutls_x509_crt_get_subject_unique_id (gnutls_x509_crt_t crt
, char *buf
,
3428 gnutls_datum_t datum
= { NULL
, 0 };
3431 _gnutls_x509_read_value (crt
->cert
, "tbsCertificate.subjectUniqueID",
3434 if (datum
.size
> *buf_size
)
3435 { /* then we're not going to fit */
3436 *buf_size
= datum
.size
;
3438 result
= GNUTLS_E_SHORT_MEMORY_BUFFER
;
3442 *buf_size
= datum
.size
;
3443 memcpy (buf
, datum
.data
, datum
.size
);
3446 _gnutls_free_datum (&datum
);
3452 * gnutls_x509_crt_get_issuer_unique_id:
3453 * @crt: Holds the certificate
3454 * @buf: user allocated memory buffer, will hold the unique id
3455 * @buf_size: size of user allocated memory buffer (on input), will hold
3456 * actual size of the unique ID on return.
3458 * This function will extract the issuerUniqueID value (if present) for
3459 * the given certificate.
3461 * If the user allocated memory buffer is not large enough to hold the
3462 * full subjectUniqueID, then a GNUTLS_E_SHORT_MEMORY_BUFFER error will be
3463 * returned, and buf_size will be set to the actual length.
3465 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3470 gnutls_x509_crt_get_issuer_unique_id (gnutls_x509_crt_t crt
, char *buf
,
3474 gnutls_datum_t datum
= { NULL
, 0 };
3477 _gnutls_x509_read_value (crt
->cert
, "tbsCertificate.issuerUniqueID",
3480 if (datum
.size
> *buf_size
)
3481 { /* then we're not going to fit */
3482 *buf_size
= datum
.size
;
3484 result
= GNUTLS_E_SHORT_MEMORY_BUFFER
;
3488 *buf_size
= datum
.size
;
3489 memcpy (buf
, datum
.data
, datum
.size
);
3492 _gnutls_free_datum (&datum
);
3498 _gnutls_parse_aia (ASN1_TYPE src
,
3501 gnutls_datum_t
* data
)
3504 char nptr
[ASN1_MAX_NAME_SIZE
];
3507 const char *oid
= NULL
;
3509 seq
++; /* 0->1, 1->2 etc */
3512 case GNUTLS_IA_ACCESSMETHOD_OID
:
3513 snprintf (nptr
, sizeof (nptr
), "?%u.accessMethod", seq
);
3516 case GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE
:
3517 snprintf (nptr
, sizeof (nptr
), "?%u.accessLocation", seq
);
3520 case GNUTLS_IA_CAISSUERS_URI
:
3521 oid
= GNUTLS_OID_AD_CAISSUERS
;
3524 case GNUTLS_IA_OCSP_URI
:
3526 oid
= GNUTLS_OID_AD_OCSP
;
3529 snprintf (nptr
, sizeof (nptr
), "?%u.accessMethod", seq
);
3530 len
= sizeof (tmpoid
);
3531 result
= asn1_read_value (src
, nptr
, tmpoid
, &len
);
3533 if (result
== ASN1_VALUE_NOT_FOUND
|| result
== ASN1_ELEMENT_NOT_FOUND
)
3534 return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
);
3536 if (result
!= ASN1_SUCCESS
)
3539 return _gnutls_asn2err (result
);
3541 if ((unsigned)len
!= strlen (oid
) + 1 || memcmp (tmpoid
, oid
, len
) != 0)
3542 return gnutls_assert_val(GNUTLS_E_UNKNOWN_ALGORITHM
);
3547 snprintf (nptr
, sizeof (nptr
),
3548 "?%u.accessLocation.uniformResourceIdentifier", seq
);
3552 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST
);
3556 result
= asn1_read_value (src
, nptr
, NULL
, &len
);
3557 if (result
== ASN1_VALUE_NOT_FOUND
|| result
== ASN1_ELEMENT_NOT_FOUND
)
3558 return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
);
3560 if (result
!= ASN1_MEM_ERROR
)
3563 return _gnutls_asn2err (result
);
3568 d
.data
= gnutls_malloc (d
.size
);
3570 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR
);
3572 result
= asn1_read_value (src
, nptr
, d
.data
, &len
);
3573 if (result
!= ASN1_SUCCESS
)
3576 gnutls_free (d
.data
);
3577 return _gnutls_asn2err (result
);
3582 data
->data
= d
.data
;
3583 data
->size
= d
.size
;
3586 gnutls_free (d
.data
);
3592 * gnutls_x509_crt_get_authority_info_access:
3593 * @crt: Holds the certificate
3594 * @seq: specifies the sequence number of the access descriptor (0 for the first one, 1 for the second etc.)
3595 * @what: what data to get, a #gnutls_info_access_what_t type.
3596 * @data: output data to be freed with gnutls_free().
3597 * @critical: pointer to output integer that is set to non-0 if the extension is marked as critical (may be %NULL)
3599 * This function extracts the Authority Information Access (AIA)
3600 * extension, see RFC 5280 section 4.2.2.1 for more information. The
3601 * AIA extension holds a sequence of AccessDescription (AD) data:
3603 * <informalexample><programlisting>
3604 * AuthorityInfoAccessSyntax ::=
3605 * SEQUENCE SIZE (1..MAX) OF AccessDescription
3607 * AccessDescription ::= SEQUENCE {
3608 * accessMethod OBJECT IDENTIFIER,
3609 * accessLocation GeneralName }
3610 * </programlisting></informalexample>
3612 * The @seq input parameter is used to indicate which member of the
3613 * sequence the caller is interested in. The first member is 0, the
3614 * second member 1 and so on. When the @seq value is out of bounds,
3615 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
3617 * The type of data returned in @data is specified via @what which
3618 * should be #gnutls_info_access_what_t values.
3620 * If @what is %GNUTLS_IA_ACCESSMETHOD_OID then @data will hold the
3621 * accessMethod OID (e.g., "1.3.6.1.5.5.7.48.1").
3623 * If @what is %GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE, @data will
3624 * hold the accessLocation GeneralName type (e.g.,
3625 * "uniformResourceIdentifier").
3627 * If @what is %GNUTLS_IA_URI, @data will hold the accessLocation URI
3628 * data. Requesting this @what value leads to an error if the
3629 * accessLocation is not of the "uniformResourceIdentifier" type.
3631 * If @what is %GNUTLS_IA_OCSP_URI, @data will hold the OCSP URI.
3632 * Requesting this @what value leads to an error if the accessMethod
3633 * is not 1.3.6.1.5.5.7.48.1 aka OSCP, or if accessLocation is not of
3634 * the "uniformResourceIdentifier" type.
3636 * If @what is %GNUTLS_IA_CAISSUERS_URI, @data will hold the caIssuers
3637 * URI. Requesting this @what value leads to an error if the
3638 * accessMethod is not 1.3.6.1.5.5.7.48.2 aka caIssuers, or if
3639 * accessLocation is not of the "uniformResourceIdentifier" type.
3641 * More @what values may be allocated in the future as needed.
3643 * If @data is NULL, the function does the same without storing the
3644 * output data, that is, it will set @critical and do error checking
3647 * The value of the critical flag is returned in *@critical. Supply a
3648 * NULL @critical if you want the function to make sure the extension
3649 * is non-critical, as required by RFC 5280.
3651 * Returns: %GNUTLS_E_SUCCESS on success, %GNUTLS_E_INVALID_REQUEST on
3652 * invalid @crt, %GNUTLS_E_CONSTRAINT_ERROR if the extension is
3653 * incorrectly marked as critical (use a non-NULL @critical to
3654 * override), %GNUTLS_E_UNKNOWN_ALGORITHM if the requested OID does
3655 * not match (e.g., when using %GNUTLS_IA_OCSP_URI), otherwise a
3656 * negative error code.
3661 gnutls_x509_crt_get_authority_info_access (gnutls_x509_crt_t crt
,
3664 gnutls_datum_t
* data
,
3665 unsigned int *critical
)
3669 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
3674 return GNUTLS_E_INVALID_REQUEST
;
3677 if ((ret
= _gnutls_x509_crt_get_extension (crt
, GNUTLS_OID_AIA
, 0, &aia
,
3681 if (aia
.size
== 0 || aia
.data
== NULL
)
3684 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
3687 if (critical
&& *critical
)
3688 return GNUTLS_E_CONSTRAINT_ERROR
;
3690 ret
= asn1_create_element (_gnutls_get_pkix (),
3691 "PKIX1.AuthorityInfoAccessSyntax", &c2
);
3692 if (ret
!= ASN1_SUCCESS
)
3695 _gnutls_free_datum (&aia
);
3696 return _gnutls_asn2err (ret
);
3699 ret
= asn1_der_decoding (&c2
, aia
.data
, aia
.size
, NULL
);
3700 /* asn1_print_structure (stdout, c2, "", ASN1_PRINT_ALL); */
3701 _gnutls_free_datum (&aia
);
3702 if (ret
!= ASN1_SUCCESS
)
3705 asn1_delete_structure (&c2
);
3706 return _gnutls_asn2err (ret
);
3709 ret
= _gnutls_parse_aia (c2
, seq
, what
, data
);
3711 asn1_delete_structure (&c2
);