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
)
181 /* Try the first header */
183 _gnutls_fbase64_decode (PEM_X509_CERT2
, data
->data
, data
->size
, &_data
);
187 /* try for the second header */
189 _gnutls_fbase64_decode (PEM_X509_CERT
, data
->data
,
204 /* Any earlier asn1_der_decoding will modify the ASN.1
205 structure, so we need to replace it with a fresh
207 asn1_delete_structure (&cert
->cert
);
209 result
= asn1_create_element (_gnutls_get_pkix (),
210 "PKIX1.Certificate", &cert
->cert
);
211 if (result
!= ASN1_SUCCESS
)
213 result
= _gnutls_asn2err (result
);
219 result
= asn1_der_decoding (&cert
->cert
, _data
.data
, _data
.size
, NULL
);
220 if (result
!= ASN1_SUCCESS
)
222 result
= _gnutls_asn2err (result
);
229 /* Since we do not want to disable any extension
231 cert
->use_extensions
= 1;
233 _gnutls_free_datum (&_data
);
239 _gnutls_free_datum (&_data
);
245 * gnutls_x509_crt_get_issuer_dn:
246 * @cert: should contain a #gnutls_x509_crt_t structure
247 * @buf: a pointer to a structure to hold the name (may be null)
248 * @buf_size: initially holds the size of @buf
250 * This function will copy the name of the Certificate issuer in the
251 * provided buffer. The name will be in the form
252 * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC4514. The output string
253 * will be ASCII or UTF-8 encoded, depending on the certificate data.
255 * If @buf is null then only the size will be filled.
257 * Returns: GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
258 * long enough, and in that case the @buf_size will be updated with
259 * the required size. On success 0 is returned.
262 gnutls_x509_crt_get_issuer_dn (gnutls_x509_crt_t cert
, char *buf
,
268 return GNUTLS_E_INVALID_REQUEST
;
271 return _gnutls_x509_parse_dn (cert
->cert
,
272 "tbsCertificate.issuer.rdnSequence", buf
,
277 * gnutls_x509_crt_get_issuer_dn_by_oid:
278 * @cert: should contain a #gnutls_x509_crt_t structure
279 * @oid: holds an Object Identified in null terminated string
280 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use (0) to get the first one.
281 * @raw_flag: If non (0) returns the raw DER data of the DN part.
282 * @buf: a pointer to a structure to hold the name (may be null)
283 * @buf_size: initially holds the size of @buf
285 * This function will extract the part of the name of the Certificate
286 * issuer specified by the given OID. The output, if the raw flag is not
287 * used, will be encoded as described in RFC4514. Thus a string that is
288 * ASCII or UTF-8 encoded, depending on the certificate data.
290 * Some helper macros with popular OIDs can be found in gnutls/x509.h
291 * If raw flag is (0), this function will only return known OIDs as
292 * text. Other OIDs will be DER encoded, as described in RFC4514 --
293 * in hex format with a '#' prefix. You can check about known OIDs
294 * using gnutls_x509_dn_oid_known().
296 * If @buf is null then only the size will be filled. If the @raw_flag
297 * is not specified the output is always null terminated, although the
298 * @buf_size will not include the null character.
300 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
301 * long enough, and in that case the @buf_size will be updated with
302 * the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there
303 * are no data in the current index. On success 0 is returned.
306 gnutls_x509_crt_get_issuer_dn_by_oid (gnutls_x509_crt_t cert
,
307 const char *oid
, int indx
,
308 unsigned int raw_flag
, void *buf
,
314 return GNUTLS_E_INVALID_REQUEST
;
317 return _gnutls_x509_parse_dn_oid (cert
->cert
,
318 "tbsCertificate.issuer.rdnSequence",
319 oid
, indx
, raw_flag
, buf
, buf_size
);
323 * gnutls_x509_crt_get_issuer_dn_oid:
324 * @cert: should contain a #gnutls_x509_crt_t structure
325 * @indx: This specifies which OID to return. Use (0) to get the first one.
326 * @oid: a pointer to a buffer to hold the OID (may be null)
327 * @oid_size: initially holds the size of @oid
329 * This function will extract the OIDs of the name of the Certificate
330 * issuer specified by the given index.
332 * If @oid is null then only the size will be filled. The @oid
333 * returned will be null terminated, although @oid_size will not
334 * account for the trailing null.
336 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
337 * long enough, and in that case the @buf_size will be updated with
338 * the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there
339 * are no data in the current index. On success 0 is returned.
342 gnutls_x509_crt_get_issuer_dn_oid (gnutls_x509_crt_t cert
,
343 int indx
, void *oid
, size_t * oid_size
)
348 return GNUTLS_E_INVALID_REQUEST
;
351 return _gnutls_x509_get_dn_oid (cert
->cert
,
352 "tbsCertificate.issuer.rdnSequence",
353 indx
, oid
, oid_size
);
357 * gnutls_x509_crt_get_dn:
358 * @cert: should contain a #gnutls_x509_crt_t structure
359 * @buf: a pointer to a structure to hold the name (may be null)
360 * @buf_size: initially holds the size of @buf
362 * This function will copy the name of the Certificate in the provided
363 * buffer. The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
364 * described in RFC4514. The output string will be ASCII or UTF-8
365 * encoded, depending on the certificate data.
367 * If @buf is null then only the size will be filled.
369 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
370 * long enough, and in that case the @buf_size will be updated
371 * with the required size. On success 0 is returned.
374 gnutls_x509_crt_get_dn (gnutls_x509_crt_t cert
, char *buf
,
380 return GNUTLS_E_INVALID_REQUEST
;
383 return _gnutls_x509_parse_dn (cert
->cert
,
384 "tbsCertificate.subject.rdnSequence", buf
,
389 * gnutls_x509_crt_get_dn_by_oid:
390 * @cert: should contain a #gnutls_x509_crt_t structure
391 * @oid: holds an Object Identified in null terminated string
392 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use (0) to get the first one.
393 * @raw_flag: If non (0) returns the raw DER data of the DN part.
394 * @buf: a pointer where the DN part will be copied (may be null).
395 * @buf_size: initially holds the size of @buf
397 * This function will extract the part of the name of the Certificate
398 * subject specified by the given OID. The output, if the raw flag is
399 * not used, will be encoded as described in RFC4514. Thus a string
400 * that is ASCII or UTF-8 encoded, depending on the certificate data.
402 * Some helper macros with popular OIDs can be found in gnutls/x509.h
403 * If raw flag is (0), this function will only return known OIDs as
404 * text. Other OIDs will be DER encoded, as described in RFC4514 --
405 * in hex format with a '#' prefix. You can check about known OIDs
406 * using gnutls_x509_dn_oid_known().
408 * If @buf is null then only the size will be filled. If the @raw_flag
409 * is not specified the output is always null terminated, although the
410 * @buf_size will not include the null character.
412 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
413 * long enough, and in that case the @buf_size will be updated with
414 * the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there
415 * are no data in the current index. On success 0 is returned.
418 gnutls_x509_crt_get_dn_by_oid (gnutls_x509_crt_t cert
, const char *oid
,
419 int indx
, unsigned int raw_flag
,
420 void *buf
, size_t * buf_size
)
425 return GNUTLS_E_INVALID_REQUEST
;
428 return _gnutls_x509_parse_dn_oid (cert
->cert
,
429 "tbsCertificate.subject.rdnSequence",
430 oid
, indx
, raw_flag
, buf
, buf_size
);
434 * gnutls_x509_crt_get_dn_oid:
435 * @cert: should contain a #gnutls_x509_crt_t structure
436 * @indx: This specifies which OID to return. Use (0) to get the first one.
437 * @oid: a pointer to a buffer to hold the OID (may be null)
438 * @oid_size: initially holds the size of @oid
440 * This function will extract the OIDs of the name of the Certificate
441 * subject specified by the given index.
443 * If @oid is null then only the size will be filled. The @oid
444 * returned will be null terminated, although @oid_size will not
445 * account for the trailing null.
447 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
448 * long enough, and in that case the @buf_size will be updated with
449 * the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there
450 * are no data in the current index. On success 0 is returned.
453 gnutls_x509_crt_get_dn_oid (gnutls_x509_crt_t cert
,
454 int indx
, void *oid
, size_t * oid_size
)
459 return GNUTLS_E_INVALID_REQUEST
;
462 return _gnutls_x509_get_dn_oid (cert
->cert
,
463 "tbsCertificate.subject.rdnSequence",
464 indx
, oid
, oid_size
);
468 * gnutls_x509_crt_get_signature_algorithm:
469 * @cert: should contain a #gnutls_x509_crt_t structure
471 * This function will return a value of the #gnutls_sign_algorithm_t
472 * enumeration that is the signature algorithm that has been used to
473 * sign this certificate.
475 * Returns: a #gnutls_sign_algorithm_t value, or a negative error code on
479 gnutls_x509_crt_get_signature_algorithm (gnutls_x509_crt_t cert
)
481 return _gnutls_x509_get_signature_algorithm(cert
->cert
, "signatureAlgorithm.algorithm");
485 * gnutls_x509_crt_get_signature:
486 * @cert: should contain a #gnutls_x509_crt_t structure
487 * @sig: a pointer where the signature part will be copied (may be null).
488 * @sizeof_sig: initially holds the size of @sig
490 * This function will extract the signature field of a certificate.
492 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
493 * negative error value. and a negative error code on error.
496 gnutls_x509_crt_get_signature (gnutls_x509_crt_t cert
,
497 char *sig
, size_t * sizeof_sig
)
506 return GNUTLS_E_INVALID_REQUEST
;
510 result
= asn1_read_value (cert
->cert
, "signature", NULL
, &len
);
511 if (result
!= ASN1_MEM_ERROR
)
514 return _gnutls_asn2err (result
);
521 return GNUTLS_E_CERTIFICATE_ERROR
;
526 if (*sizeof_sig
< (unsigned int) len
)
529 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
532 result
= asn1_read_value (cert
->cert
, "signature", sig
, &len
);
533 if (result
!= ASN1_SUCCESS
)
536 return _gnutls_asn2err (result
);
543 * gnutls_x509_crt_get_version:
544 * @cert: should contain a #gnutls_x509_crt_t structure
546 * This function will return the version of the specified Certificate.
548 * Returns: version of certificate, or a negative error code on error.
551 gnutls_x509_crt_get_version (gnutls_x509_crt_t cert
)
559 return GNUTLS_E_INVALID_REQUEST
;
562 len
= sizeof (version
);
564 asn1_read_value (cert
->cert
, "tbsCertificate.version", version
,
565 &len
)) != ASN1_SUCCESS
)
568 if (result
== ASN1_ELEMENT_NOT_FOUND
)
569 return 1; /* the DEFAULT version */
571 return _gnutls_asn2err (result
);
574 return (int) version
[0] + 1;
578 * gnutls_x509_crt_get_activation_time:
579 * @cert: should contain a #gnutls_x509_crt_t structure
581 * This function will return the time this Certificate was or will be
584 * Returns: activation time, or (time_t)-1 on error.
587 gnutls_x509_crt_get_activation_time (gnutls_x509_crt_t cert
)
595 return _gnutls_x509_get_time (cert
->cert
,
596 "tbsCertificate.validity.notBefore", 0);
600 * gnutls_x509_crt_get_expiration_time:
601 * @cert: should contain a #gnutls_x509_crt_t structure
603 * This function will return the time this Certificate was or will be
606 * Returns: expiration time, or (time_t)-1 on error.
609 gnutls_x509_crt_get_expiration_time (gnutls_x509_crt_t cert
)
617 return _gnutls_x509_get_time (cert
->cert
,
618 "tbsCertificate.validity.notAfter", 0);
622 * gnutls_x509_crt_get_private_key_usage_period:
623 * @cert: should contain a #gnutls_x509_crt_t structure
624 * @activation: The activation time
625 * @expiration: The expiration time
626 * @critical: the extension status
628 * This function will return the expiration and activation
629 * times of the private key of the certificate. It relies on
630 * the PKIX extension 2.5.29.16 being present.
632 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
633 * if the extension is not present, otherwise a negative error value.
636 gnutls_x509_crt_get_private_key_usage_period (gnutls_x509_crt_t cert
, time_t* activation
, time_t* expiration
,
637 unsigned int *critical
)
640 gnutls_datum_t der
= {NULL
, 0};
641 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
646 return GNUTLS_E_INVALID_REQUEST
;
650 _gnutls_x509_crt_get_extension (cert
, "2.5.29.16", 0, &der
,
653 return gnutls_assert_val(ret
);
655 if (der
.size
== 0 || der
.data
== NULL
)
656 return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
);
658 result
= asn1_create_element
659 (_gnutls_get_pkix (), "PKIX1.PrivateKeyUsagePeriod", &c2
);
660 if (result
!= ASN1_SUCCESS
)
663 ret
= _gnutls_asn2err (result
);
667 result
= asn1_der_decoding (&c2
, der
.data
, der
.size
, NULL
);
668 if (result
!= ASN1_SUCCESS
)
671 ret
= _gnutls_asn2err (result
);
676 *activation
= _gnutls_x509_get_time (c2
,
680 *expiration
= _gnutls_x509_get_time (c2
,
686 _gnutls_free_datum(&der
);
687 asn1_delete_structure (&c2
);
694 * gnutls_x509_crt_get_serial:
695 * @cert: should contain a #gnutls_x509_crt_t structure
696 * @result: The place where the serial number will be copied
697 * @result_size: Holds the size of the result field.
699 * This function will return the X.509 certificate's serial number.
700 * This is obtained by the X509 Certificate serialNumber field. Serial
701 * is not always a 32 or 64bit number. Some CAs use large serial
702 * numbers, thus it may be wise to handle it as something uint8_t.
704 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
705 * negative error value.
708 gnutls_x509_crt_get_serial (gnutls_x509_crt_t cert
, void *result
,
709 size_t * result_size
)
716 return GNUTLS_E_INVALID_REQUEST
;
721 asn1_read_value (cert
->cert
, "tbsCertificate.serialNumber", result
, &len
);
724 if (ret
!= ASN1_SUCCESS
)
727 return _gnutls_asn2err (ret
);
734 * gnutls_x509_crt_get_subject_key_id:
735 * @cert: should contain a #gnutls_x509_crt_t structure
736 * @ret: The place where the identifier will be copied
737 * @ret_size: Holds the size of the result field.
738 * @critical: will be non (0) if the extension is marked as critical (may be null)
740 * This function will return the X.509v3 certificate's subject key
741 * identifier. This is obtained by the X.509 Subject Key identifier
742 * extension field (2.5.29.14).
744 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
745 * if the extension is not present, otherwise a negative error value.
748 gnutls_x509_crt_get_subject_key_id (gnutls_x509_crt_t cert
, void *ret
,
749 size_t * ret_size
, unsigned int *critical
)
753 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
758 return GNUTLS_E_INVALID_REQUEST
;
763 memset (ret
, 0, *ret_size
);
768 _gnutls_x509_crt_get_extension (cert
, "2.5.29.14", 0, &id
,
774 if (id
.size
== 0 || id
.data
== NULL
)
777 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
780 result
= asn1_create_element
781 (_gnutls_get_pkix (), "PKIX1.SubjectKeyIdentifier", &c2
);
782 if (result
!= ASN1_SUCCESS
)
785 _gnutls_free_datum (&id
);
786 return _gnutls_asn2err (result
);
789 result
= asn1_der_decoding (&c2
, id
.data
, id
.size
, NULL
);
790 _gnutls_free_datum (&id
);
792 if (result
!= ASN1_SUCCESS
)
795 asn1_delete_structure (&c2
);
796 return _gnutls_asn2err (result
);
800 result
= asn1_read_value (c2
, "", ret
, &len
);
803 asn1_delete_structure (&c2
);
805 if (result
== ASN1_VALUE_NOT_FOUND
|| result
== ASN1_ELEMENT_NOT_FOUND
)
807 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
810 if (result
!= ASN1_SUCCESS
)
812 if (result
!= ASN1_MEM_ERROR
)
814 return _gnutls_asn2err (result
);
821 _get_authority_key_id (gnutls_x509_crt_t cert
, ASN1_TYPE
*c2
,
822 unsigned int *critical
)
827 *c2
= ASN1_TYPE_EMPTY
;
832 return GNUTLS_E_INVALID_REQUEST
;
836 _gnutls_x509_crt_get_extension (cert
, "2.5.29.35", 0, &id
,
839 return gnutls_assert_val(ret
);
842 if (id
.size
== 0 || id
.data
== NULL
)
845 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
848 ret
= asn1_create_element
849 (_gnutls_get_pkix (), "PKIX1.AuthorityKeyIdentifier", c2
);
850 if (ret
!= ASN1_SUCCESS
)
853 _gnutls_free_datum (&id
);
854 return _gnutls_asn2err (ret
);
857 ret
= asn1_der_decoding (c2
, id
.data
, id
.size
, NULL
);
858 _gnutls_free_datum (&id
);
860 if (ret
!= ASN1_SUCCESS
)
863 asn1_delete_structure (c2
);
864 return _gnutls_asn2err (ret
);
871 * gnutls_x509_crt_get_authority_key_gn_serial:
872 * @cert: should contain a #gnutls_x509_crt_t structure
873 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
874 * @alt: is the place where the alternative name will be copied to
875 * @alt_size: holds the size of alt.
876 * @alt_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
877 * @serial: buffer to store the serial number (may be null)
878 * @serial_size: Holds the size of the serial field (may be null)
879 * @critical: will be non (0) if the extension is marked as critical (may be null)
881 * This function will return the X.509 authority key
882 * identifier when stored as a general name (authorityCertIssuer)
885 * Because more than one general names might be stored
886 * @seq can be used as a counter to request them all until
887 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
889 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
890 * if the extension is not present, otherwise a negative error value.
895 gnutls_x509_crt_get_authority_key_gn_serial (gnutls_x509_crt_t cert
, unsigned int seq
, void *alt
,
896 size_t * alt_size
, unsigned int *alt_type
,
897 void* serial
, size_t *serial_size
,
898 unsigned int *critical
)
900 int ret
, result
, len
;
903 ret
= _get_authority_key_id(cert
, &c2
, critical
);
905 return gnutls_assert_val(ret
);
908 _gnutls_parse_general_name (c2
, "authorityCertIssuer", seq
, alt
, alt_size
, alt_type
,
912 ret
= gnutls_assert_val(ret
);
919 result
= asn1_read_value (c2
, "authorityCertSerialNumber", serial
, &len
);
925 ret
= _gnutls_asn2err(result
);
934 asn1_delete_structure (&c2
);
940 * gnutls_x509_crt_get_authority_key_id:
941 * @cert: should contain a #gnutls_x509_crt_t structure
942 * @id: The place where the identifier will be copied
943 * @id_size: Holds the size of the id field.
944 * @critical: will be non (0) if the extension is marked as critical (may be null)
946 * This function will return the X.509v3 certificate authority's key
947 * identifier. This is obtained by the X.509 Authority Key
948 * identifier extension field (2.5.29.35). Note that this function
949 * only returns the keyIdentifier field of the extension and
950 * %GNUTLS_E_X509_UNSUPPORTED_EXTENSION, if the extension contains
951 * the name and serial number of the certificate. In that case
952 * gnutls_x509_crt_get_authority_key_gn_serial() may be used.
954 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
955 * if the extension is not present, otherwise a negative error value.
958 gnutls_x509_crt_get_authority_key_id (gnutls_x509_crt_t cert
, void *id
,
960 unsigned int *critical
)
962 int ret
, result
, len
;
965 ret
= _get_authority_key_id(cert
, &c2
, critical
);
967 return gnutls_assert_val(ret
);
970 result
= asn1_read_value (c2
, "keyIdentifier", id
, &len
);
973 asn1_delete_structure (&c2
);
975 if (result
== ASN1_VALUE_NOT_FOUND
|| result
== ASN1_ELEMENT_NOT_FOUND
)
976 return gnutls_assert_val(GNUTLS_E_X509_UNSUPPORTED_EXTENSION
);
978 if (result
!= ASN1_SUCCESS
)
980 if (result
!= ASN1_MEM_ERROR
)
982 return _gnutls_asn2err (result
);
989 * gnutls_x509_crt_get_pk_algorithm:
990 * @cert: should contain a #gnutls_x509_crt_t structure
991 * @bits: if bits is non null it will hold the size of the parameters' in bits
993 * This function will return the public key algorithm of an X.509
996 * If bits is non null, it should have enough size to hold the parameters
997 * size in bits. For RSA the bits returned is the modulus.
998 * For DSA the bits returned are of the public
1001 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
1002 * success, or a negative error code on error.
1005 gnutls_x509_crt_get_pk_algorithm (gnutls_x509_crt_t cert
, unsigned int *bits
)
1012 return GNUTLS_E_INVALID_REQUEST
;
1019 _gnutls_x509_get_pk_algorithm (cert
->cert
,
1020 "tbsCertificate.subjectPublicKeyInfo",
1034 is_type_printable (int type
)
1036 if (type
== GNUTLS_SAN_DNSNAME
|| type
== GNUTLS_SAN_RFC822NAME
||
1037 type
== GNUTLS_SAN_URI
)
1043 #define XMPP_OID "1.3.6.1.5.5.7.8.5"
1045 /* returns the type and the name on success.
1046 * Type is also returned as a parameter in case of an error.
1049 _gnutls_parse_general_name (ASN1_TYPE src
, const char *src_name
,
1050 int seq
, void *name
, size_t * name_size
,
1051 unsigned int *ret_type
, int othername_oid
)
1054 char nptr
[ASN1_MAX_NAME_SIZE
];
1056 char choice_type
[128];
1057 gnutls_x509_subject_alt_name_t type
;
1059 seq
++; /* 0->1, 1->2 etc */
1061 if (src_name
[0] != 0)
1062 snprintf (nptr
, sizeof (nptr
), "%s.?%u", src_name
, seq
);
1064 snprintf (nptr
, sizeof (nptr
), "?%u", seq
);
1066 len
= sizeof (choice_type
);
1067 result
= asn1_read_value (src
, nptr
, choice_type
, &len
);
1069 if (result
== ASN1_VALUE_NOT_FOUND
|| result
== ASN1_ELEMENT_NOT_FOUND
)
1071 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1074 if (result
!= ASN1_SUCCESS
)
1077 return _gnutls_asn2err (result
);
1081 type
= _gnutls_x509_san_find_type (choice_type
);
1082 if (type
== (gnutls_x509_subject_alt_name_t
) - 1)
1085 return GNUTLS_E_X509_UNKNOWN_SAN
;
1091 if (type
== GNUTLS_SAN_OTHERNAME
)
1094 _gnutls_str_cat (nptr
, sizeof (nptr
), ".otherName.type-id");
1096 _gnutls_str_cat (nptr
, sizeof (nptr
), ".otherName.value");
1099 result
= asn1_read_value (src
, nptr
, name
, &len
);
1102 if (result
== ASN1_MEM_ERROR
)
1103 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
1105 if (result
!= ASN1_SUCCESS
)
1108 return _gnutls_asn2err (result
);
1113 if ((unsigned)len
> strlen (XMPP_OID
) && strcmp (name
, XMPP_OID
) == 0)
1114 type
= GNUTLS_SAN_OTHERNAME_XMPP
;
1120 if (src_name
[0] != 0)
1121 snprintf (nptr
, sizeof (nptr
), "%s.?%u.otherName.type-id",
1124 snprintf (nptr
, sizeof (nptr
), "?%u.otherName.type-id", seq
);
1127 result
= asn1_read_value (src
, nptr
, oid
, &len
);
1128 if (result
!= ASN1_SUCCESS
)
1131 return _gnutls_asn2err (result
);
1134 if ((unsigned)len
> strlen (XMPP_OID
) && strcmp (oid
, XMPP_OID
) == 0)
1136 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
1137 size_t orig_name_size
= *name_size
;
1139 result
= asn1_create_element
1140 (_gnutls_get_pkix (), "PKIX1.UTF8String", &c2
);
1141 if (result
!= ASN1_SUCCESS
)
1144 return _gnutls_asn2err (result
);
1147 result
= asn1_der_decoding (&c2
, name
, *name_size
, NULL
);
1148 if (result
!= ASN1_SUCCESS
)
1151 asn1_delete_structure (&c2
);
1152 return _gnutls_asn2err (result
);
1156 result
= asn1_read_value (c2
, "", name
, &len
);
1157 if (result
!= ASN1_SUCCESS
)
1160 asn1_delete_structure (&c2
);
1161 *name_size
= len
+ 1;
1162 return _gnutls_asn2err (result
);
1164 asn1_delete_structure (&c2
);
1166 if ((unsigned)len
+ 1 > orig_name_size
)
1169 *name_size
= len
+ 1;
1170 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
1174 /* null terminate it */
1175 ((char *) name
)[*name_size
] = 0;
1179 else if (type
== GNUTLS_SAN_DN
)
1181 _gnutls_str_cat (nptr
, sizeof (nptr
), ".directoryName");
1182 result
= _gnutls_x509_parse_dn (src
, nptr
, name
, name_size
);
1189 else if (othername_oid
)
1190 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1193 size_t orig_name_size
= *name_size
;
1195 _gnutls_str_cat (nptr
, sizeof (nptr
), ".");
1196 _gnutls_str_cat (nptr
, sizeof (nptr
), choice_type
);
1199 result
= asn1_read_value (src
, nptr
, name
, &len
);
1202 if (result
== ASN1_MEM_ERROR
)
1204 if (is_type_printable (type
))
1206 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
1209 if (result
!= ASN1_SUCCESS
)
1212 return _gnutls_asn2err (result
);
1215 if (is_type_printable (type
))
1218 if ((unsigned)len
+ 1 > orig_name_size
)
1222 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
1225 /* null terminate it */
1226 ((char *) name
)[*name_size
] = 0;
1235 get_alt_name (gnutls_x509_crt_t cert
, const char *extension_id
,
1236 unsigned int seq
, void *alt
,
1237 size_t * alt_size
, unsigned int *alt_type
,
1238 unsigned int *critical
, int othername_oid
)
1241 gnutls_datum_t dnsname
;
1242 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
1247 return GNUTLS_E_INVALID_REQUEST
;
1251 memset (alt
, 0, *alt_size
);
1256 _gnutls_x509_crt_get_extension (cert
, extension_id
, 0, &dnsname
,
1262 if (dnsname
.size
== 0 || dnsname
.data
== NULL
)
1265 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1268 if (strcmp ("2.5.29.17", extension_id
) == 0)
1269 result
= asn1_create_element (_gnutls_get_pkix (),
1270 "PKIX1.SubjectAltName", &c2
);
1271 else if (strcmp ("2.5.29.18", extension_id
) == 0)
1272 result
= asn1_create_element (_gnutls_get_pkix (),
1273 "PKIX1.IssuerAltName", &c2
);
1277 return GNUTLS_E_INTERNAL_ERROR
;
1280 if (result
!= ASN1_SUCCESS
)
1283 _gnutls_free_datum (&dnsname
);
1284 return _gnutls_asn2err (result
);
1287 result
= asn1_der_decoding (&c2
, dnsname
.data
, dnsname
.size
, NULL
);
1288 _gnutls_free_datum (&dnsname
);
1290 if (result
!= ASN1_SUCCESS
)
1293 asn1_delete_structure (&c2
);
1294 return _gnutls_asn2err (result
);
1298 _gnutls_parse_general_name (c2
, "", seq
, alt
, alt_size
, alt_type
,
1301 asn1_delete_structure (&c2
);
1313 * gnutls_x509_crt_get_subject_alt_name:
1314 * @cert: should contain a #gnutls_x509_crt_t structure
1315 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1316 * @san: is the place where the alternative name will be copied to
1317 * @san_size: holds the size of san.
1318 * @critical: will be non (0) if the extension is marked as critical (may be null)
1320 * This function retrieves the Alternative Name (2.5.29.17), contained
1321 * in the given certificate in the X509v3 Certificate Extensions.
1323 * When the SAN type is otherName, it will extract the data in the
1324 * otherName's value field, and %GNUTLS_SAN_OTHERNAME is returned.
1325 * You may use gnutls_x509_crt_get_subject_alt_othername_oid() to get
1326 * the corresponding OID and the "virtual" SAN types (e.g.,
1327 * %GNUTLS_SAN_OTHERNAME_XMPP).
1329 * If an otherName OID is known, the data will be decoded. Otherwise
1330 * the returned data will be DER encoded, and you will have to decode
1331 * it yourself. Currently, only the RFC 3920 id-on-xmppAddr SAN is
1334 * Returns: the alternative subject name type on success, one of the
1335 * enumerated #gnutls_x509_subject_alt_name_t. It will return
1336 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @san_size is not large enough to
1337 * hold the value. In that case @san_size will be updated with the
1338 * required size. If the certificate does not have an Alternative
1339 * name with the specified sequence number then
1340 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1343 gnutls_x509_crt_get_subject_alt_name (gnutls_x509_crt_t cert
,
1344 unsigned int seq
, void *san
,
1346 unsigned int *critical
)
1348 return get_alt_name (cert
, "2.5.29.17", seq
, san
, san_size
, NULL
, critical
,
1353 * gnutls_x509_crt_get_issuer_alt_name:
1354 * @cert: should contain a #gnutls_x509_crt_t structure
1355 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1356 * @ian: is the place where the alternative name will be copied to
1357 * @ian_size: holds the size of ian.
1358 * @critical: will be non (0) if the extension is marked as critical (may be null)
1360 * This function retrieves the Issuer Alternative Name (2.5.29.18),
1361 * contained in the given certificate in the X509v3 Certificate
1364 * When the SAN type is otherName, it will extract the data in the
1365 * otherName's value field, and %GNUTLS_SAN_OTHERNAME is returned.
1366 * You may use gnutls_x509_crt_get_subject_alt_othername_oid() to get
1367 * the corresponding OID and the "virtual" SAN types (e.g.,
1368 * %GNUTLS_SAN_OTHERNAME_XMPP).
1370 * If an otherName OID is known, the data will be decoded. Otherwise
1371 * the returned data will be DER encoded, and you will have to decode
1372 * it yourself. Currently, only the RFC 3920 id-on-xmppAddr Issuer
1373 * AltName is recognized.
1375 * Returns: the alternative issuer name type on success, one of the
1376 * enumerated #gnutls_x509_subject_alt_name_t. It will return
1377 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @ian_size is not large enough
1378 * to hold the value. In that case @ian_size will be updated with
1379 * the required size. If the certificate does not have an
1380 * Alternative name with the specified sequence number then
1381 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1386 gnutls_x509_crt_get_issuer_alt_name (gnutls_x509_crt_t cert
,
1387 unsigned int seq
, void *ian
,
1389 unsigned int *critical
)
1391 return get_alt_name (cert
, "2.5.29.18", seq
, ian
, ian_size
, NULL
, critical
,
1396 * gnutls_x509_crt_get_subject_alt_name2:
1397 * @cert: should contain a #gnutls_x509_crt_t structure
1398 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1399 * @san: is the place where the alternative name will be copied to
1400 * @san_size: holds the size of ret.
1401 * @san_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
1402 * @critical: will be non (0) if the extension is marked as critical (may be null)
1404 * This function will return the alternative names, contained in the
1405 * given certificate. It is the same as
1406 * gnutls_x509_crt_get_subject_alt_name() except for the fact that it
1407 * will return the type of the alternative name in @san_type even if
1408 * the function fails for some reason (i.e. the buffer provided is
1411 * Returns: the alternative subject name type on success, one of the
1412 * enumerated #gnutls_x509_subject_alt_name_t. It will return
1413 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @san_size is not large enough
1414 * to hold the value. In that case @san_size will be updated with
1415 * the required size. If the certificate does not have an
1416 * Alternative name with the specified sequence number then
1417 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1420 gnutls_x509_crt_get_subject_alt_name2 (gnutls_x509_crt_t cert
,
1421 unsigned int seq
, void *san
,
1423 unsigned int *san_type
,
1424 unsigned int *critical
)
1426 return get_alt_name (cert
, "2.5.29.17", seq
, san
, san_size
, san_type
,
1431 * gnutls_x509_crt_get_issuer_alt_name2:
1432 * @cert: should contain a #gnutls_x509_crt_t structure
1433 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1434 * @ian: is the place where the alternative name will be copied to
1435 * @ian_size: holds the size of ret.
1436 * @ian_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
1437 * @critical: will be non (0) if the extension is marked as critical (may be null)
1439 * This function will return the alternative names, contained in the
1440 * given certificate. It is the same as
1441 * gnutls_x509_crt_get_issuer_alt_name() except for the fact that it
1442 * will return the type of the alternative name in @ian_type even if
1443 * the function fails for some reason (i.e. the buffer provided is
1446 * Returns: the alternative issuer name type on success, one of the
1447 * enumerated #gnutls_x509_subject_alt_name_t. It will return
1448 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @ian_size is not large enough
1449 * to hold the value. In that case @ian_size will be updated with
1450 * the required size. If the certificate does not have an
1451 * Alternative name with the specified sequence number then
1452 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1458 gnutls_x509_crt_get_issuer_alt_name2 (gnutls_x509_crt_t cert
,
1459 unsigned int seq
, void *ian
,
1461 unsigned int *ian_type
,
1462 unsigned int *critical
)
1464 return get_alt_name (cert
, "2.5.29.18", seq
, ian
, ian_size
, ian_type
,
1469 * gnutls_x509_crt_get_subject_alt_othername_oid:
1470 * @cert: should contain a #gnutls_x509_crt_t structure
1471 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1472 * @oid: is the place where the otherName OID will be copied to
1473 * @oid_size: holds the size of ret.
1475 * This function will extract the type OID of an otherName Subject
1476 * Alternative Name, contained in the given certificate, and return
1477 * the type as an enumerated element.
1479 * This function is only useful if
1480 * gnutls_x509_crt_get_subject_alt_name() returned
1481 * %GNUTLS_SAN_OTHERNAME.
1483 * If @oid is null then only the size will be filled. The @oid
1484 * returned will be null terminated, although @oid_size will not
1485 * account for the trailing null.
1487 * Returns: the alternative subject name type on success, one of the
1488 * enumerated gnutls_x509_subject_alt_name_t. For supported OIDs, it
1489 * will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
1490 * e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
1491 * unknown OIDs. It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
1492 * @ian_size is not large enough to hold the value. In that case
1493 * @ian_size will be updated with the required size. If the
1494 * certificate does not have an Alternative name with the specified
1495 * sequence number and with the otherName type then
1496 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1499 gnutls_x509_crt_get_subject_alt_othername_oid (gnutls_x509_crt_t cert
,
1501 void *oid
, size_t * oid_size
)
1503 return get_alt_name (cert
, "2.5.29.17", seq
, oid
, oid_size
, NULL
, NULL
, 1);
1507 * gnutls_x509_crt_get_issuer_alt_othername_oid:
1508 * @cert: should contain a #gnutls_x509_crt_t structure
1509 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1510 * @ret: is the place where the otherName OID will be copied to
1511 * @ret_size: holds the size of ret.
1513 * This function will extract the type OID of an otherName Subject
1514 * Alternative Name, contained in the given certificate, and return
1515 * the type as an enumerated element.
1517 * If @oid is null then only the size will be filled. The @oid
1518 * returned will be null terminated, although @oid_size will not
1519 * account for the trailing null.
1521 * This function is only useful if
1522 * gnutls_x509_crt_get_issuer_alt_name() returned
1523 * %GNUTLS_SAN_OTHERNAME.
1525 * Returns: the alternative issuer name type on success, one of the
1526 * enumerated gnutls_x509_subject_alt_name_t. For supported OIDs, it
1527 * will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
1528 * e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
1529 * unknown OIDs. It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
1530 * @ret_size is not large enough to hold the value. In that case
1531 * @ret_size will be updated with the required size. If the
1532 * certificate does not have an Alternative name with the specified
1533 * sequence number and with the otherName type then
1534 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1539 gnutls_x509_crt_get_issuer_alt_othername_oid (gnutls_x509_crt_t cert
,
1541 void *ret
, size_t * ret_size
)
1543 return get_alt_name (cert
, "2.5.29.18", seq
, ret
, ret_size
, NULL
, NULL
, 1);
1547 * gnutls_x509_crt_get_basic_constraints:
1548 * @cert: should contain a #gnutls_x509_crt_t structure
1549 * @critical: will be non (0) if the extension is marked as critical
1550 * @ca: pointer to output integer indicating CA status, may be NULL,
1551 * value is 1 if the certificate CA flag is set, 0 otherwise.
1552 * @pathlen: pointer to output integer indicating path length (may be
1553 * NULL), non-negative error codes indicate a present pathLenConstraint
1554 * field and the actual value, -1 indicate that the field is absent.
1556 * This function will read the certificate's basic constraints, and
1557 * return the certificates CA status. It reads the basicConstraints
1558 * X.509 extension (2.5.29.19).
1560 * Returns: If the certificate is a CA a positive value will be
1561 * returned, or (0) if the certificate does not have CA flag set. A
1562 * negative error code may be returned in case of errors. If the
1563 * certificate does not contain the basicConstraints extension
1564 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1567 gnutls_x509_crt_get_basic_constraints (gnutls_x509_crt_t cert
,
1568 unsigned int *critical
,
1569 unsigned int *ca
, int *pathlen
)
1572 gnutls_datum_t basicConstraints
;
1573 unsigned int tmp_ca
;
1578 return GNUTLS_E_INVALID_REQUEST
;
1582 _gnutls_x509_crt_get_extension (cert
, "2.5.29.19", 0,
1583 &basicConstraints
, critical
)) < 0)
1588 if (basicConstraints
.size
== 0 || basicConstraints
.data
== NULL
)
1591 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1595 _gnutls_x509_ext_extract_basicConstraints (&tmp_ca
,
1597 basicConstraints
.data
,
1598 basicConstraints
.size
);
1601 _gnutls_free_datum (&basicConstraints
);
1613 * gnutls_x509_crt_get_ca_status:
1614 * @cert: should contain a #gnutls_x509_crt_t structure
1615 * @critical: will be non (0) if the extension is marked as critical
1617 * This function will return certificates CA status, by reading the
1618 * basicConstraints X.509 extension (2.5.29.19). If the certificate is
1619 * a CA a positive value will be returned, or (0) if the certificate
1620 * does not have CA flag set.
1622 * Use gnutls_x509_crt_get_basic_constraints() if you want to read the
1623 * pathLenConstraint field too.
1625 * Returns: A negative error code may be returned in case of parsing error.
1626 * If the certificate does not contain the basicConstraints extension
1627 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1630 gnutls_x509_crt_get_ca_status (gnutls_x509_crt_t cert
, unsigned int *critical
)
1634 return gnutls_x509_crt_get_basic_constraints (cert
, critical
, &ca
,
1639 * gnutls_x509_crt_get_key_usage:
1640 * @cert: should contain a #gnutls_x509_crt_t structure
1641 * @key_usage: where the key usage bits will be stored
1642 * @critical: will be non (0) if the extension is marked as critical
1644 * This function will return certificate's key usage, by reading the
1645 * keyUsage X.509 extension (2.5.29.15). The key usage value will ORed
1646 * values of the: %GNUTLS_KEY_DIGITAL_SIGNATURE,
1647 * %GNUTLS_KEY_NON_REPUDIATION, %GNUTLS_KEY_KEY_ENCIPHERMENT,
1648 * %GNUTLS_KEY_DATA_ENCIPHERMENT, %GNUTLS_KEY_KEY_AGREEMENT,
1649 * %GNUTLS_KEY_KEY_CERT_SIGN, %GNUTLS_KEY_CRL_SIGN,
1650 * %GNUTLS_KEY_ENCIPHER_ONLY, %GNUTLS_KEY_DECIPHER_ONLY.
1652 * Returns: the certificate key usage, or a negative error code in case of
1653 * parsing error. If the certificate does not contain the keyUsage
1654 * extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
1658 gnutls_x509_crt_get_key_usage (gnutls_x509_crt_t cert
,
1659 unsigned int *key_usage
,
1660 unsigned int *critical
)
1663 gnutls_datum_t keyUsage
;
1669 return GNUTLS_E_INVALID_REQUEST
;
1673 _gnutls_x509_crt_get_extension (cert
, "2.5.29.15", 0, &keyUsage
,
1679 if (keyUsage
.size
== 0 || keyUsage
.data
== NULL
)
1682 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1685 result
= _gnutls_x509_ext_extract_keyUsage (&_usage
, keyUsage
.data
,
1687 _gnutls_free_datum (&keyUsage
);
1689 *key_usage
= _usage
;
1701 * gnutls_x509_crt_get_proxy:
1702 * @cert: should contain a #gnutls_x509_crt_t structure
1703 * @critical: will be non (0) if the extension is marked as critical
1704 * @pathlen: pointer to output integer indicating path length (may be
1705 * NULL), non-negative error codes indicate a present pCPathLenConstraint
1706 * field and the actual value, -1 indicate that the field is absent.
1707 * @policyLanguage: output variable with OID of policy language
1708 * @policy: output variable with policy data
1709 * @sizeof_policy: output variable size of policy data
1711 * This function will get information from a proxy certificate. It
1712 * reads the ProxyCertInfo X.509 extension (1.3.6.1.5.5.7.1.14).
1714 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1715 * otherwise a negative error code is returned.
1718 gnutls_x509_crt_get_proxy (gnutls_x509_crt_t cert
,
1719 unsigned int *critical
,
1721 char **policyLanguage
,
1722 char **policy
, size_t * sizeof_policy
)
1725 gnutls_datum_t proxyCertInfo
;
1730 return GNUTLS_E_INVALID_REQUEST
;
1734 _gnutls_x509_crt_get_extension (cert
, "1.3.6.1.5.5.7.1.14", 0,
1735 &proxyCertInfo
, critical
)) < 0)
1740 if (proxyCertInfo
.size
== 0 || proxyCertInfo
.data
== NULL
)
1743 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1746 result
= _gnutls_x509_ext_extract_proxyCertInfo (pathlen
,
1751 proxyCertInfo
.size
);
1752 _gnutls_free_datum (&proxyCertInfo
);
1763 * gnutls_certificate_policy_release:
1764 * @policy: a certificate policy
1766 * This function will deinitialize all memory associated with the provided
1767 * @policy. The policy is allocated using gnutls_x509_crt_get_policy().
1770 void gnutls_certificate_policy_release(struct gnutls_certificate_policy_st
* policy
)
1774 gnutls_free(policy
->policy_oid
);
1775 for (i
=0;i
<policy
->qualifiers
;i
++)
1776 gnutls_free(policy
->qualifier_data
[i
]);
1779 static int decode_user_notice(const void* data
, size_t size
, char** txt
)
1781 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
1783 char choice_type
[64];
1785 gnutls_datum_t td
, td2
;
1787 ret
= asn1_create_element
1788 (_gnutls_get_pkix (), "PKIX1.UserNotice", &c2
);
1789 if (ret
!= ASN1_SUCCESS
)
1792 ret
= _gnutls_asn2err (ret
);
1796 ret
= asn1_der_decoding (&c2
, data
, size
, NULL
);
1797 if (ret
!= ASN1_SUCCESS
)
1800 ret
= _gnutls_asn2err (ret
);
1804 len
= sizeof(choice_type
);
1805 ret
= asn1_read_value(c2
, "explicitText", choice_type
, &len
);
1806 if (ret
!= ASN1_SUCCESS
)
1809 ret
= _gnutls_asn2err (ret
);
1813 if (strcmp(choice_type
, "utf8String") != 0 && strcmp(choice_type
, "IA5String") != 0 &&
1814 strcmp(choice_type
, "bmpString") != 0 && strcmp(choice_type
, "visibleString") != 0)
1817 ret
= GNUTLS_E_PARSING_ERROR
;
1821 snprintf (name
, sizeof (name
), "explicitText.%s", choice_type
);
1823 ret
= _gnutls_x509_read_value(c2
, name
, &td
);
1824 if (ret
!= ASN1_SUCCESS
)
1830 if (strcmp(choice_type
, "bmpString") == 0)
1831 { /* convert to UTF-8 */
1832 ret
= _gnutls_ucs2_to_utf8(td
.data
, td
.size
, &td2
);
1833 _gnutls_free_datum(&td
);
1845 /* _gnutls_x509_read_value allows that */
1846 td
.data
[td
.size
] = 0;
1849 *txt
= (void*)td
.data
;
1853 asn1_delete_structure (&c2
);
1859 * gnutls_x509_crt_get_policy:
1860 * @cert: should contain a #gnutls_x509_crt_t structure
1861 * @indx: This specifies which policy to return. Use (0) to get the first one.
1862 * @policy: A pointer to a policy structure.
1863 * @critical: will be non (0) if the extension is marked as critical
1865 * This function will extract the certificate policy specified by the
1868 * The policy returned by this function must be deinitialized by using
1869 * gnutls_certificate_policy_release().
1871 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1872 * if the extension is not present, otherwise a negative error value.
1875 gnutls_x509_crt_get_policy (gnutls_x509_crt_t crt
, int indx
, struct gnutls_certificate_policy_st
* policy
, unsigned int *critical
)
1877 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
1879 char tmpoid
[MAX_OID_SIZE
];
1880 gnutls_datum_t tmpd
= {NULL
, 0};
1887 return GNUTLS_E_INVALID_REQUEST
;
1890 memset(policy
, 0, sizeof(*policy
));
1893 _gnutls_x509_crt_get_extension (crt
, "2.5.29.32", 0, &tmpd
,
1899 if (tmpd
.size
== 0 || tmpd
.data
== NULL
)
1902 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1905 ret
= asn1_create_element
1906 (_gnutls_get_pkix (), "PKIX1.certificatePolicies", &c2
);
1907 if (ret
!= ASN1_SUCCESS
)
1910 ret
= _gnutls_asn2err (ret
);
1914 ret
= asn1_der_decoding (&c2
, tmpd
.data
, tmpd
.size
, NULL
);
1915 if (ret
!= ASN1_SUCCESS
)
1918 ret
= _gnutls_asn2err (ret
);
1921 _gnutls_free_datum (&tmpd
);
1924 /* create a string like "?1"
1926 snprintf (tmpstr
, sizeof (tmpstr
), "?%u.policyIdentifier", indx
);
1928 ret
= _gnutls_x509_read_value(c2
, tmpstr
, &tmpd
);
1930 if (ret
== GNUTLS_E_ASN1_ELEMENT_NOT_FOUND
)
1931 ret
= GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1938 policy
->policy_oid
= (void*)tmpd
.data
;
1941 for (i
=0;i
<GNUTLS_MAX_QUALIFIERS
;i
++)
1945 snprintf (tmpstr
, sizeof (tmpstr
), "?%u.policyQualifiers.?%u.policyQualifierId", indx
, i
+1);
1947 len
= sizeof(tmpoid
);
1948 ret
= asn1_read_value(c2
, tmpstr
, tmpoid
, &len
);
1950 if (ret
== ASN1_ELEMENT_NOT_FOUND
&& i
> 0)
1951 break; /* finished */
1953 if (ret
!= ASN1_SUCCESS
)
1956 ret
= _gnutls_asn2err (ret
);
1960 if (strcmp(tmpoid
, "1.3.6.1.5.5.7.2.1") == 0)
1962 snprintf (tmpstr
, sizeof (tmpstr
), "?%u.policyQualifiers.?%u.qualifier", indx
, i
+1);
1964 ret
= _gnutls_x509_read_string(c2
, tmpstr
, &td
, RV_IA5STRING
);
1971 policy
->qualifier_data
[i
] = (void*)td
.data
;
1973 policy
->qualifier_type
[i
] = GNUTLS_X509_QUALIFIER_URI
;
1975 else if (strcmp(tmpoid
, "1.3.6.1.5.5.7.2.2") == 0)
1977 snprintf (tmpstr
, sizeof (tmpstr
), "?%u.policyQualifiers.?%u.qualifier", indx
, i
+1);
1979 ret
= _gnutls_x509_read_string(c2
, tmpstr
, &td
, RV_RAW
);
1986 ret
= decode_user_notice(td
.data
, td
.size
, &policy
->qualifier_data
[i
]);
1987 gnutls_free(td
.data
);
1996 policy
->qualifier_type
[i
] = GNUTLS_X509_QUALIFIER_NOTICE
;
1999 policy
->qualifier_type
[i
] = GNUTLS_X509_QUALIFIER_UNKNOWN
;
2001 policy
->qualifiers
++;
2010 gnutls_certificate_policy_release(policy
);
2013 _gnutls_free_datum (&tmpd
);
2014 asn1_delete_structure (&c2
);
2020 * gnutls_x509_crt_get_extension_by_oid:
2021 * @cert: should contain a #gnutls_x509_crt_t structure
2022 * @oid: holds an Object Identified in null terminated string
2023 * @indx: In case multiple same OIDs exist in the extensions, this specifies which to send. Use (0) to get the first one.
2024 * @buf: a pointer to a structure to hold the name (may be null)
2025 * @buf_size: initially holds the size of @buf
2026 * @critical: will be non (0) if the extension is marked as critical
2028 * This function will return the extension specified by the OID in the
2029 * certificate. The extensions will be returned as binary data DER
2030 * encoded, in the provided buffer.
2032 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2033 * otherwise a negative error code is returned. If the certificate does not
2034 * contain the specified extension
2035 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
2038 gnutls_x509_crt_get_extension_by_oid (gnutls_x509_crt_t cert
,
2039 const char *oid
, int indx
,
2040 void *buf
, size_t * buf_size
,
2041 unsigned int *critical
)
2044 gnutls_datum_t output
;
2049 return GNUTLS_E_INVALID_REQUEST
;
2053 _gnutls_x509_crt_get_extension (cert
, oid
, indx
, &output
,
2060 if (output
.size
== 0 || output
.data
== NULL
)
2063 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
2066 if (output
.size
> (unsigned int) *buf_size
)
2068 *buf_size
= output
.size
;
2069 _gnutls_free_datum (&output
);
2070 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
2073 *buf_size
= output
.size
;
2076 memcpy (buf
, output
.data
, output
.size
);
2078 _gnutls_free_datum (&output
);
2085 * gnutls_x509_crt_get_extension_oid:
2086 * @cert: should contain a #gnutls_x509_crt_t structure
2087 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
2088 * @oid: a pointer to a structure to hold the OID (may be null)
2089 * @oid_size: initially holds the size of @oid
2091 * This function will return the requested extension OID in the certificate.
2092 * The extension OID will be stored as a string in the provided buffer.
2094 * The @oid returned will be null terminated, although @oid_size will not
2095 * account for the trailing null.
2097 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2098 * otherwise a negative error code is returned. If you have reached the
2099 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2103 gnutls_x509_crt_get_extension_oid (gnutls_x509_crt_t cert
, int indx
,
2104 void *oid
, size_t * oid_size
)
2111 return GNUTLS_E_INVALID_REQUEST
;
2114 result
= _gnutls_x509_crt_get_extension_oid (cert
, indx
, oid
, oid_size
);
2125 * gnutls_x509_crt_get_extension_info:
2126 * @cert: should contain a #gnutls_x509_crt_t structure
2127 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
2128 * @oid: a pointer to a structure to hold the OID
2129 * @oid_size: initially holds the maximum size of @oid, on return
2130 * holds actual size of @oid.
2131 * @critical: output variable with critical flag, may be NULL.
2133 * This function will return the requested extension OID in the
2134 * certificate, and the critical flag for it. The extension OID will
2135 * be stored as a string in the provided buffer. Use
2136 * gnutls_x509_crt_get_extension_data() to extract the data.
2138 * If the buffer provided is not long enough to hold the output, then
2139 * @oid_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
2140 * returned. The @oid returned will be null terminated, although
2141 * @oid_size will not account for the trailing null.
2143 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2144 * otherwise a negative error code is returned. If you have reached the
2145 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2149 gnutls_x509_crt_get_extension_info (gnutls_x509_crt_t cert
, int indx
,
2150 void *oid
, size_t * oid_size
,
2151 unsigned int *critical
)
2154 char str_critical
[10];
2155 char name
[ASN1_MAX_NAME_SIZE
];
2161 return GNUTLS_E_INVALID_REQUEST
;
2164 snprintf (name
, sizeof (name
), "tbsCertificate.extensions.?%u.extnID",
2168 result
= asn1_read_value (cert
->cert
, name
, oid
, &len
);
2171 if (result
== ASN1_ELEMENT_NOT_FOUND
)
2172 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
2173 else if (result
!= ASN1_SUCCESS
)
2176 return _gnutls_asn2err (result
);
2179 snprintf (name
, sizeof (name
), "tbsCertificate.extensions.?%u.critical",
2181 len
= sizeof (str_critical
);
2182 result
= asn1_read_value (cert
->cert
, name
, str_critical
, &len
);
2183 if (result
!= ASN1_SUCCESS
)
2186 return _gnutls_asn2err (result
);
2191 if (str_critical
[0] == 'T')
2202 * gnutls_x509_crt_get_extension_data:
2203 * @cert: should contain a #gnutls_x509_crt_t structure
2204 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
2205 * @data: a pointer to a structure to hold the data (may be null)
2206 * @sizeof_data: initially holds the size of @oid
2208 * This function will return the requested extension data in the
2209 * certificate. The extension data will be stored as a string in the
2212 * Use gnutls_x509_crt_get_extension_info() to extract the OID and
2213 * critical flag. Use gnutls_x509_crt_get_extension_by_oid() instead,
2214 * if you want to get data indexed by the extension OID rather than
2217 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2218 * otherwise a negative error code is returned. If you have reached the
2219 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2223 gnutls_x509_crt_get_extension_data (gnutls_x509_crt_t cert
, int indx
,
2224 void *data
, size_t * sizeof_data
)
2227 char name
[ASN1_MAX_NAME_SIZE
];
2232 return GNUTLS_E_INVALID_REQUEST
;
2235 snprintf (name
, sizeof (name
), "tbsCertificate.extensions.?%u.extnValue",
2239 result
= asn1_read_value (cert
->cert
, name
, data
, &len
);
2242 if (result
== ASN1_ELEMENT_NOT_FOUND
)
2243 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
2244 else if (result
< 0)
2247 return _gnutls_asn2err (result
);
2254 _gnutls_x509_crt_get_raw_dn2 (gnutls_x509_crt_t cert
,
2255 const char *whom
, gnutls_datum_t
* start
)
2257 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
2260 gnutls_datum_t signed_data
= { NULL
, 0 };
2262 /* get the issuer of 'cert'
2265 asn1_create_element (_gnutls_get_pkix (), "PKIX1.TBSCertificate",
2266 &c2
)) != ASN1_SUCCESS
)
2269 return _gnutls_asn2err (result
);
2273 _gnutls_x509_get_signed_data (cert
->cert
, "tbsCertificate", &signed_data
);
2280 result
= asn1_der_decoding (&c2
, signed_data
.data
, signed_data
.size
, NULL
);
2281 if (result
!= ASN1_SUCCESS
)
2284 asn1_delete_structure (&c2
);
2285 result
= _gnutls_asn2err (result
);
2290 asn1_der_decoding_startEnd (c2
, signed_data
.data
, signed_data
.size
,
2291 whom
, &start1
, &end1
);
2293 if (result
!= ASN1_SUCCESS
)
2296 result
= _gnutls_asn2err (result
);
2300 len1
= end1
- start1
+ 1;
2302 _gnutls_set_datum (start
, &signed_data
.data
[start1
], len1
);
2307 asn1_delete_structure (&c2
);
2308 _gnutls_free_datum (&signed_data
);
2313 * gnutls_x509_crt_get_raw_issuer_dn:
2314 * @cert: should contain a #gnutls_x509_crt_t structure
2315 * @start: will hold the starting point of the DN
2317 * This function will return a pointer to the DER encoded DN structure
2318 * and the length. This points to allocated data that must be free'd using gnutls_free().
2320 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2321 * negative error value.or a negative error code on error.
2325 gnutls_x509_crt_get_raw_issuer_dn (gnutls_x509_crt_t cert
,
2326 gnutls_datum_t
* start
)
2328 return _gnutls_x509_crt_get_raw_dn2 (cert
, "issuer", start
);
2332 * gnutls_x509_crt_get_raw_dn:
2333 * @cert: should contain a #gnutls_x509_crt_t structure
2334 * @start: will hold the starting point of the DN
2336 * This function will return a pointer to the DER encoded DN structure and
2337 * the length. This points to allocated data that must be free'd using gnutls_free().
2339 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2340 * negative error value. or a negative error code on error.
2344 gnutls_x509_crt_get_raw_dn (gnutls_x509_crt_t cert
, gnutls_datum_t
* start
)
2346 return _gnutls_x509_crt_get_raw_dn2 (cert
, "subject", start
);
2350 get_dn (gnutls_x509_crt_t cert
, const char *whom
, gnutls_x509_dn_t
* dn
)
2352 *dn
= asn1_find_node (cert
->cert
, whom
);
2354 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND
;
2359 * gnutls_x509_crt_get_subject:
2360 * @cert: should contain a #gnutls_x509_crt_t structure
2361 * @dn: output variable with pointer to uint8_t DN.
2363 * Return the Certificate's Subject DN as an uint8_t data type. You
2364 * may use gnutls_x509_dn_get_rdn_ava() to decode the DN.
2366 * Note that @dn should be treated as constant. Because points
2367 * into the @cert object, you may not deallocate @cert
2368 * and continue to access @dn.
2370 * Returns: Returns 0 on success, or an error code.
2373 gnutls_x509_crt_get_subject (gnutls_x509_crt_t cert
, gnutls_x509_dn_t
* dn
)
2375 return get_dn (cert
, "tbsCertificate.subject.rdnSequence", dn
);
2379 * gnutls_x509_crt_get_issuer:
2380 * @cert: should contain a #gnutls_x509_crt_t structure
2381 * @dn: output variable with pointer to uint8_t DN
2383 * Return the Certificate's Issuer DN as an uint8_t data type. You may
2384 * use gnutls_x509_dn_get_rdn_ava() to decode the DN.
2386 * Note that @dn should be treated as constant. Because points
2387 * into the @cert object, you may not deallocate @cert
2388 * and continue to access @dn.
2390 * Returns: Returns 0 on success, or an error code.
2393 gnutls_x509_crt_get_issuer (gnutls_x509_crt_t cert
, gnutls_x509_dn_t
* dn
)
2395 return get_dn (cert
, "tbsCertificate.issuer.rdnSequence", dn
);
2399 * gnutls_x509_dn_get_rdn_ava:
2400 * @dn: input variable with uint8_t DN pointer
2401 * @irdn: index of RDN
2402 * @iava: index of AVA.
2403 * @ava: Pointer to structure which will hold output information.
2405 * Get pointers to data within the DN.
2407 * Note that @ava will contain pointers into the @dn structure, so you
2408 * should not modify any data or deallocate it. Note also that the DN
2409 * in turn points into the original certificate structure, and thus
2410 * you may not deallocate the certificate and continue to access @dn.
2412 * Returns: Returns 0 on success, or an error code.
2415 gnutls_x509_dn_get_rdn_ava (gnutls_x509_dn_t dn
,
2416 int irdn
, int iava
, gnutls_x509_ava_st
* ava
)
2418 ASN1_TYPE rdn
, elem
;
2419 ASN1_DATA_NODE vnode
;
2421 int lenlen
, remlen
, ret
;
2422 char rbuf
[ASN1_MAX_NAME_SIZE
];
2424 const unsigned char *ptr
;
2427 irdn
++; /* 0->1, 1->2 etc */
2429 snprintf (rbuf
, sizeof (rbuf
), "rdnSequence.?%d.?%d", irdn
, iava
);
2430 rdn
= asn1_find_node (dn
, rbuf
);
2434 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND
;
2437 snprintf (rbuf
, sizeof (rbuf
), "?%d.type", iava
);
2438 elem
= asn1_find_node (rdn
, rbuf
);
2442 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND
;
2445 ret
= asn1_read_node_value(elem
, &vnode
);
2446 if (ret
!= ASN1_SUCCESS
)
2449 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND
;
2452 ava
->oid
.data
= (void*)vnode
.value
;
2453 ava
->oid
.size
= vnode
.value_len
;
2455 snprintf (rbuf
, sizeof (rbuf
), "?%d.value", iava
);
2456 elem
= asn1_find_node (rdn
, rbuf
);
2460 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND
;
2463 ret
= asn1_read_node_value(elem
, &vnode
);
2464 if (ret
!= ASN1_SUCCESS
)
2467 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND
;
2469 /* The value still has the previous tag's length bytes, plus the
2470 * current value's tag and length bytes. Decode them.
2474 remlen
= vnode
.value_len
;
2475 len
= asn1_get_length_der (ptr
, remlen
, &lenlen
);
2479 return GNUTLS_E_ASN1_DER_ERROR
;
2484 ret
= asn1_get_tag_der (ptr
, remlen
, &cls
, &lenlen
, &ava
->value_tag
);
2488 return _gnutls_asn2err (ret
);
2497 tmp
= asn1_get_length_der (ptr
, remlen
, &lenlen
);
2501 return GNUTLS_E_ASN1_DER_ERROR
;
2503 ava
->value
.size
= tmp
;
2505 ava
->value
.data
= (void*)(ptr
+ lenlen
);
2511 * gnutls_x509_crt_get_fingerprint:
2512 * @cert: should contain a #gnutls_x509_crt_t structure
2513 * @algo: is a digest algorithm
2514 * @buf: a pointer to a structure to hold the fingerprint (may be null)
2515 * @buf_size: initially holds the size of @buf
2517 * This function will calculate and copy the certificate's fingerprint
2518 * in the provided buffer.
2520 * If the buffer is null then only the size will be filled.
2522 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
2523 * not long enough, and in that case the *buf_size will be updated
2524 * with the required size. On success 0 is returned.
2527 gnutls_x509_crt_get_fingerprint (gnutls_x509_crt_t cert
,
2528 gnutls_digest_algorithm_t algo
,
2529 void *buf
, size_t * buf_size
)
2536 if (buf_size
== 0 || cert
== NULL
)
2538 return GNUTLS_E_INVALID_REQUEST
;
2542 asn1_der_coding (cert
->cert
, "", NULL
, &cert_buf_size
, NULL
);
2544 cert_buf
= gnutls_malloc (cert_buf_size
);
2545 if (cert_buf
== NULL
)
2548 return GNUTLS_E_MEMORY_ERROR
;
2551 result
= asn1_der_coding (cert
->cert
, "", cert_buf
, &cert_buf_size
, NULL
);
2553 if (result
!= ASN1_SUCCESS
)
2556 gnutls_free (cert_buf
);
2557 return _gnutls_asn2err (result
);
2560 tmp
.data
= cert_buf
;
2561 tmp
.size
= cert_buf_size
;
2563 result
= gnutls_fingerprint (algo
, &tmp
, buf
, buf_size
);
2564 gnutls_free (cert_buf
);
2570 * gnutls_x509_crt_export:
2571 * @cert: Holds the certificate
2572 * @format: the format of output params. One of PEM or DER.
2573 * @output_data: will contain a certificate PEM or DER encoded
2574 * @output_data_size: holds the size of output_data (and will be
2575 * replaced by the actual size of parameters)
2577 * This function will export the certificate to DER or PEM format.
2579 * If the buffer provided is not long enough to hold the output, then
2580 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2583 * If the structure is PEM encoded, it will have a header
2584 * of "BEGIN CERTIFICATE".
2586 * Returns: In case of failure a negative error code will be
2587 * returned, and 0 on success.
2590 gnutls_x509_crt_export (gnutls_x509_crt_t cert
,
2591 gnutls_x509_crt_fmt_t format
, void *output_data
,
2592 size_t * output_data_size
)
2597 return GNUTLS_E_INVALID_REQUEST
;
2600 return _gnutls_x509_export_int (cert
->cert
, format
, "CERTIFICATE",
2601 output_data
, output_data_size
);
2605 * gnutls_x509_crt_export2:
2606 * @cert: Holds the certificate
2607 * @format: the format of output params. One of PEM or DER.
2608 * @out: will contain a certificate PEM or DER encoded
2610 * This function will export the certificate to DER or PEM format.
2611 * The output buffer is allocated using gnutls_malloc().
2613 * If the structure is PEM encoded, it will have a header
2614 * of "BEGIN CERTIFICATE".
2616 * Returns: In case of failure a negative error code will be
2617 * returned, and 0 on success.
2622 gnutls_x509_crt_export2 (gnutls_x509_crt_t cert
,
2623 gnutls_x509_crt_fmt_t format
, gnutls_datum_t
* out
)
2628 return GNUTLS_E_INVALID_REQUEST
;
2631 return _gnutls_x509_export_int2 (cert
->cert
, format
, "CERTIFICATE", out
);
2635 _gnutls_get_key_id (gnutls_pk_algorithm_t pk
, gnutls_pk_params_st
* params
,
2636 unsigned char *output_data
,
2637 size_t * output_data_size
)
2640 gnutls_datum_t der
= { NULL
, 0 };
2641 const gnutls_digest_algorithm_t hash
= GNUTLS_DIG_SHA1
;
2642 unsigned int digest_len
= _gnutls_hash_get_algo_len(hash
);
2644 if (output_data
== NULL
|| *output_data_size
< digest_len
)
2647 *output_data_size
= digest_len
;
2648 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
2651 ret
= _gnutls_x509_encode_PKI_params(&der
, pk
, params
);
2653 return gnutls_assert_val(ret
);
2655 ret
= _gnutls_hash_fast(hash
, der
.data
, der
.size
, output_data
);
2661 *output_data_size
= digest_len
;
2667 _gnutls_free_datum (&der
);
2672 * gnutls_x509_crt_get_key_id:
2673 * @crt: Holds the certificate
2674 * @flags: should be 0 for now
2675 * @output_data: will contain the key ID
2676 * @output_data_size: holds the size of output_data (and will be
2677 * replaced by the actual size of parameters)
2679 * This function will return a unique ID that depends on the public
2680 * key parameters. This ID can be used in checking whether a
2681 * certificate corresponds to the given private key.
2683 * If the buffer provided is not long enough to hold the output, then
2684 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2685 * be returned. The output will normally be a SHA-1 hash output,
2686 * which is 20 bytes.
2688 * Returns: In case of failure a negative error code will be
2689 * returned, and 0 on success.
2692 gnutls_x509_crt_get_key_id (gnutls_x509_crt_t crt
, unsigned int flags
,
2693 unsigned char *output_data
,
2694 size_t * output_data_size
)
2697 gnutls_pk_params_st params
;
2702 return GNUTLS_E_INVALID_REQUEST
;
2705 pk
= gnutls_x509_crt_get_pk_algorithm (crt
, NULL
);
2712 ret
= _gnutls_x509_crt_get_mpis (crt
, ¶ms
);
2719 ret
= _gnutls_get_key_id(pk
, ¶ms
, output_data
, output_data_size
);
2721 gnutls_pk_params_release(¶ms
);
2727 /* This is exactly as gnutls_x509_crt_check_revocation() except that
2731 _gnutls_x509_crt_check_revocation (gnutls_x509_crt_t cert
,
2732 const gnutls_x509_crl_t
* crl_list
,
2733 int crl_list_length
,
2734 gnutls_verify_output_function func
)
2736 uint8_t serial
[128];
2737 uint8_t cert_serial
[128];
2738 size_t serial_size
, cert_serial_size
;
2739 int ncerts
, ret
, i
, j
;
2740 gnutls_datum_t dn1
, dn2
;
2745 return GNUTLS_E_INVALID_REQUEST
;
2748 for (j
= 0; j
< crl_list_length
; j
++)
2749 { /* do for all the crls */
2751 /* Step 1. check if issuer's DN match
2753 ret
= gnutls_x509_crl_get_raw_issuer_dn (crl_list
[j
], &dn1
);
2760 ret
= gnutls_x509_crt_get_raw_issuer_dn (cert
, &dn2
);
2767 ret
= _gnutls_x509_compare_raw_dn (&dn1
, &dn2
);
2768 _gnutls_free_datum (&dn1
);
2769 _gnutls_free_datum (&dn2
);
2772 /* issuers do not match so don't even
2778 /* Step 2. Read the certificate's serial number
2780 cert_serial_size
= sizeof (cert_serial
);
2781 ret
= gnutls_x509_crt_get_serial (cert
, cert_serial
, &cert_serial_size
);
2788 /* Step 3. cycle through the CRL serials and compare with
2789 * certificate serial we have.
2792 ncerts
= gnutls_x509_crl_get_crt_count (crl_list
[j
]);
2799 for (i
= 0; i
< ncerts
; i
++)
2801 serial_size
= sizeof (serial
);
2803 gnutls_x509_crl_get_crt_serial (crl_list
[j
], i
, serial
,
2804 &serial_size
, NULL
);
2812 if (serial_size
== cert_serial_size
)
2814 if (memcmp (serial
, cert_serial
, serial_size
) == 0)
2817 if (func
) func(cert
, NULL
, crl_list
[j
], GNUTLS_CERT_REVOKED
|GNUTLS_CERT_INVALID
);
2818 return 1; /* revoked! */
2822 if (func
) func(cert
, NULL
, crl_list
[j
], 0);
2825 return 0; /* not revoked. */
2830 * gnutls_x509_crt_check_revocation:
2831 * @cert: should contain a #gnutls_x509_crt_t structure
2832 * @crl_list: should contain a list of gnutls_x509_crl_t structures
2833 * @crl_list_length: the length of the crl_list
2835 * This function will return check if the given certificate is
2836 * revoked. It is assumed that the CRLs have been verified before.
2838 * Returns: 0 if the certificate is NOT revoked, and 1 if it is. A
2839 * negative error code is returned on error.
2842 gnutls_x509_crt_check_revocation (gnutls_x509_crt_t cert
,
2843 const gnutls_x509_crl_t
* crl_list
,
2844 int crl_list_length
)
2846 return _gnutls_x509_crt_check_revocation(cert
, crl_list
, crl_list_length
, NULL
);
2850 * gnutls_x509_crt_get_verify_algorithm:
2851 * @crt: Holds the certificate
2852 * @signature: contains the signature
2853 * @hash: The result of the call with the hash algorithm used for signature
2855 * This function will read the certifcate and the signed data to
2856 * determine the hash algorithm used to generate the signature.
2858 * Deprecated: Use gnutls_pubkey_get_verify_algorithm() instead.
2860 * Returns: the 0 if the hash algorithm is found. A negative error code is
2861 * returned on error.
2866 gnutls_x509_crt_get_verify_algorithm (gnutls_x509_crt_t crt
,
2867 const gnutls_datum_t
* signature
,
2868 gnutls_digest_algorithm_t
* hash
)
2870 gnutls_pk_params_st issuer_params
;
2876 return GNUTLS_E_INVALID_REQUEST
;
2879 ret
= _gnutls_x509_crt_get_mpis (crt
, &issuer_params
);
2886 ret
= _gnutls_x509_verify_algorithm (hash
,
2888 gnutls_x509_crt_get_pk_algorithm (crt
,
2892 /* release allocated mpis */
2893 gnutls_pk_params_release(&issuer_params
);
2901 * gnutls_x509_crt_get_preferred_hash_algorithm:
2902 * @crt: Holds the certificate
2903 * @hash: The result of the call with the hash algorithm used for signature
2904 * @mand: If non (0) it means that the algorithm MUST use this hash. May be NULL.
2906 * This function will read the certifcate and return the appropriate digest
2907 * algorithm to use for signing with this certificate. Some certificates (i.e.
2908 * DSA might not be able to sign without the preferred algorithm).
2910 * Deprecated: Please use gnutls_pubkey_get_preferred_hash_algorithm().
2912 * Returns: the 0 if the hash algorithm is found. A negative error code is
2913 * returned on error.
2918 gnutls_x509_crt_get_preferred_hash_algorithm (gnutls_x509_crt_t crt
,
2919 gnutls_digest_algorithm_t
*
2920 hash
, unsigned int *mand
)
2922 gnutls_pk_params_st issuer_params
;
2928 return GNUTLS_E_INVALID_REQUEST
;
2931 ret
= _gnutls_x509_crt_get_mpis (crt
, &issuer_params
);
2939 _gnutls_pk_get_hash_algorithm (gnutls_x509_crt_get_pk_algorithm
2940 (crt
, NULL
), &issuer_params
,
2943 /* release allocated mpis */
2944 gnutls_pk_params_release(&issuer_params
);
2950 * gnutls_x509_crt_verify_data:
2951 * @crt: Holds the certificate
2952 * @flags: should be 0 for now
2953 * @data: holds the data to be signed
2954 * @signature: contains the signature
2956 * This function will verify the given signed data, using the
2957 * parameters from the certificate.
2959 * Deprecated. Please use gnutls_pubkey_verify_data().
2961 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
2962 * is returned, and zero or positive code on success.
2965 gnutls_x509_crt_verify_data (gnutls_x509_crt_t crt
, unsigned int flags
,
2966 const gnutls_datum_t
* data
,
2967 const gnutls_datum_t
* signature
)
2974 return GNUTLS_E_INVALID_REQUEST
;
2977 result
= _gnutls_x509_verify_data (GNUTLS_DIG_UNKNOWN
, data
, signature
, crt
);
2988 * gnutls_x509_crt_verify_hash:
2989 * @crt: Holds the certificate
2990 * @flags: should be 0 for now
2991 * @hash: holds the hash digest to be verified
2992 * @signature: contains the signature
2994 * This function will verify the given signed digest, using the
2995 * parameters from the certificate.
2997 * Deprecated. Please use gnutls_pubkey_verify_data2() or gnutls_pubkey_verify_hash2().
2999 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
3000 * is returned, and zero or positive code on success.
3003 gnutls_x509_crt_verify_hash (gnutls_x509_crt_t crt
, unsigned int flags
,
3004 const gnutls_datum_t
* hash
,
3005 const gnutls_datum_t
* signature
)
3007 gnutls_pk_params_st params
;
3008 gnutls_digest_algorithm_t algo
;
3014 return GNUTLS_E_INVALID_REQUEST
;
3017 ret
= gnutls_x509_crt_get_verify_algorithm (crt
, signature
, &algo
);
3019 return gnutls_assert_val(ret
);
3021 /* Read the MPI parameters from the issuer's certificate.
3024 _gnutls_x509_crt_get_mpis (crt
, ¶ms
);
3032 pubkey_verify_hashed_data (gnutls_x509_crt_get_pk_algorithm (crt
, NULL
), algo
,
3033 hash
, signature
, ¶ms
);
3039 /* release all allocated MPIs
3041 gnutls_pk_params_release(¶ms
);
3047 * gnutls_x509_crt_get_crl_dist_points:
3048 * @cert: should contain a #gnutls_x509_crt_t structure
3049 * @seq: specifies the sequence number of the distribution point (0 for the first one, 1 for the second etc.)
3050 * @ret: is the place where the distribution point will be copied to
3051 * @ret_size: holds the size of ret.
3052 * @reason_flags: Revocation reasons. An ORed sequence of flags from %gnutls_x509_crl_reason_flags_t.
3053 * @critical: will be non (0) if the extension is marked as critical (may be null)
3055 * This function retrieves the CRL distribution points (2.5.29.31),
3056 * contained in the given certificate in the X509v3 Certificate
3059 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER and updates @ret_size if
3060 * @ret_size is not enough to hold the distribution point, or the
3061 * type of the distribution point if everything was ok. The type is
3062 * one of the enumerated %gnutls_x509_subject_alt_name_t. If the
3063 * certificate does not have an Alternative name with the specified
3064 * sequence number then %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is
3068 gnutls_x509_crt_get_crl_dist_points (gnutls_x509_crt_t cert
,
3069 unsigned int seq
, void *ret
,
3071 unsigned int *reason_flags
,
3072 unsigned int *critical
)
3075 gnutls_datum_t dist_points
= { NULL
, 0 };
3076 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
3077 char name
[ASN1_MAX_NAME_SIZE
];
3079 gnutls_x509_subject_alt_name_t type
;
3085 return GNUTLS_E_INVALID_REQUEST
;
3088 if (*ret_size
> 0 && ret
)
3089 memset (ret
, 0, *ret_size
);
3097 _gnutls_x509_crt_get_extension (cert
, "2.5.29.31", 0, &dist_points
,
3104 if (dist_points
.size
== 0 || dist_points
.data
== NULL
)
3107 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
3110 result
= asn1_create_element
3111 (_gnutls_get_pkix (), "PKIX1.CRLDistributionPoints", &c2
);
3112 if (result
!= ASN1_SUCCESS
)
3115 _gnutls_free_datum (&dist_points
);
3116 return _gnutls_asn2err (result
);
3119 result
= asn1_der_decoding (&c2
, dist_points
.data
, dist_points
.size
, NULL
);
3120 _gnutls_free_datum (&dist_points
);
3122 if (result
!= ASN1_SUCCESS
)
3125 asn1_delete_structure (&c2
);
3126 return _gnutls_asn2err (result
);
3129 /* Return the different names from the first CRLDistr. point.
3130 * The whole thing is a mess.
3132 _gnutls_str_cpy (name
, sizeof (name
), "?1.distributionPoint.fullName");
3134 result
= _gnutls_parse_general_name (c2
, name
, seq
, ret
, ret_size
, NULL
, 0);
3137 asn1_delete_structure (&c2
);
3144 /* Read the CRL reasons.
3148 _gnutls_str_cpy (name
, sizeof (name
), "?1.reasons");
3150 reasons
[0] = reasons
[1] = 0;
3152 len
= sizeof (reasons
);
3153 result
= asn1_read_value (c2
, name
, reasons
, &len
);
3155 if (result
!= ASN1_VALUE_NOT_FOUND
&& result
!= ASN1_SUCCESS
)
3158 asn1_delete_structure (&c2
);
3159 return _gnutls_asn2err (result
);
3162 *reason_flags
= reasons
[0] | (reasons
[1] << 8);
3165 asn1_delete_structure (&c2
);
3171 * gnutls_x509_crt_get_key_purpose_oid:
3172 * @cert: should contain a #gnutls_x509_crt_t structure
3173 * @indx: This specifies which OID to return. Use (0) to get the first one.
3174 * @oid: a pointer to a buffer to hold the OID (may be null)
3175 * @oid_size: initially holds the size of @oid
3176 * @critical: output flag to indicate criticality of extension
3178 * This function will extract the key purpose OIDs of the Certificate
3179 * specified by the given index. These are stored in the Extended Key
3180 * Usage extension (2.5.29.37) See the GNUTLS_KP_* definitions for
3181 * human readable names.
3183 * If @oid is null then only the size will be filled. The @oid
3184 * returned will be null terminated, although @oid_size will not
3185 * account for the trailing null.
3187 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
3188 * not long enough, and in that case the *oid_size will be updated
3189 * with the required size. On success 0 is returned.
3192 gnutls_x509_crt_get_key_purpose_oid (gnutls_x509_crt_t cert
,
3193 int indx
, void *oid
, size_t * oid_size
,
3194 unsigned int *critical
)
3196 char tmpstr
[ASN1_MAX_NAME_SIZE
];
3199 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
3204 return GNUTLS_E_INVALID_REQUEST
;
3208 memset (oid
, 0, *oid_size
);
3213 _gnutls_x509_crt_get_extension (cert
, "2.5.29.37", 0, &id
,
3219 if (id
.size
== 0 || id
.data
== NULL
)
3222 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
3225 result
= asn1_create_element
3226 (_gnutls_get_pkix (), "PKIX1.ExtKeyUsageSyntax", &c2
);
3227 if (result
!= ASN1_SUCCESS
)
3230 _gnutls_free_datum (&id
);
3231 return _gnutls_asn2err (result
);
3234 result
= asn1_der_decoding (&c2
, id
.data
, id
.size
, NULL
);
3235 _gnutls_free_datum (&id
);
3237 if (result
!= ASN1_SUCCESS
)
3240 asn1_delete_structure (&c2
);
3241 return _gnutls_asn2err (result
);
3245 /* create a string like "?1"
3247 snprintf (tmpstr
, sizeof (tmpstr
), "?%u", indx
);
3250 result
= asn1_read_value (c2
, tmpstr
, oid
, &len
);
3253 asn1_delete_structure (&c2
);
3255 if (result
== ASN1_VALUE_NOT_FOUND
|| result
== ASN1_ELEMENT_NOT_FOUND
)
3257 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
3260 if (result
!= ASN1_SUCCESS
)
3263 return _gnutls_asn2err (result
);
3271 * gnutls_x509_crt_get_pk_rsa_raw:
3272 * @crt: Holds the certificate
3273 * @m: will hold the modulus
3274 * @e: will hold the public exponent
3276 * This function will export the RSA public key's parameters found in
3277 * the given structure. The new parameters will be allocated using
3278 * gnutls_malloc() and will be stored in the appropriate datum.
3280 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3283 gnutls_x509_crt_get_pk_rsa_raw (gnutls_x509_crt_t crt
,
3284 gnutls_datum_t
* m
, gnutls_datum_t
* e
)
3287 gnutls_pk_params_st params
;
3292 return GNUTLS_E_INVALID_REQUEST
;
3295 ret
= gnutls_x509_crt_get_pk_algorithm (crt
, NULL
);
3296 if (ret
!= GNUTLS_PK_RSA
)
3299 return GNUTLS_E_INVALID_REQUEST
;
3302 ret
= _gnutls_x509_crt_get_mpis (crt
, ¶ms
);
3309 ret
= _gnutls_mpi_dprint_lz (params
.params
[0], m
);
3316 ret
= _gnutls_mpi_dprint_lz (params
.params
[1], e
);
3320 _gnutls_free_datum (m
);
3327 gnutls_pk_params_release(¶ms
);
3332 * gnutls_x509_crt_get_pk_dsa_raw:
3333 * @crt: Holds the certificate
3334 * @p: will hold the p
3335 * @q: will hold the q
3336 * @g: will hold the g
3337 * @y: will hold the y
3339 * This function will export the DSA public key's parameters found in
3340 * the given certificate. The new parameters will be allocated using
3341 * gnutls_malloc() and will be stored in the appropriate datum.
3343 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3346 gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt
,
3347 gnutls_datum_t
* p
, gnutls_datum_t
* q
,
3348 gnutls_datum_t
* g
, gnutls_datum_t
* y
)
3351 gnutls_pk_params_st params
;
3356 return GNUTLS_E_INVALID_REQUEST
;
3359 ret
= gnutls_x509_crt_get_pk_algorithm (crt
, NULL
);
3360 if (ret
!= GNUTLS_PK_DSA
)
3363 return GNUTLS_E_INVALID_REQUEST
;
3366 ret
= _gnutls_x509_crt_get_mpis (crt
, ¶ms
);
3375 ret
= _gnutls_mpi_dprint_lz (params
.params
[0], p
);
3383 ret
= _gnutls_mpi_dprint_lz (params
.params
[1], q
);
3387 _gnutls_free_datum (p
);
3393 ret
= _gnutls_mpi_dprint_lz (params
.params
[2], g
);
3397 _gnutls_free_datum (p
);
3398 _gnutls_free_datum (q
);
3404 ret
= _gnutls_mpi_dprint_lz (params
.params
[3], y
);
3408 _gnutls_free_datum (p
);
3409 _gnutls_free_datum (g
);
3410 _gnutls_free_datum (q
);
3417 gnutls_pk_params_release(¶ms
);
3423 * gnutls_x509_crt_list_import2:
3424 * @certs: The structures to store the parsed certificate. Must not be initialized.
3425 * @size: It will contain the size of the list.
3426 * @data: The PEM encoded certificate.
3427 * @format: One of DER or PEM.
3428 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
3430 * This function will convert the given PEM encoded certificate list
3431 * to the native gnutls_x509_crt_t format. The output will be stored
3432 * in @certs which will be initialized.
3434 * If the Certificate is PEM encoded it should have a header of "X509
3435 * CERTIFICATE", or "CERTIFICATE".
3437 * Returns: the number of certificates read or a negative error value.
3442 gnutls_x509_crt_list_import2 (gnutls_x509_crt_t
** certs
,
3443 unsigned int * size
,
3444 const gnutls_datum_t
* data
,
3445 gnutls_x509_crt_fmt_t format
, unsigned int flags
)
3447 unsigned int init
= 1024;
3450 *certs
= gnutls_malloc(sizeof(gnutls_x509_crt_t
)*init
);
3454 return GNUTLS_E_MEMORY_ERROR
;
3457 ret
= gnutls_x509_crt_list_import(*certs
, &init
, data
, format
, GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED
);
3458 if (ret
== GNUTLS_E_SHORT_MEMORY_BUFFER
)
3460 *certs
= gnutls_realloc_fast(*certs
, sizeof(gnutls_x509_crt_t
)*init
);
3464 return GNUTLS_E_MEMORY_ERROR
;
3467 ret
= gnutls_x509_crt_list_import(*certs
, &init
, data
, format
, flags
);
3472 gnutls_free(*certs
);
3481 static int check_if_sorted(gnutls_x509_crt_t
* crt
, int nr
)
3483 char prev_dn
[MAX_DN
];
3485 size_t prev_dn_size
, dn_size
;
3488 /* check if the X.509 list is ordered */
3496 dn_size
= sizeof(dn
);
3497 ret
= gnutls_x509_crt_get_dn(crt
[i
], dn
, &dn_size
);
3500 ret
= gnutls_assert_val(ret
);
3504 if (dn_size
!= prev_dn_size
|| memcmp(dn
, prev_dn
, dn_size
) != 0)
3506 ret
= gnutls_assert_val(GNUTLS_E_CERTIFICATE_LIST_UNSORTED
);
3511 prev_dn_size
= sizeof(prev_dn
);
3512 ret
= gnutls_x509_crt_get_issuer_dn(crt
[i
], prev_dn
, &prev_dn_size
);
3515 ret
= gnutls_assert_val(ret
);
3529 * gnutls_x509_crt_list_import:
3530 * @certs: The structures to store the parsed certificate. Must not be initialized.
3531 * @cert_max: Initially must hold the maximum number of certs. It will be updated with the number of certs available.
3532 * @data: The PEM encoded certificate.
3533 * @format: One of DER or PEM.
3534 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
3536 * This function will convert the given PEM encoded certificate list
3537 * to the native gnutls_x509_crt_t format. The output will be stored
3538 * in @certs. They will be automatically initialized.
3540 * The flag %GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED will cause
3541 * import to fail if the certificates in the provided buffer are more
3542 * than the available structures. The %GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED
3543 * flag will cause the function to fail if the provided list is not
3544 * sorted from subject to issuer.
3546 * If the Certificate is PEM encoded it should have a header of "X509
3547 * CERTIFICATE", or "CERTIFICATE".
3549 * Returns: the number of certificates read or a negative error value.
3552 gnutls_x509_crt_list_import (gnutls_x509_crt_t
* certs
,
3553 unsigned int *cert_max
,
3554 const gnutls_datum_t
* data
,
3555 gnutls_x509_crt_fmt_t format
, unsigned int flags
)
3560 int ret
, nocopy
= 0;
3561 unsigned int count
= 0, j
;
3563 if (format
== GNUTLS_X509_FMT_DER
)
3568 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
3571 count
= 1; /* import only the first one */
3573 ret
= gnutls_x509_crt_init (&certs
[0]);
3580 ret
= gnutls_x509_crt_import (certs
[0], data
, format
);
3591 /* move to the certificate
3593 ptr
= memmem (data
->data
, data
->size
,
3594 PEM_CERT_SEP
, sizeof (PEM_CERT_SEP
) - 1);
3596 ptr
= memmem (data
->data
, data
->size
,
3597 PEM_CERT_SEP2
, sizeof (PEM_CERT_SEP2
) - 1);
3600 return gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_FOUND
);
3606 if (count
>= *cert_max
)
3608 if (!(flags
& GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED
))
3616 ret
= gnutls_x509_crt_init (&certs
[count
]);
3623 tmp
.data
= (void *) ptr
;
3624 tmp
.size
= data
->size
- (ptr
- (char *) data
->data
);
3627 gnutls_x509_crt_import (certs
[count
], &tmp
, GNUTLS_X509_FMT_PEM
);
3635 /* now we move ptr after the pem header
3638 /* find the next certificate (if any)
3640 size
= data
->size
- (ptr
- (char *) data
->data
);
3646 ptr2
= memmem (ptr
, size
, PEM_CERT_SEP
, sizeof (PEM_CERT_SEP
) - 1);
3648 ptr2
= memmem (ptr
, size
, PEM_CERT_SEP2
,
3649 sizeof (PEM_CERT_SEP2
) - 1);
3658 while (ptr
!= NULL
);
3662 if (flags
& GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED
)
3664 ret
= check_if_sorted(certs
, *cert_max
);
3675 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
3678 for (j
= 0; j
< count
; j
++)
3679 gnutls_x509_crt_deinit (certs
[j
]);
3684 * gnutls_x509_crt_get_subject_unique_id:
3685 * @crt: Holds the certificate
3686 * @buf: user allocated memory buffer, will hold the unique id
3687 * @buf_size: size of user allocated memory buffer (on input), will hold
3688 * actual size of the unique ID on return.
3690 * This function will extract the subjectUniqueID value (if present) for
3691 * the given certificate.
3693 * If the user allocated memory buffer is not large enough to hold the
3694 * full subjectUniqueID, then a GNUTLS_E_SHORT_MEMORY_BUFFER error will be
3695 * returned, and buf_size will be set to the actual length.
3697 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3700 gnutls_x509_crt_get_subject_unique_id (gnutls_x509_crt_t crt
, char *buf
,
3704 gnutls_datum_t datum
= { NULL
, 0 };
3707 _gnutls_x509_read_string (crt
->cert
, "tbsCertificate.subjectUniqueID",
3708 &datum
, RV_BIT_STRING
);
3710 if (datum
.size
> *buf_size
)
3711 { /* then we're not going to fit */
3712 *buf_size
= datum
.size
;
3714 result
= GNUTLS_E_SHORT_MEMORY_BUFFER
;
3718 *buf_size
= datum
.size
;
3719 memcpy (buf
, datum
.data
, datum
.size
);
3722 _gnutls_free_datum (&datum
);
3728 * gnutls_x509_crt_get_issuer_unique_id:
3729 * @crt: Holds the certificate
3730 * @buf: user allocated memory buffer, will hold the unique id
3731 * @buf_size: size of user allocated memory buffer (on input), will hold
3732 * actual size of the unique ID on return.
3734 * This function will extract the issuerUniqueID value (if present) for
3735 * the given certificate.
3737 * If the user allocated memory buffer is not large enough to hold the
3738 * full subjectUniqueID, then a GNUTLS_E_SHORT_MEMORY_BUFFER error will be
3739 * returned, and buf_size will be set to the actual length.
3741 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3746 gnutls_x509_crt_get_issuer_unique_id (gnutls_x509_crt_t crt
, char *buf
,
3750 gnutls_datum_t datum
= { NULL
, 0 };
3753 _gnutls_x509_read_string (crt
->cert
, "tbsCertificate.issuerUniqueID",
3754 &datum
, RV_BIT_STRING
);
3756 if (datum
.size
> *buf_size
)
3757 { /* then we're not going to fit */
3758 *buf_size
= datum
.size
;
3760 result
= GNUTLS_E_SHORT_MEMORY_BUFFER
;
3764 *buf_size
= datum
.size
;
3765 memcpy (buf
, datum
.data
, datum
.size
);
3768 _gnutls_free_datum (&datum
);
3774 _gnutls_parse_aia (ASN1_TYPE src
,
3777 gnutls_datum_t
* data
)
3780 char nptr
[ASN1_MAX_NAME_SIZE
];
3783 const char *oid
= NULL
;
3785 seq
++; /* 0->1, 1->2 etc */
3788 case GNUTLS_IA_ACCESSMETHOD_OID
:
3789 snprintf (nptr
, sizeof (nptr
), "?%u.accessMethod", seq
);
3792 case GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE
:
3793 snprintf (nptr
, sizeof (nptr
), "?%u.accessLocation", seq
);
3796 case GNUTLS_IA_CAISSUERS_URI
:
3797 oid
= GNUTLS_OID_AD_CAISSUERS
;
3800 case GNUTLS_IA_OCSP_URI
:
3802 oid
= GNUTLS_OID_AD_OCSP
;
3805 snprintf (nptr
, sizeof (nptr
), "?%u.accessMethod", seq
);
3806 len
= sizeof (tmpoid
);
3807 result
= asn1_read_value (src
, nptr
, tmpoid
, &len
);
3809 if (result
== ASN1_VALUE_NOT_FOUND
|| result
== ASN1_ELEMENT_NOT_FOUND
)
3810 return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
);
3812 if (result
!= ASN1_SUCCESS
)
3815 return _gnutls_asn2err (result
);
3817 if ((unsigned)len
!= strlen (oid
) + 1 || memcmp (tmpoid
, oid
, len
) != 0)
3818 return gnutls_assert_val(GNUTLS_E_UNKNOWN_ALGORITHM
);
3823 snprintf (nptr
, sizeof (nptr
),
3824 "?%u.accessLocation.uniformResourceIdentifier", seq
);
3828 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST
);
3832 result
= asn1_read_value (src
, nptr
, NULL
, &len
);
3833 if (result
== ASN1_VALUE_NOT_FOUND
|| result
== ASN1_ELEMENT_NOT_FOUND
)
3834 return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
);
3836 if (result
!= ASN1_MEM_ERROR
)
3839 return _gnutls_asn2err (result
);
3844 d
.data
= gnutls_malloc (d
.size
);
3846 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR
);
3848 result
= asn1_read_value (src
, nptr
, d
.data
, &len
);
3849 if (result
!= ASN1_SUCCESS
)
3852 gnutls_free (d
.data
);
3853 return _gnutls_asn2err (result
);
3858 data
->data
= d
.data
;
3859 data
->size
= d
.size
;
3862 gnutls_free (d
.data
);
3868 * gnutls_x509_crt_get_authority_info_access:
3869 * @crt: Holds the certificate
3870 * @seq: specifies the sequence number of the access descriptor (0 for the first one, 1 for the second etc.)
3871 * @what: what data to get, a #gnutls_info_access_what_t type.
3872 * @data: output data to be freed with gnutls_free().
3873 * @critical: pointer to output integer that is set to non-0 if the extension is marked as critical (may be %NULL)
3875 * This function extracts the Authority Information Access (AIA)
3876 * extension, see RFC 5280 section 4.2.2.1 for more information. The
3877 * AIA extension holds a sequence of AccessDescription (AD) data:
3879 * <informalexample><programlisting>
3880 * AuthorityInfoAccessSyntax ::=
3881 * SEQUENCE SIZE (1..MAX) OF AccessDescription
3883 * AccessDescription ::= SEQUENCE {
3884 * accessMethod OBJECT IDENTIFIER,
3885 * accessLocation GeneralName }
3886 * </programlisting></informalexample>
3888 * The @seq input parameter is used to indicate which member of the
3889 * sequence the caller is interested in. The first member is 0, the
3890 * second member 1 and so on. When the @seq value is out of bounds,
3891 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
3893 * The type of data returned in @data is specified via @what which
3894 * should be #gnutls_info_access_what_t values.
3896 * If @what is %GNUTLS_IA_ACCESSMETHOD_OID then @data will hold the
3897 * accessMethod OID (e.g., "1.3.6.1.5.5.7.48.1").
3899 * If @what is %GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE, @data will
3900 * hold the accessLocation GeneralName type (e.g.,
3901 * "uniformResourceIdentifier").
3903 * If @what is %GNUTLS_IA_URI, @data will hold the accessLocation URI
3904 * data. Requesting this @what value leads to an error if the
3905 * accessLocation is not of the "uniformResourceIdentifier" type.
3907 * If @what is %GNUTLS_IA_OCSP_URI, @data will hold the OCSP URI.
3908 * Requesting this @what value leads to an error if the accessMethod
3909 * is not 1.3.6.1.5.5.7.48.1 aka OSCP, or if accessLocation is not of
3910 * the "uniformResourceIdentifier" type.
3912 * If @what is %GNUTLS_IA_CAISSUERS_URI, @data will hold the caIssuers
3913 * URI. Requesting this @what value leads to an error if the
3914 * accessMethod is not 1.3.6.1.5.5.7.48.2 aka caIssuers, or if
3915 * accessLocation is not of the "uniformResourceIdentifier" type.
3917 * More @what values may be allocated in the future as needed.
3919 * If @data is NULL, the function does the same without storing the
3920 * output data, that is, it will set @critical and do error checking
3923 * The value of the critical flag is returned in *@critical. Supply a
3924 * NULL @critical if you want the function to make sure the extension
3925 * is non-critical, as required by RFC 5280.
3927 * Returns: %GNUTLS_E_SUCCESS on success, %GNUTLS_E_INVALID_REQUEST on
3928 * invalid @crt, %GNUTLS_E_CONSTRAINT_ERROR if the extension is
3929 * incorrectly marked as critical (use a non-NULL @critical to
3930 * override), %GNUTLS_E_UNKNOWN_ALGORITHM if the requested OID does
3931 * not match (e.g., when using %GNUTLS_IA_OCSP_URI), otherwise a
3932 * negative error code.
3937 gnutls_x509_crt_get_authority_info_access (gnutls_x509_crt_t crt
,
3940 gnutls_datum_t
* data
,
3941 unsigned int *critical
)
3945 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
3950 return GNUTLS_E_INVALID_REQUEST
;
3953 if ((ret
= _gnutls_x509_crt_get_extension (crt
, GNUTLS_OID_AIA
, 0, &aia
,
3957 if (aia
.size
== 0 || aia
.data
== NULL
)
3960 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
3963 if (critical
&& *critical
)
3964 return GNUTLS_E_CONSTRAINT_ERROR
;
3966 ret
= asn1_create_element (_gnutls_get_pkix (),
3967 "PKIX1.AuthorityInfoAccessSyntax", &c2
);
3968 if (ret
!= ASN1_SUCCESS
)
3971 _gnutls_free_datum (&aia
);
3972 return _gnutls_asn2err (ret
);
3975 ret
= asn1_der_decoding (&c2
, aia
.data
, aia
.size
, NULL
);
3976 /* asn1_print_structure (stdout, c2, "", ASN1_PRINT_ALL); */
3977 _gnutls_free_datum (&aia
);
3978 if (ret
!= ASN1_SUCCESS
)
3981 asn1_delete_structure (&c2
);
3982 return _gnutls_asn2err (ret
);
3985 ret
= _gnutls_parse_aia (c2
, seq
, what
, data
);
3987 asn1_delete_structure (&c2
);
3995 * gnutls_x509_crt_set_pin_function:
3996 * @crt: The certificate structure
3998 * @userdata: data associated with the callback
4000 * This function will set a callback function to be used when
4001 * it is required to access a protected object. This function overrides
4002 * the global function set using gnutls_pkcs11_set_pin_function().
4004 * Note that this callback is currently used only during the import
4005 * of a PKCS #11 certificate with gnutls_x509_crt_import_pkcs11_url().
4010 void gnutls_x509_crt_set_pin_function (gnutls_x509_crt_t crt
,
4011 gnutls_pin_callback_t fn
, void *userdata
)
4014 crt
->pin
.data
= userdata
;