Use the new asn1_read_node_value()
[gnutls.git] / lib / x509 / x509.c
blob498eb05d5b2da9bbb3a4a6d1ccc8a1fd1597accf
1 /*
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>
29 #include <common.h>
30 #include <gnutls_x509.h>
31 #include <x509_b64.h>
32 #include <x509_int.h>
33 #include <libtasn1.h>
34 #include <gnutls_pk.h>
36 /**
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.
44 **/
45 int
46 gnutls_x509_crt_init (gnutls_x509_crt_t * cert)
48 gnutls_x509_crt_t tmp = gnutls_calloc (1, sizeof (gnutls_x509_crt_int));
49 int result;
51 if (!tmp)
52 return GNUTLS_E_MEMORY_ERROR;
54 result = asn1_create_element (_gnutls_get_pkix (),
55 "PKIX1.Certificate", &tmp->cert);
56 if (result != ASN1_SUCCESS)
58 gnutls_assert ();
59 gnutls_free (tmp);
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. */
66 *cert = tmp;
68 return 0; /* success */
71 /*-
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.
80 -*/
81 int
82 _gnutls_x509_crt_cpy (gnutls_x509_crt_t dest, gnutls_x509_crt_t src)
84 int ret;
85 size_t der_size=0;
86 uint8_t *der;
87 gnutls_datum_t tmp;
89 ret = gnutls_x509_crt_export (src, GNUTLS_X509_FMT_DER, NULL, &der_size);
90 if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
92 gnutls_assert ();
93 return ret;
96 der = gnutls_malloc (der_size);
97 if (der == NULL)
99 gnutls_assert ();
100 return GNUTLS_E_MEMORY_ERROR;
103 ret = gnutls_x509_crt_export (src, GNUTLS_X509_FMT_DER, der, &der_size);
104 if (ret < 0)
106 gnutls_assert ();
107 gnutls_free (der);
108 return ret;
111 tmp.data = der;
112 tmp.size = der_size;
113 ret = gnutls_x509_crt_import (dest, &tmp, GNUTLS_X509_FMT_DER);
115 gnutls_free (der);
117 if (ret < 0)
119 gnutls_assert ();
120 return ret;
123 return 0;
127 * gnutls_x509_crt_deinit:
128 * @cert: The structure to be deinitialized
130 * This function will deinitialize a certificate structure.
132 void
133 gnutls_x509_crt_deinit (gnutls_x509_crt_t cert)
135 if (!cert)
136 return;
138 if (cert->cert)
139 asn1_delete_structure (&cert->cert);
141 gnutls_free (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
152 * in @cert.
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;
168 if (cert == NULL)
170 gnutls_assert ();
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 uint8_t *out;
183 /* Try the first header */
184 result =
185 _gnutls_fbase64_decode (PEM_X509_CERT2, data->data, data->size, &out);
187 if (result <= 0)
189 /* try for the second header */
190 result =
191 _gnutls_fbase64_decode (PEM_X509_CERT, data->data,
192 data->size, &out);
194 if (result <= 0)
196 if (result == 0)
197 result = GNUTLS_E_INTERNAL_ERROR;
198 gnutls_assert ();
199 return result;
203 _data.data = out;
204 _data.size = result;
206 need_free = 1;
209 if (cert->cert)
211 /* Any earlier asn1_der_decoding will modify the ASN.1
212 structure, so we need to replace it with a fresh
213 structure. */
214 asn1_delete_structure (&cert->cert);
216 result = asn1_create_element (_gnutls_get_pkix (),
217 "PKIX1.Certificate", &cert->cert);
218 if (result != ASN1_SUCCESS)
220 result = _gnutls_asn2err (result);
221 gnutls_assert ();
222 goto cleanup;
226 result = asn1_der_decoding (&cert->cert, _data.data, _data.size, NULL);
227 if (result != ASN1_SUCCESS)
229 result = _gnutls_asn2err (result);
230 gnutls_assert ();
231 goto cleanup;
234 /* Since we do not want to disable any extension
236 cert->use_extensions = 1;
237 if (need_free)
238 _gnutls_free_datum (&_data);
240 return 0;
242 cleanup:
243 if (need_free)
244 _gnutls_free_datum (&_data);
245 return result;
250 * gnutls_x509_crt_get_issuer_dn:
251 * @cert: should contain a #gnutls_x509_crt_t structure
252 * @buf: a pointer to a structure to hold the name (may be null)
253 * @buf_size: initially holds the size of @buf
255 * This function will copy the name of the Certificate issuer in the
256 * provided buffer. The name will be in the form
257 * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC4514. The output string
258 * will be ASCII or UTF-8 encoded, depending on the certificate data.
260 * If @buf is null then only the size will be filled.
262 * Returns: GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
263 * long enough, and in that case the @buf_size will be updated with
264 * the required size. On success 0 is returned.
267 gnutls_x509_crt_get_issuer_dn (gnutls_x509_crt_t cert, char *buf,
268 size_t * buf_size)
270 if (cert == NULL)
272 gnutls_assert ();
273 return GNUTLS_E_INVALID_REQUEST;
276 return _gnutls_x509_parse_dn (cert->cert,
277 "tbsCertificate.issuer.rdnSequence", buf,
278 buf_size);
282 * gnutls_x509_crt_get_issuer_dn_by_oid:
283 * @cert: should contain a #gnutls_x509_crt_t structure
284 * @oid: holds an Object Identified in null terminated string
285 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use (0) to get the first one.
286 * @raw_flag: If non (0) returns the raw DER data of the DN part.
287 * @buf: a pointer to a structure to hold the name (may be null)
288 * @buf_size: initially holds the size of @buf
290 * This function will extract the part of the name of the Certificate
291 * issuer specified by the given OID. The output, if the raw flag is not
292 * used, will be encoded as described in RFC4514. Thus a string that is
293 * ASCII or UTF-8 encoded, depending on the certificate data.
295 * Some helper macros with popular OIDs can be found in gnutls/x509.h
296 * If raw flag is (0), this function will only return known OIDs as
297 * text. Other OIDs will be DER encoded, as described in RFC4514 --
298 * in hex format with a '#' prefix. You can check about known OIDs
299 * using gnutls_x509_dn_oid_known().
301 * If @buf is null then only the size will be filled. If the @raw_flag
302 * is not specified the output is always null terminated, although the
303 * @buf_size will not include the null character.
305 * Returns: GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
306 * long enough, and in that case the @buf_size will be updated
307 * with the required size. On success 0 is returned.
310 gnutls_x509_crt_get_issuer_dn_by_oid (gnutls_x509_crt_t cert,
311 const char *oid, int indx,
312 unsigned int raw_flag, void *buf,
313 size_t * buf_size)
315 if (cert == NULL)
317 gnutls_assert ();
318 return GNUTLS_E_INVALID_REQUEST;
321 return _gnutls_x509_parse_dn_oid (cert->cert,
322 "tbsCertificate.issuer.rdnSequence",
323 oid, indx, raw_flag, buf, buf_size);
327 * gnutls_x509_crt_get_issuer_dn_oid:
328 * @cert: should contain a #gnutls_x509_crt_t structure
329 * @indx: This specifies which OID to return. Use (0) to get the first one.
330 * @oid: a pointer to a buffer to hold the OID (may be null)
331 * @oid_size: initially holds the size of @oid
333 * This function will extract the OIDs of the name of the Certificate
334 * issuer specified by the given index.
336 * If @oid is null then only the size will be filled. The @oid
337 * returned will be null terminated, although @oid_size will not
338 * account for the trailing null.
340 * Returns: GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
341 * long enough, and in that case the @oid_size will be updated
342 * with the required size. On success 0 is returned.
345 gnutls_x509_crt_get_issuer_dn_oid (gnutls_x509_crt_t cert,
346 int indx, void *oid, size_t * oid_size)
348 if (cert == NULL)
350 gnutls_assert ();
351 return GNUTLS_E_INVALID_REQUEST;
354 return _gnutls_x509_get_dn_oid (cert->cert,
355 "tbsCertificate.issuer.rdnSequence",
356 indx, oid, oid_size);
360 * gnutls_x509_crt_get_dn:
361 * @cert: should contain a #gnutls_x509_crt_t structure
362 * @buf: a pointer to a structure to hold the name (may be null)
363 * @buf_size: initially holds the size of @buf
365 * This function will copy the name of the Certificate in the provided
366 * buffer. The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
367 * described in RFC4514. The output string will be ASCII or UTF-8
368 * encoded, depending on the certificate data.
370 * If @buf is null then only the size will be filled.
372 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
373 * long enough, and in that case the @buf_size will be updated
374 * with the required size. On success 0 is returned.
377 gnutls_x509_crt_get_dn (gnutls_x509_crt_t cert, char *buf,
378 size_t * buf_size)
380 if (cert == NULL)
382 gnutls_assert ();
383 return GNUTLS_E_INVALID_REQUEST;
386 return _gnutls_x509_parse_dn (cert->cert,
387 "tbsCertificate.subject.rdnSequence", buf,
388 buf_size);
392 * gnutls_x509_crt_get_dn_by_oid:
393 * @cert: should contain a #gnutls_x509_crt_t structure
394 * @oid: holds an Object Identified in null terminated string
395 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use (0) to get the first one.
396 * @raw_flag: If non (0) returns the raw DER data of the DN part.
397 * @buf: a pointer where the DN part will be copied (may be null).
398 * @buf_size: initially holds the size of @buf
400 * This function will extract the part of the name of the Certificate
401 * subject specified by the given OID. The output, if the raw flag is
402 * not used, will be encoded as described in RFC4514. Thus a string
403 * that is ASCII or UTF-8 encoded, depending on the certificate data.
405 * Some helper macros with popular OIDs can be found in gnutls/x509.h
406 * If raw flag is (0), this function will only return known OIDs as
407 * text. Other OIDs will be DER encoded, as described in RFC4514 --
408 * in hex format with a '#' prefix. You can check about known OIDs
409 * using gnutls_x509_dn_oid_known().
411 * If @buf is null then only the size will be filled. If the @raw_flag
412 * is not specified the output is always null terminated, although the
413 * @buf_size will not include the null character.
415 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
416 * not long enough, and in that case the *buf_size will be updated
417 * with the required size. On success 0 is returned.
420 gnutls_x509_crt_get_dn_by_oid (gnutls_x509_crt_t cert, const char *oid,
421 int indx, unsigned int raw_flag,
422 void *buf, size_t * buf_size)
424 if (cert == NULL)
426 gnutls_assert ();
427 return GNUTLS_E_INVALID_REQUEST;
430 return _gnutls_x509_parse_dn_oid (cert->cert,
431 "tbsCertificate.subject.rdnSequence",
432 oid, indx, raw_flag, buf, buf_size);
436 * gnutls_x509_crt_get_dn_oid:
437 * @cert: should contain a #gnutls_x509_crt_t structure
438 * @indx: This specifies which OID to return. Use (0) to get the first one.
439 * @oid: a pointer to a buffer to hold the OID (may be null)
440 * @oid_size: initially holds the size of @oid
442 * This function will extract the OIDs of the name of the Certificate
443 * subject specified by the given index.
445 * If @oid is null then only the size will be filled. The @oid
446 * returned will be null terminated, although @oid_size will not
447 * account for the trailing null.
449 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
450 * not long enough, and in that case the @oid_size will be updated
451 * with the required size. On success 0 is returned.
454 gnutls_x509_crt_get_dn_oid (gnutls_x509_crt_t cert,
455 int indx, void *oid, size_t * oid_size)
457 if (cert == NULL)
459 gnutls_assert ();
460 return GNUTLS_E_INVALID_REQUEST;
463 return _gnutls_x509_get_dn_oid (cert->cert,
464 "tbsCertificate.subject.rdnSequence",
465 indx, oid, oid_size);
469 * gnutls_x509_crt_get_signature_algorithm:
470 * @cert: should contain a #gnutls_x509_crt_t structure
472 * This function will return a value of the #gnutls_sign_algorithm_t
473 * enumeration that is the signature algorithm that has been used to
474 * sign this certificate.
476 * Returns: a #gnutls_sign_algorithm_t value, or a negative error code on
477 * error.
480 gnutls_x509_crt_get_signature_algorithm (gnutls_x509_crt_t cert)
482 return _gnutls_x509_get_signature_algorithm(cert->cert, "signatureAlgorithm.algorithm");
486 * gnutls_x509_crt_get_signature:
487 * @cert: should contain a #gnutls_x509_crt_t structure
488 * @sig: a pointer where the signature part will be copied (may be null).
489 * @sizeof_sig: initially holds the size of @sig
491 * This function will extract the signature field of a certificate.
493 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
494 * negative error value. and a negative error code on error.
497 gnutls_x509_crt_get_signature (gnutls_x509_crt_t cert,
498 char *sig, size_t * sizeof_sig)
500 int result;
501 unsigned int bits;
502 int len;
504 if (cert == NULL)
506 gnutls_assert ();
507 return GNUTLS_E_INVALID_REQUEST;
510 len = 0;
511 result = asn1_read_value (cert->cert, "signature", NULL, &len);
512 if (result != ASN1_MEM_ERROR)
514 gnutls_assert ();
515 return _gnutls_asn2err (result);
518 bits = len;
519 if (bits % 8 != 0)
521 gnutls_assert ();
522 return GNUTLS_E_CERTIFICATE_ERROR;
525 len = bits / 8;
527 if (*sizeof_sig < (unsigned int) len)
529 *sizeof_sig = len;
530 return GNUTLS_E_SHORT_MEMORY_BUFFER;
533 result = asn1_read_value (cert->cert, "signature", sig, &len);
534 if (result != ASN1_SUCCESS)
536 gnutls_assert ();
537 return _gnutls_asn2err (result);
540 return 0;
544 * gnutls_x509_crt_get_version:
545 * @cert: should contain a #gnutls_x509_crt_t structure
547 * This function will return the version of the specified Certificate.
549 * Returns: version of certificate, or a negative error code on error.
552 gnutls_x509_crt_get_version (gnutls_x509_crt_t cert)
554 uint8_t version[8];
555 int len, result;
557 if (cert == NULL)
559 gnutls_assert ();
560 return GNUTLS_E_INVALID_REQUEST;
563 len = sizeof (version);
564 if ((result =
565 asn1_read_value (cert->cert, "tbsCertificate.version", version,
566 &len)) != ASN1_SUCCESS)
569 if (result == ASN1_ELEMENT_NOT_FOUND)
570 return 1; /* the DEFAULT version */
571 gnutls_assert ();
572 return _gnutls_asn2err (result);
575 return (int) version[0] + 1;
579 * gnutls_x509_crt_get_activation_time:
580 * @cert: should contain a #gnutls_x509_crt_t structure
582 * This function will return the time this Certificate was or will be
583 * activated.
585 * Returns: activation time, or (time_t)-1 on error.
587 time_t
588 gnutls_x509_crt_get_activation_time (gnutls_x509_crt_t cert)
590 if (cert == NULL)
592 gnutls_assert ();
593 return (time_t) - 1;
596 return _gnutls_x509_get_time (cert->cert,
597 "tbsCertificate.validity.notBefore", 0);
601 * gnutls_x509_crt_get_expiration_time:
602 * @cert: should contain a #gnutls_x509_crt_t structure
604 * This function will return the time this Certificate was or will be
605 * expired.
607 * Returns: expiration time, or (time_t)-1 on error.
609 time_t
610 gnutls_x509_crt_get_expiration_time (gnutls_x509_crt_t cert)
612 if (cert == NULL)
614 gnutls_assert ();
615 return (time_t) - 1;
618 return _gnutls_x509_get_time (cert->cert,
619 "tbsCertificate.validity.notAfter", 0);
623 * gnutls_x509_crt_get_private_key_usage_period:
624 * @cert: should contain a #gnutls_x509_crt_t structure
625 * @activation: The activation time
626 * @expiration: The expiration time
627 * @critical: the extension status
629 * This function will return the expiration and activation
630 * times of the private key of the certificate. It relies on
631 * the PKIX extension 2.5.29.16 being present.
633 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
634 * if the extension is not present, otherwise a negative error value.
637 gnutls_x509_crt_get_private_key_usage_period (gnutls_x509_crt_t cert, time_t* activation, time_t* expiration,
638 unsigned int *critical)
640 int result, ret;
641 gnutls_datum_t der = {NULL, 0};
642 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
644 if (cert == NULL)
646 gnutls_assert ();
647 return GNUTLS_E_INVALID_REQUEST;
650 ret =
651 _gnutls_x509_crt_get_extension (cert, "2.5.29.16", 0, &der,
652 critical);
653 if (ret < 0)
654 return gnutls_assert_val(ret);
656 if (der.size == 0 || der.data == NULL)
657 return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
659 result = asn1_create_element
660 (_gnutls_get_pkix (), "PKIX1.PrivateKeyUsagePeriod", &c2);
661 if (result != ASN1_SUCCESS)
663 gnutls_assert ();
664 ret = _gnutls_asn2err (result);
665 goto cleanup;
668 result = asn1_der_decoding (&c2, der.data, der.size, NULL);
669 if (result != ASN1_SUCCESS)
671 gnutls_assert ();
672 ret = _gnutls_asn2err (result);
673 goto cleanup;
676 if (activation)
677 *activation = _gnutls_x509_get_time (c2,
678 "notBefore", 1);
680 if (expiration)
681 *expiration = _gnutls_x509_get_time (c2,
682 "notAfter", 1);
684 ret = 0;
686 cleanup:
687 _gnutls_free_datum(&der);
688 asn1_delete_structure (&c2);
690 return ret;
695 * gnutls_x509_crt_get_serial:
696 * @cert: should contain a #gnutls_x509_crt_t structure
697 * @result: The place where the serial number will be copied
698 * @result_size: Holds the size of the result field.
700 * This function will return the X.509 certificate's serial number.
701 * This is obtained by the X509 Certificate serialNumber field. Serial
702 * is not always a 32 or 64bit number. Some CAs use large serial
703 * numbers, thus it may be wise to handle it as something uint8_t.
705 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
706 * negative error value.
709 gnutls_x509_crt_get_serial (gnutls_x509_crt_t cert, void *result,
710 size_t * result_size)
712 int ret, len;
714 if (cert == NULL)
716 gnutls_assert ();
717 return GNUTLS_E_INVALID_REQUEST;
720 len = *result_size;
721 ret =
722 asn1_read_value (cert->cert, "tbsCertificate.serialNumber", result, &len);
723 *result_size = len;
725 if (ret != ASN1_SUCCESS)
727 gnutls_assert ();
728 return _gnutls_asn2err (ret);
731 return 0;
735 * gnutls_x509_crt_get_subject_key_id:
736 * @cert: should contain a #gnutls_x509_crt_t structure
737 * @ret: The place where the identifier will be copied
738 * @ret_size: Holds the size of the result field.
739 * @critical: will be non (0) if the extension is marked as critical (may be null)
741 * This function will return the X.509v3 certificate's subject key
742 * identifier. This is obtained by the X.509 Subject Key identifier
743 * extension field (2.5.29.14).
745 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
746 * if the extension is not present, otherwise a negative error value.
749 gnutls_x509_crt_get_subject_key_id (gnutls_x509_crt_t cert, void *ret,
750 size_t * ret_size, unsigned int *critical)
752 int result, len;
753 gnutls_datum_t id;
754 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
756 if (cert == NULL)
758 gnutls_assert ();
759 return GNUTLS_E_INVALID_REQUEST;
763 if (ret)
764 memset (ret, 0, *ret_size);
765 else
766 *ret_size = 0;
768 if ((result =
769 _gnutls_x509_crt_get_extension (cert, "2.5.29.14", 0, &id,
770 critical)) < 0)
772 return result;
775 if (id.size == 0 || id.data == NULL)
777 gnutls_assert ();
778 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
781 result = asn1_create_element
782 (_gnutls_get_pkix (), "PKIX1.SubjectKeyIdentifier", &c2);
783 if (result != ASN1_SUCCESS)
785 gnutls_assert ();
786 _gnutls_free_datum (&id);
787 return _gnutls_asn2err (result);
790 result = asn1_der_decoding (&c2, id.data, id.size, NULL);
791 _gnutls_free_datum (&id);
793 if (result != ASN1_SUCCESS)
795 gnutls_assert ();
796 asn1_delete_structure (&c2);
797 return _gnutls_asn2err (result);
800 len = *ret_size;
801 result = asn1_read_value (c2, "", ret, &len);
803 *ret_size = len;
804 asn1_delete_structure (&c2);
806 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
808 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
811 if (result != ASN1_SUCCESS)
813 if (result != ASN1_MEM_ERROR)
814 gnutls_assert ();
815 return _gnutls_asn2err (result);
818 return 0;
821 static int
822 _get_authority_key_id (gnutls_x509_crt_t cert, ASN1_TYPE *c2,
823 unsigned int *critical)
825 int ret;
826 gnutls_datum_t id;
828 *c2 = ASN1_TYPE_EMPTY;
830 if (cert == NULL)
832 gnutls_assert ();
833 return GNUTLS_E_INVALID_REQUEST;
836 if ((ret =
837 _gnutls_x509_crt_get_extension (cert, "2.5.29.35", 0, &id,
838 critical)) < 0)
840 return gnutls_assert_val(ret);
843 if (id.size == 0 || id.data == NULL)
845 gnutls_assert ();
846 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
849 ret = asn1_create_element
850 (_gnutls_get_pkix (), "PKIX1.AuthorityKeyIdentifier", c2);
851 if (ret != ASN1_SUCCESS)
853 gnutls_assert ();
854 _gnutls_free_datum (&id);
855 return _gnutls_asn2err (ret);
858 ret = asn1_der_decoding (c2, id.data, id.size, NULL);
859 _gnutls_free_datum (&id);
861 if (ret != ASN1_SUCCESS)
863 gnutls_assert ();
864 asn1_delete_structure (c2);
865 return _gnutls_asn2err (ret);
868 return 0;
872 * gnutls_x509_crt_get_authority_key_gn_serial:
873 * @cert: should contain a #gnutls_x509_crt_t structure
874 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
875 * @alt: is the place where the alternative name will be copied to
876 * @alt_size: holds the size of alt.
877 * @alt_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
878 * @serial: buffer to store the serial number (may be null)
879 * @serial_size: Holds the size of the serial field (may be null)
880 * @critical: will be non (0) if the extension is marked as critical (may be null)
882 * This function will return the X.509 authority key
883 * identifier when stored as a general name (authorityCertIssuer)
884 * and serial number.
886 * Because more than one general names might be stored
887 * @seq can be used as a counter to request them all until
888 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
890 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
891 * if the extension is not present, otherwise a negative error value.
893 * Since: 3.0
896 gnutls_x509_crt_get_authority_key_gn_serial (gnutls_x509_crt_t cert, unsigned int seq, void *alt,
897 size_t * alt_size, unsigned int *alt_type,
898 void* serial, size_t *serial_size,
899 unsigned int *critical)
901 int ret, result, len;
902 ASN1_TYPE c2;
904 ret = _get_authority_key_id(cert, &c2, critical);
905 if (ret < 0)
906 return gnutls_assert_val(ret);
908 ret =
909 _gnutls_parse_general_name (c2, "authorityCertIssuer", seq, alt, alt_size, alt_type,
911 if (ret < 0)
913 ret = gnutls_assert_val(ret);
914 goto fail;
917 if (serial)
919 len = *serial_size;
920 result = asn1_read_value (c2, "authorityCertSerialNumber", serial, &len);
922 *serial_size = len;
924 if (result < 0)
926 ret = _gnutls_asn2err(result);
927 goto fail;
932 ret = 0;
934 fail:
935 asn1_delete_structure (&c2);
937 return ret;
941 * gnutls_x509_crt_get_authority_key_id:
942 * @cert: should contain a #gnutls_x509_crt_t structure
943 * @id: The place where the identifier will be copied
944 * @id_size: Holds the size of the id field.
945 * @critical: will be non (0) if the extension is marked as critical (may be null)
947 * This function will return the X.509v3 certificate authority's key
948 * identifier. This is obtained by the X.509 Authority Key
949 * identifier extension field (2.5.29.35). Note that this function
950 * only returns the keyIdentifier field of the extension and
951 * %GNUTLS_E_X509_UNSUPPORTED_EXTENSION, if the extension contains
952 * the name and serial number of the certificate. In that case
953 * gnutls_x509_crt_get_authority_key_gn_serial() may be used.
955 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
956 * if the extension is not present, otherwise a negative error value.
959 gnutls_x509_crt_get_authority_key_id (gnutls_x509_crt_t cert, void *id,
960 size_t * id_size,
961 unsigned int *critical)
963 int ret, result, len;
964 ASN1_TYPE c2;
966 ret = _get_authority_key_id(cert, &c2, critical);
967 if (ret < 0)
968 return gnutls_assert_val(ret);
970 len = *id_size;
971 result = asn1_read_value (c2, "keyIdentifier", id, &len);
973 *id_size = len;
974 asn1_delete_structure (&c2);
976 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
977 return gnutls_assert_val(GNUTLS_E_X509_UNSUPPORTED_EXTENSION);
979 if (result != ASN1_SUCCESS)
981 if (result != ASN1_MEM_ERROR)
982 gnutls_assert ();
983 return _gnutls_asn2err (result);
986 return 0;
990 * gnutls_x509_crt_get_pk_algorithm:
991 * @cert: should contain a #gnutls_x509_crt_t structure
992 * @bits: if bits is non null it will hold the size of the parameters' in bits
994 * This function will return the public key algorithm of an X.509
995 * certificate.
997 * If bits is non null, it should have enough size to hold the parameters
998 * size in bits. For RSA the bits returned is the modulus.
999 * For DSA the bits returned are of the public
1000 * exponent.
1002 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
1003 * success, or a negative error code on error.
1006 gnutls_x509_crt_get_pk_algorithm (gnutls_x509_crt_t cert, unsigned int *bits)
1008 int result;
1010 if (cert == NULL)
1012 gnutls_assert ();
1013 return GNUTLS_E_INVALID_REQUEST;
1016 if (bits)
1017 *bits = 0;
1019 result =
1020 _gnutls_x509_get_pk_algorithm (cert->cert,
1021 "tbsCertificate.subjectPublicKeyInfo",
1022 bits);
1024 if (result < 0)
1026 gnutls_assert ();
1027 return result;
1030 return result;
1034 inline static int
1035 is_type_printable (int type)
1037 if (type == GNUTLS_SAN_DNSNAME || type == GNUTLS_SAN_RFC822NAME ||
1038 type == GNUTLS_SAN_URI)
1039 return 1;
1040 else
1041 return 0;
1044 #define XMPP_OID "1.3.6.1.5.5.7.8.5"
1046 /* returns the type and the name on success.
1047 * Type is also returned as a parameter in case of an error.
1050 _gnutls_parse_general_name (ASN1_TYPE src, const char *src_name,
1051 int seq, void *name, size_t * name_size,
1052 unsigned int *ret_type, int othername_oid)
1054 int len;
1055 char nptr[ASN1_MAX_NAME_SIZE];
1056 int result;
1057 char choice_type[128];
1058 gnutls_x509_subject_alt_name_t type;
1060 seq++; /* 0->1, 1->2 etc */
1062 if (src_name[0] != 0)
1063 snprintf (nptr, sizeof (nptr), "%s.?%u", src_name, seq);
1064 else
1065 snprintf (nptr, sizeof (nptr), "?%u", seq);
1067 len = sizeof (choice_type);
1068 result = asn1_read_value (src, nptr, choice_type, &len);
1070 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
1072 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1075 if (result != ASN1_SUCCESS)
1077 gnutls_assert ();
1078 return _gnutls_asn2err (result);
1082 type = _gnutls_x509_san_find_type (choice_type);
1083 if (type == (gnutls_x509_subject_alt_name_t) - 1)
1085 gnutls_assert ();
1086 return GNUTLS_E_X509_UNKNOWN_SAN;
1089 if (ret_type)
1090 *ret_type = type;
1092 if (type == GNUTLS_SAN_OTHERNAME)
1094 if (othername_oid)
1095 _gnutls_str_cat (nptr, sizeof (nptr), ".otherName.type-id");
1096 else
1097 _gnutls_str_cat (nptr, sizeof (nptr), ".otherName.value");
1099 len = *name_size;
1100 result = asn1_read_value (src, nptr, name, &len);
1101 *name_size = len;
1103 if (result == ASN1_MEM_ERROR)
1104 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1106 if (result != ASN1_SUCCESS)
1108 gnutls_assert ();
1109 return _gnutls_asn2err (result);
1112 if (othername_oid)
1114 if ((unsigned)len > strlen (XMPP_OID) && strcmp (name, XMPP_OID) == 0)
1115 type = GNUTLS_SAN_OTHERNAME_XMPP;
1117 else
1119 char oid[42];
1121 if (src_name[0] != 0)
1122 snprintf (nptr, sizeof (nptr), "%s.?%u.otherName.type-id",
1123 src_name, seq);
1124 else
1125 snprintf (nptr, sizeof (nptr), "?%u.otherName.type-id", seq);
1127 len = sizeof (oid);
1128 result = asn1_read_value (src, nptr, oid, &len);
1129 if (result != ASN1_SUCCESS)
1131 gnutls_assert ();
1132 return _gnutls_asn2err (result);
1135 if ((unsigned)len > strlen (XMPP_OID) && strcmp (oid, XMPP_OID) == 0)
1137 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1138 size_t orig_name_size = *name_size;
1140 result = asn1_create_element
1141 (_gnutls_get_pkix (), "PKIX1.UTF8String", &c2);
1142 if (result != ASN1_SUCCESS)
1144 gnutls_assert ();
1145 return _gnutls_asn2err (result);
1148 result = asn1_der_decoding (&c2, name, *name_size, NULL);
1149 if (result != ASN1_SUCCESS)
1151 gnutls_assert ();
1152 asn1_delete_structure (&c2);
1153 return _gnutls_asn2err (result);
1156 len = *name_size;
1157 result = asn1_read_value (c2, "", name, &len);
1158 if (result != ASN1_SUCCESS)
1160 gnutls_assert ();
1161 asn1_delete_structure (&c2);
1162 *name_size = len + 1;
1163 return _gnutls_asn2err (result);
1165 asn1_delete_structure (&c2);
1167 if ((unsigned)len + 1 > orig_name_size)
1169 gnutls_assert ();
1170 *name_size = len + 1;
1171 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1174 *name_size = len;
1175 /* null terminate it */
1176 ((char *) name)[*name_size] = 0;
1180 else if (type == GNUTLS_SAN_DN)
1182 _gnutls_str_cat (nptr, sizeof (nptr), ".directoryName");
1183 result = _gnutls_x509_parse_dn (src, nptr, name, name_size);
1184 if (result < 0)
1186 gnutls_assert ();
1187 return result;
1190 else if (othername_oid)
1191 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1192 else
1194 size_t orig_name_size = *name_size;
1196 _gnutls_str_cat (nptr, sizeof (nptr), ".");
1197 _gnutls_str_cat (nptr, sizeof (nptr), choice_type);
1199 len = *name_size;
1200 result = asn1_read_value (src, nptr, name, &len);
1201 *name_size = len;
1203 if (result == ASN1_MEM_ERROR)
1205 if (is_type_printable (type))
1206 (*name_size)++;
1207 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1210 if (result != ASN1_SUCCESS)
1212 gnutls_assert ();
1213 return _gnutls_asn2err (result);
1216 if (is_type_printable (type))
1219 if ((unsigned)len + 1 > orig_name_size)
1221 gnutls_assert ();
1222 (*name_size)++;
1223 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1226 /* null terminate it */
1227 ((char *) name)[*name_size] = 0;
1232 return type;
1235 static int
1236 get_alt_name (gnutls_x509_crt_t cert, const char *extension_id,
1237 unsigned int seq, void *alt,
1238 size_t * alt_size, unsigned int *alt_type,
1239 unsigned int *critical, int othername_oid)
1241 int result;
1242 gnutls_datum_t dnsname;
1243 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1245 if (cert == NULL)
1247 gnutls_assert ();
1248 return GNUTLS_E_INVALID_REQUEST;
1251 if (alt)
1252 memset (alt, 0, *alt_size);
1253 else
1254 *alt_size = 0;
1256 if ((result =
1257 _gnutls_x509_crt_get_extension (cert, extension_id, 0, &dnsname,
1258 critical)) < 0)
1260 return result;
1263 if (dnsname.size == 0 || dnsname.data == NULL)
1265 gnutls_assert ();
1266 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1269 if (strcmp ("2.5.29.17", extension_id) == 0)
1270 result = asn1_create_element (_gnutls_get_pkix (),
1271 "PKIX1.SubjectAltName", &c2);
1272 else if (strcmp ("2.5.29.18", extension_id) == 0)
1273 result = asn1_create_element (_gnutls_get_pkix (),
1274 "PKIX1.IssuerAltName", &c2);
1275 else
1277 gnutls_assert ();
1278 return GNUTLS_E_INTERNAL_ERROR;
1281 if (result != ASN1_SUCCESS)
1283 gnutls_assert ();
1284 _gnutls_free_datum (&dnsname);
1285 return _gnutls_asn2err (result);
1288 result = asn1_der_decoding (&c2, dnsname.data, dnsname.size, NULL);
1289 _gnutls_free_datum (&dnsname);
1291 if (result != ASN1_SUCCESS)
1293 gnutls_assert ();
1294 asn1_delete_structure (&c2);
1295 return _gnutls_asn2err (result);
1298 result =
1299 _gnutls_parse_general_name (c2, "", seq, alt, alt_size, alt_type,
1300 othername_oid);
1302 asn1_delete_structure (&c2);
1304 if (result < 0)
1306 gnutls_assert ();
1307 return result;
1310 return result;
1314 * gnutls_x509_crt_get_subject_alt_name:
1315 * @cert: should contain a #gnutls_x509_crt_t structure
1316 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1317 * @san: is the place where the alternative name will be copied to
1318 * @san_size: holds the size of san.
1319 * @critical: will be non (0) if the extension is marked as critical (may be null)
1321 * This function retrieves the Alternative Name (2.5.29.17), contained
1322 * in the given certificate in the X509v3 Certificate Extensions.
1324 * When the SAN type is otherName, it will extract the data in the
1325 * otherName's value field, and %GNUTLS_SAN_OTHERNAME is returned.
1326 * You may use gnutls_x509_crt_get_subject_alt_othername_oid() to get
1327 * the corresponding OID and the "virtual" SAN types (e.g.,
1328 * %GNUTLS_SAN_OTHERNAME_XMPP).
1330 * If an otherName OID is known, the data will be decoded. Otherwise
1331 * the returned data will be DER encoded, and you will have to decode
1332 * it yourself. Currently, only the RFC 3920 id-on-xmppAddr SAN is
1333 * recognized.
1335 * Returns: the alternative subject name type on success, one of the
1336 * enumerated #gnutls_x509_subject_alt_name_t. It will return
1337 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @san_size is not large enough to
1338 * hold the value. In that case @san_size will be updated with the
1339 * required size. If the certificate does not have an Alternative
1340 * name with the specified sequence number then
1341 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1344 gnutls_x509_crt_get_subject_alt_name (gnutls_x509_crt_t cert,
1345 unsigned int seq, void *san,
1346 size_t * san_size,
1347 unsigned int *critical)
1349 return get_alt_name (cert, "2.5.29.17", seq, san, san_size, NULL, critical,
1354 * gnutls_x509_crt_get_issuer_alt_name:
1355 * @cert: should contain a #gnutls_x509_crt_t structure
1356 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1357 * @ian: is the place where the alternative name will be copied to
1358 * @ian_size: holds the size of ian.
1359 * @critical: will be non (0) if the extension is marked as critical (may be null)
1361 * This function retrieves the Issuer Alternative Name (2.5.29.18),
1362 * contained in the given certificate in the X509v3 Certificate
1363 * Extensions.
1365 * When the SAN type is otherName, it will extract the data in the
1366 * otherName's value field, and %GNUTLS_SAN_OTHERNAME is returned.
1367 * You may use gnutls_x509_crt_get_subject_alt_othername_oid() to get
1368 * the corresponding OID and the "virtual" SAN types (e.g.,
1369 * %GNUTLS_SAN_OTHERNAME_XMPP).
1371 * If an otherName OID is known, the data will be decoded. Otherwise
1372 * the returned data will be DER encoded, and you will have to decode
1373 * it yourself. Currently, only the RFC 3920 id-on-xmppAddr Issuer
1374 * AltName is recognized.
1376 * Returns: the alternative issuer name type on success, one of the
1377 * enumerated #gnutls_x509_subject_alt_name_t. It will return
1378 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @ian_size is not large enough
1379 * to hold the value. In that case @ian_size will be updated with
1380 * the required size. If the certificate does not have an
1381 * Alternative name with the specified sequence number then
1382 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1384 * Since: 2.10.0
1387 gnutls_x509_crt_get_issuer_alt_name (gnutls_x509_crt_t cert,
1388 unsigned int seq, void *ian,
1389 size_t * ian_size,
1390 unsigned int *critical)
1392 return get_alt_name (cert, "2.5.29.18", seq, ian, ian_size, NULL, critical,
1397 * gnutls_x509_crt_get_subject_alt_name2:
1398 * @cert: should contain a #gnutls_x509_crt_t structure
1399 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1400 * @san: is the place where the alternative name will be copied to
1401 * @san_size: holds the size of ret.
1402 * @san_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
1403 * @critical: will be non (0) if the extension is marked as critical (may be null)
1405 * This function will return the alternative names, contained in the
1406 * given certificate. It is the same as
1407 * gnutls_x509_crt_get_subject_alt_name() except for the fact that it
1408 * will return the type of the alternative name in @san_type even if
1409 * the function fails for some reason (i.e. the buffer provided is
1410 * not enough).
1412 * Returns: the alternative subject name type on success, one of the
1413 * enumerated #gnutls_x509_subject_alt_name_t. It will return
1414 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @san_size is not large enough
1415 * to hold the value. In that case @san_size will be updated with
1416 * the required size. If the certificate does not have an
1417 * Alternative name with the specified sequence number then
1418 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1421 gnutls_x509_crt_get_subject_alt_name2 (gnutls_x509_crt_t cert,
1422 unsigned int seq, void *san,
1423 size_t * san_size,
1424 unsigned int *san_type,
1425 unsigned int *critical)
1427 return get_alt_name (cert, "2.5.29.17", seq, san, san_size, san_type,
1428 critical, 0);
1432 * gnutls_x509_crt_get_issuer_alt_name2:
1433 * @cert: should contain a #gnutls_x509_crt_t structure
1434 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1435 * @ian: is the place where the alternative name will be copied to
1436 * @ian_size: holds the size of ret.
1437 * @ian_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
1438 * @critical: will be non (0) if the extension is marked as critical (may be null)
1440 * This function will return the alternative names, contained in the
1441 * given certificate. It is the same as
1442 * gnutls_x509_crt_get_issuer_alt_name() except for the fact that it
1443 * will return the type of the alternative name in @ian_type even if
1444 * the function fails for some reason (i.e. the buffer provided is
1445 * not enough).
1447 * Returns: the alternative issuer name type on success, one of the
1448 * enumerated #gnutls_x509_subject_alt_name_t. It will return
1449 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @ian_size is not large enough
1450 * to hold the value. In that case @ian_size will be updated with
1451 * the required size. If the certificate does not have an
1452 * Alternative name with the specified sequence number then
1453 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1455 * Since: 2.10.0
1459 gnutls_x509_crt_get_issuer_alt_name2 (gnutls_x509_crt_t cert,
1460 unsigned int seq, void *ian,
1461 size_t * ian_size,
1462 unsigned int *ian_type,
1463 unsigned int *critical)
1465 return get_alt_name (cert, "2.5.29.18", seq, ian, ian_size, ian_type,
1466 critical, 0);
1470 * gnutls_x509_crt_get_subject_alt_othername_oid:
1471 * @cert: should contain a #gnutls_x509_crt_t structure
1472 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1473 * @oid: is the place where the otherName OID will be copied to
1474 * @oid_size: holds the size of ret.
1476 * This function will extract the type OID of an otherName Subject
1477 * Alternative Name, contained in the given certificate, and return
1478 * the type as an enumerated element.
1480 * This function is only useful if
1481 * gnutls_x509_crt_get_subject_alt_name() returned
1482 * %GNUTLS_SAN_OTHERNAME.
1484 * If @oid is null then only the size will be filled. The @oid
1485 * returned will be null terminated, although @oid_size will not
1486 * account for the trailing null.
1488 * Returns: the alternative subject name type on success, one of the
1489 * enumerated gnutls_x509_subject_alt_name_t. For supported OIDs, it
1490 * will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
1491 * e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
1492 * unknown OIDs. It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
1493 * @ian_size is not large enough to hold the value. In that case
1494 * @ian_size will be updated with the required size. If the
1495 * certificate does not have an Alternative name with the specified
1496 * sequence number and with the otherName type then
1497 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1500 gnutls_x509_crt_get_subject_alt_othername_oid (gnutls_x509_crt_t cert,
1501 unsigned int seq,
1502 void *oid, size_t * oid_size)
1504 return get_alt_name (cert, "2.5.29.17", seq, oid, oid_size, NULL, NULL, 1);
1508 * gnutls_x509_crt_get_issuer_alt_othername_oid:
1509 * @cert: should contain a #gnutls_x509_crt_t structure
1510 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1511 * @ret: is the place where the otherName OID will be copied to
1512 * @ret_size: holds the size of ret.
1514 * This function will extract the type OID of an otherName Subject
1515 * Alternative Name, contained in the given certificate, and return
1516 * the type as an enumerated element.
1518 * If @oid is null then only the size will be filled. The @oid
1519 * returned will be null terminated, although @oid_size will not
1520 * account for the trailing null.
1522 * This function is only useful if
1523 * gnutls_x509_crt_get_issuer_alt_name() returned
1524 * %GNUTLS_SAN_OTHERNAME.
1526 * Returns: the alternative issuer name type on success, one of the
1527 * enumerated gnutls_x509_subject_alt_name_t. For supported OIDs, it
1528 * will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
1529 * e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
1530 * unknown OIDs. It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
1531 * @ret_size is not large enough to hold the value. In that case
1532 * @ret_size will be updated with the required size. If the
1533 * certificate does not have an Alternative name with the specified
1534 * sequence number and with the otherName type then
1535 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1537 * Since: 2.10.0
1540 gnutls_x509_crt_get_issuer_alt_othername_oid (gnutls_x509_crt_t cert,
1541 unsigned int seq,
1542 void *ret, size_t * ret_size)
1544 return get_alt_name (cert, "2.5.29.18", seq, ret, ret_size, NULL, NULL, 1);
1548 * gnutls_x509_crt_get_basic_constraints:
1549 * @cert: should contain a #gnutls_x509_crt_t structure
1550 * @critical: will be non (0) if the extension is marked as critical
1551 * @ca: pointer to output integer indicating CA status, may be NULL,
1552 * value is 1 if the certificate CA flag is set, 0 otherwise.
1553 * @pathlen: pointer to output integer indicating path length (may be
1554 * NULL), non-negative error codes indicate a present pathLenConstraint
1555 * field and the actual value, -1 indicate that the field is absent.
1557 * This function will read the certificate's basic constraints, and
1558 * return the certificates CA status. It reads the basicConstraints
1559 * X.509 extension (2.5.29.19).
1561 * Returns: If the certificate is a CA a positive value will be
1562 * returned, or (0) if the certificate does not have CA flag set. A
1563 * negative error code may be returned in case of errors. If the
1564 * certificate does not contain the basicConstraints extension
1565 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1568 gnutls_x509_crt_get_basic_constraints (gnutls_x509_crt_t cert,
1569 unsigned int *critical,
1570 unsigned int *ca, int *pathlen)
1572 int result;
1573 gnutls_datum_t basicConstraints;
1574 unsigned int tmp_ca;
1576 if (cert == NULL)
1578 gnutls_assert ();
1579 return GNUTLS_E_INVALID_REQUEST;
1582 if ((result =
1583 _gnutls_x509_crt_get_extension (cert, "2.5.29.19", 0,
1584 &basicConstraints, critical)) < 0)
1586 return result;
1589 if (basicConstraints.size == 0 || basicConstraints.data == NULL)
1591 gnutls_assert ();
1592 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1595 result =
1596 _gnutls_x509_ext_extract_basicConstraints (&tmp_ca,
1597 pathlen,
1598 basicConstraints.data,
1599 basicConstraints.size);
1600 if (ca)
1601 *ca = tmp_ca;
1602 _gnutls_free_datum (&basicConstraints);
1604 if (result < 0)
1606 gnutls_assert ();
1607 return result;
1610 return tmp_ca;
1614 * gnutls_x509_crt_get_ca_status:
1615 * @cert: should contain a #gnutls_x509_crt_t structure
1616 * @critical: will be non (0) if the extension is marked as critical
1618 * This function will return certificates CA status, by reading the
1619 * basicConstraints X.509 extension (2.5.29.19). If the certificate is
1620 * a CA a positive value will be returned, or (0) if the certificate
1621 * does not have CA flag set.
1623 * Use gnutls_x509_crt_get_basic_constraints() if you want to read the
1624 * pathLenConstraint field too.
1626 * Returns: A negative error code may be returned in case of parsing error.
1627 * If the certificate does not contain the basicConstraints extension
1628 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1631 gnutls_x509_crt_get_ca_status (gnutls_x509_crt_t cert, unsigned int *critical)
1633 int pathlen;
1634 unsigned int ca;
1635 return gnutls_x509_crt_get_basic_constraints (cert, critical, &ca,
1636 &pathlen);
1640 * gnutls_x509_crt_get_key_usage:
1641 * @cert: should contain a #gnutls_x509_crt_t structure
1642 * @key_usage: where the key usage bits will be stored
1643 * @critical: will be non (0) if the extension is marked as critical
1645 * This function will return certificate's key usage, by reading the
1646 * keyUsage X.509 extension (2.5.29.15). The key usage value will ORed
1647 * values of the: %GNUTLS_KEY_DIGITAL_SIGNATURE,
1648 * %GNUTLS_KEY_NON_REPUDIATION, %GNUTLS_KEY_KEY_ENCIPHERMENT,
1649 * %GNUTLS_KEY_DATA_ENCIPHERMENT, %GNUTLS_KEY_KEY_AGREEMENT,
1650 * %GNUTLS_KEY_KEY_CERT_SIGN, %GNUTLS_KEY_CRL_SIGN,
1651 * %GNUTLS_KEY_ENCIPHER_ONLY, %GNUTLS_KEY_DECIPHER_ONLY.
1653 * Returns: the certificate key usage, or a negative error code in case of
1654 * parsing error. If the certificate does not contain the keyUsage
1655 * extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
1656 * returned.
1659 gnutls_x509_crt_get_key_usage (gnutls_x509_crt_t cert,
1660 unsigned int *key_usage,
1661 unsigned int *critical)
1663 int result;
1664 gnutls_datum_t keyUsage;
1665 uint16_t _usage;
1667 if (cert == NULL)
1669 gnutls_assert ();
1670 return GNUTLS_E_INVALID_REQUEST;
1673 if ((result =
1674 _gnutls_x509_crt_get_extension (cert, "2.5.29.15", 0, &keyUsage,
1675 critical)) < 0)
1677 return result;
1680 if (keyUsage.size == 0 || keyUsage.data == NULL)
1682 gnutls_assert ();
1683 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1686 result = _gnutls_x509_ext_extract_keyUsage (&_usage, keyUsage.data,
1687 keyUsage.size);
1688 _gnutls_free_datum (&keyUsage);
1690 *key_usage = _usage;
1692 if (result < 0)
1694 gnutls_assert ();
1695 return result;
1698 return 0;
1702 * gnutls_x509_crt_get_proxy:
1703 * @cert: should contain a #gnutls_x509_crt_t structure
1704 * @critical: will be non (0) if the extension is marked as critical
1705 * @pathlen: pointer to output integer indicating path length (may be
1706 * NULL), non-negative error codes indicate a present pCPathLenConstraint
1707 * field and the actual value, -1 indicate that the field is absent.
1708 * @policyLanguage: output variable with OID of policy language
1709 * @policy: output variable with policy data
1710 * @sizeof_policy: output variable size of policy data
1712 * This function will get information from a proxy certificate. It
1713 * reads the ProxyCertInfo X.509 extension (1.3.6.1.5.5.7.1.14).
1715 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1716 * otherwise a negative error code is returned.
1719 gnutls_x509_crt_get_proxy (gnutls_x509_crt_t cert,
1720 unsigned int *critical,
1721 int *pathlen,
1722 char **policyLanguage,
1723 char **policy, size_t * sizeof_policy)
1725 int result;
1726 gnutls_datum_t proxyCertInfo;
1728 if (cert == NULL)
1730 gnutls_assert ();
1731 return GNUTLS_E_INVALID_REQUEST;
1734 if ((result =
1735 _gnutls_x509_crt_get_extension (cert, "1.3.6.1.5.5.7.1.14", 0,
1736 &proxyCertInfo, critical)) < 0)
1738 return result;
1741 if (proxyCertInfo.size == 0 || proxyCertInfo.data == NULL)
1743 gnutls_assert ();
1744 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1747 result = _gnutls_x509_ext_extract_proxyCertInfo (pathlen,
1748 policyLanguage,
1749 policy,
1750 sizeof_policy,
1751 proxyCertInfo.data,
1752 proxyCertInfo.size);
1753 _gnutls_free_datum (&proxyCertInfo);
1754 if (result < 0)
1756 gnutls_assert ();
1757 return result;
1760 return 0;
1764 * gnutls_x509_crt_get_extension_by_oid:
1765 * @cert: should contain a #gnutls_x509_crt_t structure
1766 * @oid: holds an Object Identified in null terminated string
1767 * @indx: In case multiple same OIDs exist in the extensions, this specifies which to send. Use (0) to get the first one.
1768 * @buf: a pointer to a structure to hold the name (may be null)
1769 * @buf_size: initially holds the size of @buf
1770 * @critical: will be non (0) if the extension is marked as critical
1772 * This function will return the extension specified by the OID in the
1773 * certificate. The extensions will be returned as binary data DER
1774 * encoded, in the provided buffer.
1776 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1777 * otherwise a negative error code is returned. If the certificate does not
1778 * contain the specified extension
1779 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1782 gnutls_x509_crt_get_extension_by_oid (gnutls_x509_crt_t cert,
1783 const char *oid, int indx,
1784 void *buf, size_t * buf_size,
1785 unsigned int *critical)
1787 int result;
1788 gnutls_datum_t output;
1790 if (cert == NULL)
1792 gnutls_assert ();
1793 return GNUTLS_E_INVALID_REQUEST;
1796 if ((result =
1797 _gnutls_x509_crt_get_extension (cert, oid, indx, &output,
1798 critical)) < 0)
1800 gnutls_assert ();
1801 return result;
1804 if (output.size == 0 || output.data == NULL)
1806 gnutls_assert ();
1807 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1810 if (output.size > (unsigned int) *buf_size)
1812 *buf_size = output.size;
1813 _gnutls_free_datum (&output);
1814 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1817 *buf_size = output.size;
1819 if (buf)
1820 memcpy (buf, output.data, output.size);
1822 _gnutls_free_datum (&output);
1824 return 0;
1829 * gnutls_x509_crt_get_extension_oid:
1830 * @cert: should contain a #gnutls_x509_crt_t structure
1831 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
1832 * @oid: a pointer to a structure to hold the OID (may be null)
1833 * @oid_size: initially holds the size of @oid
1835 * This function will return the requested extension OID in the certificate.
1836 * The extension OID will be stored as a string in the provided buffer.
1838 * The @oid returned will be null terminated, although @oid_size will not
1839 * account for the trailing null.
1841 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1842 * otherwise a negative error code is returned. If you have reached the
1843 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1844 * will be returned.
1847 gnutls_x509_crt_get_extension_oid (gnutls_x509_crt_t cert, int indx,
1848 void *oid, size_t * oid_size)
1850 int result;
1852 if (cert == NULL)
1854 gnutls_assert ();
1855 return GNUTLS_E_INVALID_REQUEST;
1858 result = _gnutls_x509_crt_get_extension_oid (cert, indx, oid, oid_size);
1859 if (result < 0)
1861 return result;
1864 return 0;
1869 * gnutls_x509_crt_get_extension_info:
1870 * @cert: should contain a #gnutls_x509_crt_t structure
1871 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
1872 * @oid: a pointer to a structure to hold the OID
1873 * @oid_size: initially holds the maximum size of @oid, on return
1874 * holds actual size of @oid.
1875 * @critical: output variable with critical flag, may be NULL.
1877 * This function will return the requested extension OID in the
1878 * certificate, and the critical flag for it. The extension OID will
1879 * be stored as a string in the provided buffer. Use
1880 * gnutls_x509_crt_get_extension_data() to extract the data.
1882 * If the buffer provided is not long enough to hold the output, then
1883 * @oid_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
1884 * returned. The @oid returned will be null terminated, although
1885 * @oid_size will not account for the trailing null.
1887 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1888 * otherwise a negative error code is returned. If you have reached the
1889 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1890 * will be returned.
1893 gnutls_x509_crt_get_extension_info (gnutls_x509_crt_t cert, int indx,
1894 void *oid, size_t * oid_size,
1895 unsigned int *critical)
1897 int result;
1898 char str_critical[10];
1899 char name[ASN1_MAX_NAME_SIZE];
1900 int len;
1902 if (!cert)
1904 gnutls_assert ();
1905 return GNUTLS_E_INVALID_REQUEST;
1908 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u.extnID",
1909 indx + 1);
1911 len = *oid_size;
1912 result = asn1_read_value (cert->cert, name, oid, &len);
1913 *oid_size = len;
1915 if (result == ASN1_ELEMENT_NOT_FOUND)
1916 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1917 else if (result != ASN1_SUCCESS)
1919 gnutls_assert ();
1920 return _gnutls_asn2err (result);
1923 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u.critical",
1924 indx + 1);
1925 len = sizeof (str_critical);
1926 result = asn1_read_value (cert->cert, name, str_critical, &len);
1927 if (result != ASN1_SUCCESS)
1929 gnutls_assert ();
1930 return _gnutls_asn2err (result);
1933 if (critical)
1935 if (str_critical[0] == 'T')
1936 *critical = 1;
1937 else
1938 *critical = 0;
1941 return 0;
1946 * gnutls_x509_crt_get_extension_data:
1947 * @cert: should contain a #gnutls_x509_crt_t structure
1948 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
1949 * @data: a pointer to a structure to hold the data (may be null)
1950 * @sizeof_data: initially holds the size of @oid
1952 * This function will return the requested extension data in the
1953 * certificate. The extension data will be stored as a string in the
1954 * provided buffer.
1956 * Use gnutls_x509_crt_get_extension_info() to extract the OID and
1957 * critical flag. Use gnutls_x509_crt_get_extension_by_oid() instead,
1958 * if you want to get data indexed by the extension OID rather than
1959 * sequence.
1961 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1962 * otherwise a negative error code is returned. If you have reached the
1963 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1964 * will be returned.
1967 gnutls_x509_crt_get_extension_data (gnutls_x509_crt_t cert, int indx,
1968 void *data, size_t * sizeof_data)
1970 int result, len;
1971 char name[ASN1_MAX_NAME_SIZE];
1973 if (!cert)
1975 gnutls_assert ();
1976 return GNUTLS_E_INVALID_REQUEST;
1979 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u.extnValue",
1980 indx + 1);
1982 len = *sizeof_data;
1983 result = asn1_read_value (cert->cert, name, data, &len);
1984 *sizeof_data = len;
1986 if (result == ASN1_ELEMENT_NOT_FOUND)
1987 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1988 else if (result < 0)
1990 gnutls_assert ();
1991 return _gnutls_asn2err (result);
1994 return 0;
1997 static int
1998 _gnutls_x509_crt_get_raw_dn2 (gnutls_x509_crt_t cert,
1999 const char *whom, gnutls_datum_t * start)
2001 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2002 int result, len1;
2003 int start1, end1;
2004 gnutls_datum_t signed_data = { NULL, 0 };
2006 /* get the issuer of 'cert'
2008 if ((result =
2009 asn1_create_element (_gnutls_get_pkix (), "PKIX1.TBSCertificate",
2010 &c2)) != ASN1_SUCCESS)
2012 gnutls_assert ();
2013 return _gnutls_asn2err (result);
2016 result =
2017 _gnutls_x509_get_signed_data (cert->cert, "tbsCertificate", &signed_data);
2018 if (result < 0)
2020 gnutls_assert ();
2021 goto cleanup;
2024 result = asn1_der_decoding (&c2, signed_data.data, signed_data.size, NULL);
2025 if (result != ASN1_SUCCESS)
2027 gnutls_assert ();
2028 asn1_delete_structure (&c2);
2029 result = _gnutls_asn2err (result);
2030 goto cleanup;
2033 result =
2034 asn1_der_decoding_startEnd (c2, signed_data.data, signed_data.size,
2035 whom, &start1, &end1);
2037 if (result != ASN1_SUCCESS)
2039 gnutls_assert ();
2040 result = _gnutls_asn2err (result);
2041 goto cleanup;
2044 len1 = end1 - start1 + 1;
2046 _gnutls_set_datum (start, &signed_data.data[start1], len1);
2048 result = 0;
2050 cleanup:
2051 asn1_delete_structure (&c2);
2052 _gnutls_free_datum (&signed_data);
2053 return result;
2057 * gnutls_x509_crt_get_raw_issuer_dn:
2058 * @cert: should contain a #gnutls_x509_crt_t structure
2059 * @start: will hold the starting point of the DN
2061 * This function will return a pointer to the DER encoded DN structure
2062 * and the length. This points to allocated data that must be free'd using gnutls_free().
2064 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2065 * negative error value.or a negative error code on error.
2069 gnutls_x509_crt_get_raw_issuer_dn (gnutls_x509_crt_t cert,
2070 gnutls_datum_t * start)
2072 return _gnutls_x509_crt_get_raw_dn2 (cert, "issuer", start);
2076 * gnutls_x509_crt_get_raw_dn:
2077 * @cert: should contain a #gnutls_x509_crt_t structure
2078 * @start: will hold the starting point of the DN
2080 * This function will return a pointer to the DER encoded DN structure and
2081 * the length. This points to allocated data that must be free'd using gnutls_free().
2083 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2084 * negative error value. or a negative error code on error.
2088 gnutls_x509_crt_get_raw_dn (gnutls_x509_crt_t cert, gnutls_datum_t * start)
2090 return _gnutls_x509_crt_get_raw_dn2 (cert, "subject", start);
2093 static int
2094 get_dn (gnutls_x509_crt_t cert, const char *whom, gnutls_x509_dn_t * dn)
2096 *dn = asn1_find_node (cert->cert, whom);
2097 if (!*dn)
2098 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2099 return 0;
2103 * gnutls_x509_crt_get_subject:
2104 * @cert: should contain a #gnutls_x509_crt_t structure
2105 * @dn: output variable with pointer to uint8_t DN.
2107 * Return the Certificate's Subject DN as an uint8_t data type. You
2108 * may use gnutls_x509_dn_get_rdn_ava() to decode the DN.
2110 * Note that @dn should be treated as constant. Because points
2111 * into the @cert object, you may not deallocate @cert
2112 * and continue to access @dn.
2114 * Returns: Returns 0 on success, or an error code.
2117 gnutls_x509_crt_get_subject (gnutls_x509_crt_t cert, gnutls_x509_dn_t * dn)
2119 return get_dn (cert, "tbsCertificate.subject.rdnSequence", dn);
2123 * gnutls_x509_crt_get_issuer:
2124 * @cert: should contain a #gnutls_x509_crt_t structure
2125 * @dn: output variable with pointer to uint8_t DN
2127 * Return the Certificate's Issuer DN as an uint8_t data type. You may
2128 * use gnutls_x509_dn_get_rdn_ava() to decode the DN.
2130 * Note that @dn should be treated as constant. Because points
2131 * into the @cert object, you may not deallocate @cert
2132 * and continue to access @dn.
2134 * Returns: Returns 0 on success, or an error code.
2137 gnutls_x509_crt_get_issuer (gnutls_x509_crt_t cert, gnutls_x509_dn_t * dn)
2139 return get_dn (cert, "tbsCertificate.issuer.rdnSequence", dn);
2143 * gnutls_x509_dn_get_rdn_ava:
2144 * @dn: input variable with uint8_t DN pointer
2145 * @irdn: index of RDN
2146 * @iava: index of AVA.
2147 * @ava: Pointer to structure which will hold output information.
2149 * Get pointers to data within the DN.
2151 * Note that @ava will contain pointers into the @dn structure, so you
2152 * should not modify any data or deallocate it. Note also that the DN
2153 * in turn points into the original certificate structure, and thus
2154 * you may not deallocate the certificate and continue to access @dn.
2156 * Returns: Returns 0 on success, or an error code.
2159 gnutls_x509_dn_get_rdn_ava (gnutls_x509_dn_t dn,
2160 int irdn, int iava, gnutls_x509_ava_st * ava)
2162 ASN1_TYPE rdn, elem;
2163 ASN1_DATA_NODE vnode;
2164 long len;
2165 int lenlen, remlen, ret;
2166 char rbuf[ASN1_MAX_NAME_SIZE];
2167 unsigned char cls;
2168 const unsigned char *ptr;
2170 iava++;
2171 irdn++; /* 0->1, 1->2 etc */
2173 snprintf (rbuf, sizeof (rbuf), "rdnSequence.?%d.?%d", irdn, iava);
2174 rdn = asn1_find_node (dn, rbuf);
2175 if (!rdn)
2177 gnutls_assert ();
2178 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2181 snprintf (rbuf, sizeof (rbuf), "?%d.type", iava);
2182 elem = asn1_find_node (rdn, rbuf);
2183 if (!elem)
2185 gnutls_assert ();
2186 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2189 ret = asn1_read_node_value(elem, &vnode);
2190 if (ret != ASN1_SUCCESS)
2192 gnutls_assert ();
2193 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2196 ava->oid.data = (void*)vnode.value;
2197 ava->oid.size = vnode.value_len;
2199 snprintf (rbuf, sizeof (rbuf), "?%d.value", iava);
2200 elem = asn1_find_node (rdn, rbuf);
2201 if (!elem)
2203 gnutls_assert ();
2204 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2207 ret = asn1_read_node_value(elem, &vnode);
2208 if (ret != ASN1_SUCCESS)
2210 gnutls_assert ();
2211 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2213 /* The value still has the previous tag's length bytes, plus the
2214 * current value's tag and length bytes. Decode them.
2217 ptr = vnode.value;
2218 remlen = vnode.value_len;
2219 len = asn1_get_length_der (ptr, remlen, &lenlen);
2220 if (len < 0)
2222 gnutls_assert ();
2223 return GNUTLS_E_ASN1_DER_ERROR;
2226 ptr += lenlen;
2227 remlen -= lenlen;
2228 ret = asn1_get_tag_der (ptr, remlen, &cls, &lenlen, &ava->value_tag);
2229 if (ret)
2231 gnutls_assert ();
2232 return _gnutls_asn2err (ret);
2235 ptr += lenlen;
2236 remlen -= lenlen;
2239 signed long tmp;
2241 tmp = asn1_get_length_der (ptr, remlen, &lenlen);
2242 if (tmp < 0)
2244 gnutls_assert ();
2245 return GNUTLS_E_ASN1_DER_ERROR;
2247 ava->value.size = tmp;
2249 ava->value.data = (void*)(ptr + lenlen);
2251 return 0;
2255 * gnutls_x509_crt_get_fingerprint:
2256 * @cert: should contain a #gnutls_x509_crt_t structure
2257 * @algo: is a digest algorithm
2258 * @buf: a pointer to a structure to hold the fingerprint (may be null)
2259 * @buf_size: initially holds the size of @buf
2261 * This function will calculate and copy the certificate's fingerprint
2262 * in the provided buffer.
2264 * If the buffer is null then only the size will be filled.
2266 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
2267 * not long enough, and in that case the *buf_size will be updated
2268 * with the required size. On success 0 is returned.
2271 gnutls_x509_crt_get_fingerprint (gnutls_x509_crt_t cert,
2272 gnutls_digest_algorithm_t algo,
2273 void *buf, size_t * buf_size)
2275 uint8_t *cert_buf;
2276 int cert_buf_size;
2277 int result;
2278 gnutls_datum_t tmp;
2280 if (buf_size == 0 || cert == NULL)
2282 return GNUTLS_E_INVALID_REQUEST;
2285 cert_buf_size = 0;
2286 asn1_der_coding (cert->cert, "", NULL, &cert_buf_size, NULL);
2288 cert_buf = gnutls_malloc (cert_buf_size);
2289 if (cert_buf == NULL)
2291 gnutls_assert ();
2292 return GNUTLS_E_MEMORY_ERROR;
2295 result = asn1_der_coding (cert->cert, "", cert_buf, &cert_buf_size, NULL);
2297 if (result != ASN1_SUCCESS)
2299 gnutls_assert ();
2300 gnutls_free (cert_buf);
2301 return _gnutls_asn2err (result);
2304 tmp.data = cert_buf;
2305 tmp.size = cert_buf_size;
2307 result = gnutls_fingerprint (algo, &tmp, buf, buf_size);
2308 gnutls_free (cert_buf);
2310 return result;
2314 * gnutls_x509_crt_export:
2315 * @cert: Holds the certificate
2316 * @format: the format of output params. One of PEM or DER.
2317 * @output_data: will contain a certificate PEM or DER encoded
2318 * @output_data_size: holds the size of output_data (and will be
2319 * replaced by the actual size of parameters)
2321 * This function will export the certificate to DER or PEM format.
2323 * If the buffer provided is not long enough to hold the output, then
2324 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2325 * be returned.
2327 * If the structure is PEM encoded, it will have a header
2328 * of "BEGIN CERTIFICATE".
2330 * Returns: In case of failure a negative error code will be
2331 * returned, and 0 on success.
2334 gnutls_x509_crt_export (gnutls_x509_crt_t cert,
2335 gnutls_x509_crt_fmt_t format, void *output_data,
2336 size_t * output_data_size)
2338 if (cert == NULL)
2340 gnutls_assert ();
2341 return GNUTLS_E_INVALID_REQUEST;
2344 return _gnutls_x509_export_int (cert->cert, format, "CERTIFICATE",
2345 output_data, output_data_size);
2349 _gnutls_get_key_id (gnutls_pk_algorithm_t pk, gnutls_pk_params_st * params,
2350 unsigned char *output_data,
2351 size_t * output_data_size)
2353 int ret = 0;
2354 gnutls_datum_t der = { NULL, 0 };
2355 const gnutls_digest_algorithm_t hash = GNUTLS_DIG_SHA1;
2356 unsigned int digest_len = _gnutls_hash_get_algo_len(hash);
2358 if (output_data == NULL || *output_data_size < digest_len)
2360 gnutls_assert ();
2361 *output_data_size = digest_len;
2362 return GNUTLS_E_SHORT_MEMORY_BUFFER;
2365 ret = _gnutls_x509_encode_PKI_params(&der, pk, params);
2366 if (ret < 0)
2367 return gnutls_assert_val(ret);
2369 ret = _gnutls_hash_fast(hash, der.data, der.size, output_data);
2370 if (ret < 0)
2372 gnutls_assert ();
2373 goto cleanup;
2375 *output_data_size = digest_len;
2377 ret = 0;
2379 cleanup:
2381 _gnutls_free_datum (&der);
2382 return ret;
2386 * gnutls_x509_crt_get_key_id:
2387 * @crt: Holds the certificate
2388 * @flags: should be 0 for now
2389 * @output_data: will contain the key ID
2390 * @output_data_size: holds the size of output_data (and will be
2391 * replaced by the actual size of parameters)
2393 * This function will return a unique ID the depends on the public
2394 * key parameters. This ID can be used in checking whether a
2395 * certificate corresponds to the given private key.
2397 * If the buffer provided is not long enough to hold the output, then
2398 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2399 * be returned. The output will normally be a SHA-1 hash output,
2400 * which is 20 bytes.
2402 * Returns: In case of failure a negative error code will be
2403 * returned, and 0 on success.
2406 gnutls_x509_crt_get_key_id (gnutls_x509_crt_t crt, unsigned int flags,
2407 unsigned char *output_data,
2408 size_t * output_data_size)
2410 int pk, ret = 0;
2411 gnutls_pk_params_st params;
2413 if (crt == NULL)
2415 gnutls_assert ();
2416 return GNUTLS_E_INVALID_REQUEST;
2419 pk = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
2420 if (pk < 0)
2422 gnutls_assert ();
2423 return pk;
2426 ret = _gnutls_x509_crt_get_mpis (crt, &params);
2427 if (ret < 0)
2429 gnutls_assert ();
2430 return ret;
2433 ret = _gnutls_get_key_id(pk, &params, output_data, output_data_size);
2435 gnutls_pk_params_release(&params);
2437 return ret;
2441 /* This is exactly as gnutls_x509_crt_check_revocation() except that
2442 * it calls func.
2445 _gnutls_x509_crt_check_revocation (gnutls_x509_crt_t cert,
2446 const gnutls_x509_crl_t * crl_list,
2447 int crl_list_length,
2448 gnutls_verify_output_function func)
2450 uint8_t serial[128];
2451 uint8_t cert_serial[128];
2452 size_t serial_size, cert_serial_size;
2453 int ncerts, ret, i, j;
2454 gnutls_datum_t dn1, dn2;
2456 if (cert == NULL)
2458 gnutls_assert ();
2459 return GNUTLS_E_INVALID_REQUEST;
2462 for (j = 0; j < crl_list_length; j++)
2463 { /* do for all the crls */
2465 /* Step 1. check if issuer's DN match
2467 ret = gnutls_x509_crl_get_raw_issuer_dn (crl_list[j], &dn1);
2468 if (ret < 0)
2470 gnutls_assert ();
2471 return ret;
2474 ret = gnutls_x509_crt_get_raw_issuer_dn (cert, &dn2);
2475 if (ret < 0)
2477 gnutls_assert ();
2478 return ret;
2481 ret = _gnutls_x509_compare_raw_dn (&dn1, &dn2);
2482 _gnutls_free_datum (&dn1);
2483 _gnutls_free_datum (&dn2);
2484 if (ret == 0)
2486 /* issuers do not match so don't even
2487 * bother checking.
2489 continue;
2492 /* Step 2. Read the certificate's serial number
2494 cert_serial_size = sizeof (cert_serial);
2495 ret = gnutls_x509_crt_get_serial (cert, cert_serial, &cert_serial_size);
2496 if (ret < 0)
2498 gnutls_assert ();
2499 return ret;
2502 /* Step 3. cycle through the CRL serials and compare with
2503 * certificate serial we have.
2506 ncerts = gnutls_x509_crl_get_crt_count (crl_list[j]);
2507 if (ncerts < 0)
2509 gnutls_assert ();
2510 return ncerts;
2513 for (i = 0; i < ncerts; i++)
2515 serial_size = sizeof (serial);
2516 ret =
2517 gnutls_x509_crl_get_crt_serial (crl_list[j], i, serial,
2518 &serial_size, NULL);
2520 if (ret < 0)
2522 gnutls_assert ();
2523 return ret;
2526 if (serial_size == cert_serial_size)
2528 if (memcmp (serial, cert_serial, serial_size) == 0)
2530 /* serials match */
2531 if (func) func(cert, NULL, crl_list[j], GNUTLS_CERT_REVOKED|GNUTLS_CERT_INVALID);
2532 return 1; /* revoked! */
2536 if (func) func(cert, NULL, crl_list[j], 0);
2539 return 0; /* not revoked. */
2544 * gnutls_x509_crt_check_revocation:
2545 * @cert: should contain a #gnutls_x509_crt_t structure
2546 * @crl_list: should contain a list of gnutls_x509_crl_t structures
2547 * @crl_list_length: the length of the crl_list
2549 * This function will return check if the given certificate is
2550 * revoked. It is assumed that the CRLs have been verified before.
2552 * Returns: 0 if the certificate is NOT revoked, and 1 if it is. A
2553 * negative error code is returned on error.
2556 gnutls_x509_crt_check_revocation (gnutls_x509_crt_t cert,
2557 const gnutls_x509_crl_t * crl_list,
2558 int crl_list_length)
2560 return _gnutls_x509_crt_check_revocation(cert, crl_list, crl_list_length, NULL);
2564 * gnutls_x509_crt_get_verify_algorithm:
2565 * @crt: Holds the certificate
2566 * @signature: contains the signature
2567 * @hash: The result of the call with the hash algorithm used for signature
2569 * This function will read the certifcate and the signed data to
2570 * determine the hash algorithm used to generate the signature.
2572 * Deprecated: Use gnutls_pubkey_get_verify_algorithm() instead.
2574 * Returns: the 0 if the hash algorithm is found. A negative error code is
2575 * returned on error.
2577 * Since: 2.8.0
2580 gnutls_x509_crt_get_verify_algorithm (gnutls_x509_crt_t crt,
2581 const gnutls_datum_t * signature,
2582 gnutls_digest_algorithm_t * hash)
2584 gnutls_pk_params_st issuer_params;
2585 int ret;
2587 if (crt == NULL)
2589 gnutls_assert ();
2590 return GNUTLS_E_INVALID_REQUEST;
2593 ret = _gnutls_x509_crt_get_mpis (crt, &issuer_params);
2594 if (ret < 0)
2596 gnutls_assert ();
2597 return ret;
2600 ret = _gnutls_x509_verify_algorithm (hash,
2601 signature,
2602 gnutls_x509_crt_get_pk_algorithm (crt,
2603 NULL),
2604 &issuer_params);
2606 /* release allocated mpis */
2607 gnutls_pk_params_release(&issuer_params);
2609 return ret;
2615 * gnutls_x509_crt_get_preferred_hash_algorithm:
2616 * @crt: Holds the certificate
2617 * @hash: The result of the call with the hash algorithm used for signature
2618 * @mand: If non (0) it means that the algorithm MUST use this hash. May be NULL.
2620 * This function will read the certifcate and return the appropriate digest
2621 * algorithm to use for signing with this certificate. Some certificates (i.e.
2622 * DSA might not be able to sign without the preferred algorithm).
2624 * Deprecated: Please use gnutls_pubkey_get_preferred_hash_algorithm().
2626 * Returns: the 0 if the hash algorithm is found. A negative error code is
2627 * returned on error.
2629 * Since: 2.12.0
2632 gnutls_x509_crt_get_preferred_hash_algorithm (gnutls_x509_crt_t crt,
2633 gnutls_digest_algorithm_t *
2634 hash, unsigned int *mand)
2636 gnutls_pk_params_st issuer_params;
2637 int ret;
2639 if (crt == NULL)
2641 gnutls_assert ();
2642 return GNUTLS_E_INVALID_REQUEST;
2645 ret = _gnutls_x509_crt_get_mpis (crt, &issuer_params);
2646 if (ret < 0)
2648 gnutls_assert ();
2649 return ret;
2652 ret =
2653 _gnutls_pk_get_hash_algorithm (gnutls_x509_crt_get_pk_algorithm
2654 (crt, NULL), &issuer_params,
2655 hash, mand);
2657 /* release allocated mpis */
2658 gnutls_pk_params_release(&issuer_params);
2660 return ret;
2664 * gnutls_x509_crt_verify_data:
2665 * @crt: Holds the certificate
2666 * @flags: should be 0 for now
2667 * @data: holds the data to be signed
2668 * @signature: contains the signature
2670 * This function will verify the given signed data, using the
2671 * parameters from the certificate.
2673 * Deprecated. Please use gnutls_pubkey_verify_data().
2675 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
2676 * is returned, and zero or positive code on success.
2679 gnutls_x509_crt_verify_data (gnutls_x509_crt_t crt, unsigned int flags,
2680 const gnutls_datum_t * data,
2681 const gnutls_datum_t * signature)
2683 int result;
2685 if (crt == NULL)
2687 gnutls_assert ();
2688 return GNUTLS_E_INVALID_REQUEST;
2691 result = _gnutls_x509_verify_data (GNUTLS_DIG_UNKNOWN, data, signature, crt);
2692 if (result < 0)
2694 gnutls_assert ();
2695 return result;
2698 return result;
2702 * gnutls_x509_crt_verify_hash:
2703 * @crt: Holds the certificate
2704 * @flags: should be 0 for now
2705 * @hash: holds the hash digest to be verified
2706 * @signature: contains the signature
2708 * This function will verify the given signed digest, using the
2709 * parameters from the certificate.
2711 * Deprecated. Please use gnutls_pubkey_verify_data2() or gnutls_pubkey_verify_hash2().
2713 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
2714 * is returned, and zero or positive code on success.
2717 gnutls_x509_crt_verify_hash (gnutls_x509_crt_t crt, unsigned int flags,
2718 const gnutls_datum_t * hash,
2719 const gnutls_datum_t * signature)
2721 gnutls_pk_params_st params;
2722 gnutls_digest_algorithm_t algo;
2723 int ret;
2725 if (crt == NULL)
2727 gnutls_assert ();
2728 return GNUTLS_E_INVALID_REQUEST;
2731 ret = gnutls_x509_crt_get_verify_algorithm (crt, signature, &algo);
2732 if (ret < 0)
2733 return gnutls_assert_val(ret);
2735 /* Read the MPI parameters from the issuer's certificate.
2737 ret =
2738 _gnutls_x509_crt_get_mpis (crt, &params);
2739 if (ret < 0)
2741 gnutls_assert ();
2742 return ret;
2745 ret =
2746 pubkey_verify_hashed_data (gnutls_x509_crt_get_pk_algorithm (crt, NULL), algo,
2747 hash, signature, &params);
2748 if (ret < 0)
2750 gnutls_assert ();
2753 /* release all allocated MPIs
2755 gnutls_pk_params_release(&params);
2757 return ret;
2761 * gnutls_x509_crt_get_crl_dist_points:
2762 * @cert: should contain a #gnutls_x509_crt_t structure
2763 * @seq: specifies the sequence number of the distribution point (0 for the first one, 1 for the second etc.)
2764 * @ret: is the place where the distribution point will be copied to
2765 * @ret_size: holds the size of ret.
2766 * @reason_flags: Revocation reasons flags.
2767 * @critical: will be non (0) if the extension is marked as critical (may be null)
2769 * This function retrieves the CRL distribution points (2.5.29.31),
2770 * contained in the given certificate in the X509v3 Certificate
2771 * Extensions.
2773 * @reason_flags should be an ORed sequence of
2774 * %GNUTLS_CRL_REASON_UNUSED, %GNUTLS_CRL_REASON_KEY_COMPROMISE,
2775 * %GNUTLS_CRL_REASON_CA_COMPROMISE,
2776 * %GNUTLS_CRL_REASON_AFFILIATION_CHANGED,
2777 * %GNUTLS_CRL_REASON_SUPERSEEDED,
2778 * %GNUTLS_CRL_REASON_CESSATION_OF_OPERATION,
2779 * %GNUTLS_CRL_REASON_CERTIFICATE_HOLD,
2780 * %GNUTLS_CRL_REASON_PRIVILEGE_WITHDRAWN,
2781 * %GNUTLS_CRL_REASON_AA_COMPROMISE, or (0) for all possible reasons.
2783 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER and updates @ret_size if
2784 * @ret_size is not enough to hold the distribution point, or the
2785 * type of the distribution point if everything was ok. The type is
2786 * one of the enumerated %gnutls_x509_subject_alt_name_t. If the
2787 * certificate does not have an Alternative name with the specified
2788 * sequence number then %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is
2789 * returned.
2792 gnutls_x509_crt_get_crl_dist_points (gnutls_x509_crt_t cert,
2793 unsigned int seq, void *ret,
2794 size_t * ret_size,
2795 unsigned int *reason_flags,
2796 unsigned int *critical)
2798 int result;
2799 gnutls_datum_t dist_points = { NULL, 0 };
2800 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2801 char name[ASN1_MAX_NAME_SIZE];
2802 int len;
2803 gnutls_x509_subject_alt_name_t type;
2804 uint8_t reasons[2];
2806 if (cert == NULL)
2808 gnutls_assert ();
2809 return GNUTLS_E_INVALID_REQUEST;
2812 if (*ret_size > 0 && ret)
2813 memset (ret, 0, *ret_size);
2814 else
2815 *ret_size = 0;
2817 if (reason_flags)
2818 *reason_flags = 0;
2820 result =
2821 _gnutls_x509_crt_get_extension (cert, "2.5.29.31", 0, &dist_points,
2822 critical);
2823 if (result < 0)
2825 return result;
2828 if (dist_points.size == 0 || dist_points.data == NULL)
2830 gnutls_assert ();
2831 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2834 result = asn1_create_element
2835 (_gnutls_get_pkix (), "PKIX1.CRLDistributionPoints", &c2);
2836 if (result != ASN1_SUCCESS)
2838 gnutls_assert ();
2839 _gnutls_free_datum (&dist_points);
2840 return _gnutls_asn2err (result);
2843 result = asn1_der_decoding (&c2, dist_points.data, dist_points.size, NULL);
2844 _gnutls_free_datum (&dist_points);
2846 if (result != ASN1_SUCCESS)
2848 gnutls_assert ();
2849 asn1_delete_structure (&c2);
2850 return _gnutls_asn2err (result);
2853 /* Return the different names from the first CRLDistr. point.
2854 * The whole thing is a mess.
2856 _gnutls_str_cpy (name, sizeof (name), "?1.distributionPoint.fullName");
2858 result = _gnutls_parse_general_name (c2, name, seq, ret, ret_size, NULL, 0);
2859 if (result < 0)
2861 asn1_delete_structure (&c2);
2862 return result;
2865 type = result;
2868 /* Read the CRL reasons.
2870 if (reason_flags)
2872 _gnutls_str_cpy (name, sizeof (name), "?1.reasons");
2874 reasons[0] = reasons[1] = 0;
2876 len = sizeof (reasons);
2877 result = asn1_read_value (c2, name, reasons, &len);
2879 if (result != ASN1_VALUE_NOT_FOUND && result != ASN1_SUCCESS)
2881 gnutls_assert ();
2882 asn1_delete_structure (&c2);
2883 return _gnutls_asn2err (result);
2886 *reason_flags = reasons[0] | (reasons[1] << 8);
2889 asn1_delete_structure (&c2);
2891 return type;
2895 * gnutls_x509_crt_get_key_purpose_oid:
2896 * @cert: should contain a #gnutls_x509_crt_t structure
2897 * @indx: This specifies which OID to return. Use (0) to get the first one.
2898 * @oid: a pointer to a buffer to hold the OID (may be null)
2899 * @oid_size: initially holds the size of @oid
2900 * @critical: output flag to indicate criticality of extension
2902 * This function will extract the key purpose OIDs of the Certificate
2903 * specified by the given index. These are stored in the Extended Key
2904 * Usage extension (2.5.29.37) See the GNUTLS_KP_* definitions for
2905 * human readable names.
2907 * If @oid is null then only the size will be filled. The @oid
2908 * returned will be null terminated, although @oid_size will not
2909 * account for the trailing null.
2911 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
2912 * not long enough, and in that case the *oid_size will be updated
2913 * with the required size. On success 0 is returned.
2916 gnutls_x509_crt_get_key_purpose_oid (gnutls_x509_crt_t cert,
2917 int indx, void *oid, size_t * oid_size,
2918 unsigned int *critical)
2920 char tmpstr[ASN1_MAX_NAME_SIZE];
2921 int result, len;
2922 gnutls_datum_t id;
2923 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2925 if (cert == NULL)
2927 gnutls_assert ();
2928 return GNUTLS_E_INVALID_REQUEST;
2931 if (oid)
2932 memset (oid, 0, *oid_size);
2933 else
2934 *oid_size = 0;
2936 if ((result =
2937 _gnutls_x509_crt_get_extension (cert, "2.5.29.37", 0, &id,
2938 critical)) < 0)
2940 return result;
2943 if (id.size == 0 || id.data == NULL)
2945 gnutls_assert ();
2946 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2949 result = asn1_create_element
2950 (_gnutls_get_pkix (), "PKIX1.ExtKeyUsageSyntax", &c2);
2951 if (result != ASN1_SUCCESS)
2953 gnutls_assert ();
2954 _gnutls_free_datum (&id);
2955 return _gnutls_asn2err (result);
2958 result = asn1_der_decoding (&c2, id.data, id.size, NULL);
2959 _gnutls_free_datum (&id);
2961 if (result != ASN1_SUCCESS)
2963 gnutls_assert ();
2964 asn1_delete_structure (&c2);
2965 return _gnutls_asn2err (result);
2968 indx++;
2969 /* create a string like "?1"
2971 snprintf (tmpstr, sizeof (tmpstr), "?%u", indx);
2973 len = *oid_size;
2974 result = asn1_read_value (c2, tmpstr, oid, &len);
2976 *oid_size = len;
2977 asn1_delete_structure (&c2);
2979 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
2981 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2984 if (result != ASN1_SUCCESS)
2986 gnutls_assert ();
2987 return _gnutls_asn2err (result);
2990 return 0;
2995 * gnutls_x509_crt_get_pk_rsa_raw:
2996 * @crt: Holds the certificate
2997 * @m: will hold the modulus
2998 * @e: will hold the public exponent
3000 * This function will export the RSA public key's parameters found in
3001 * the given structure. The new parameters will be allocated using
3002 * gnutls_malloc() and will be stored in the appropriate datum.
3004 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3007 gnutls_x509_crt_get_pk_rsa_raw (gnutls_x509_crt_t crt,
3008 gnutls_datum_t * m, gnutls_datum_t * e)
3010 int ret;
3011 gnutls_pk_params_st params;
3013 if (crt == NULL)
3015 gnutls_assert ();
3016 return GNUTLS_E_INVALID_REQUEST;
3019 ret = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
3020 if (ret != GNUTLS_PK_RSA)
3022 gnutls_assert ();
3023 return GNUTLS_E_INVALID_REQUEST;
3026 ret = _gnutls_x509_crt_get_mpis (crt, &params);
3027 if (ret < 0)
3029 gnutls_assert ();
3030 return ret;
3033 ret = _gnutls_mpi_dprint_lz (params.params[0], m);
3034 if (ret < 0)
3036 gnutls_assert ();
3037 goto cleanup;
3040 ret = _gnutls_mpi_dprint_lz (params.params[1], e);
3041 if (ret < 0)
3043 gnutls_assert ();
3044 _gnutls_free_datum (m);
3045 goto cleanup;
3048 ret = 0;
3050 cleanup:
3051 gnutls_pk_params_release(&params);
3052 return ret;
3056 * gnutls_x509_crt_get_pk_dsa_raw:
3057 * @crt: Holds the certificate
3058 * @p: will hold the p
3059 * @q: will hold the q
3060 * @g: will hold the g
3061 * @y: will hold the y
3063 * This function will export the DSA public key's parameters found in
3064 * the given certificate. The new parameters will be allocated using
3065 * gnutls_malloc() and will be stored in the appropriate datum.
3067 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3070 gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt,
3071 gnutls_datum_t * p, gnutls_datum_t * q,
3072 gnutls_datum_t * g, gnutls_datum_t * y)
3074 int ret;
3075 gnutls_pk_params_st params;
3077 if (crt == NULL)
3079 gnutls_assert ();
3080 return GNUTLS_E_INVALID_REQUEST;
3083 ret = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
3084 if (ret != GNUTLS_PK_DSA)
3086 gnutls_assert ();
3087 return GNUTLS_E_INVALID_REQUEST;
3090 ret = _gnutls_x509_crt_get_mpis (crt, &params);
3091 if (ret < 0)
3093 gnutls_assert ();
3094 return ret;
3098 /* P */
3099 ret = _gnutls_mpi_dprint_lz (params.params[0], p);
3100 if (ret < 0)
3102 gnutls_assert ();
3103 goto cleanup;
3106 /* Q */
3107 ret = _gnutls_mpi_dprint_lz (params.params[1], q);
3108 if (ret < 0)
3110 gnutls_assert ();
3111 _gnutls_free_datum (p);
3112 goto cleanup;
3116 /* G */
3117 ret = _gnutls_mpi_dprint_lz (params.params[2], g);
3118 if (ret < 0)
3120 gnutls_assert ();
3121 _gnutls_free_datum (p);
3122 _gnutls_free_datum (q);
3123 goto cleanup;
3127 /* Y */
3128 ret = _gnutls_mpi_dprint_lz (params.params[3], y);
3129 if (ret < 0)
3131 gnutls_assert ();
3132 _gnutls_free_datum (p);
3133 _gnutls_free_datum (g);
3134 _gnutls_free_datum (q);
3135 goto cleanup;
3138 ret = 0;
3140 cleanup:
3141 gnutls_pk_params_release(&params);
3142 return ret;
3147 * gnutls_x509_crt_list_import2:
3148 * @certs: The structures to store the parsed certificate. Must not be initialized.
3149 * @size: It will contain the size of the list.
3150 * @data: The PEM encoded certificate.
3151 * @format: One of DER or PEM.
3152 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
3154 * This function will convert the given PEM encoded certificate list
3155 * to the native gnutls_x509_crt_t format. The output will be stored
3156 * in @certs. They will be automatically initialized.
3158 * If the Certificate is PEM encoded it should have a header of "X509
3159 * CERTIFICATE", or "CERTIFICATE".
3161 * Returns: the number of certificates read or a negative error value.
3163 * Since: 3.0
3166 gnutls_x509_crt_list_import2 (gnutls_x509_crt_t ** certs,
3167 unsigned int * size,
3168 const gnutls_datum_t * data,
3169 gnutls_x509_crt_fmt_t format, unsigned int flags)
3171 unsigned int init = 1024;
3172 int ret;
3174 *certs = gnutls_malloc(sizeof(gnutls_x509_crt_t)*init);
3175 if (*certs == NULL)
3177 gnutls_assert();
3178 return GNUTLS_E_MEMORY_ERROR;
3181 ret = gnutls_x509_crt_list_import(*certs, &init, data, format, GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
3182 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
3184 *certs = gnutls_realloc_fast(*certs, sizeof(gnutls_x509_crt_t)*init);
3185 if (*certs == NULL)
3187 gnutls_assert();
3188 return GNUTLS_E_MEMORY_ERROR;
3191 ret = gnutls_x509_crt_list_import(*certs, &init, data, format, flags);
3194 if (ret < 0)
3196 gnutls_free(*certs);
3197 *certs = NULL;
3198 return ret;
3201 *size = init;
3202 return 0;
3205 static int check_if_sorted(gnutls_x509_crt_t * crt, int nr)
3207 char prev_dn[MAX_DN];
3208 char dn[MAX_DN];
3209 size_t prev_dn_size, dn_size;
3210 int i, ret;
3212 /* check if the X.509 list is ordered */
3213 if (nr > 1)
3216 for (i=0;i<nr;i++)
3218 if (i>0)
3220 dn_size = sizeof(dn);
3221 ret = gnutls_x509_crt_get_dn(crt[i], dn, &dn_size);
3222 if (ret < 0)
3224 ret = gnutls_assert_val(ret);
3225 goto cleanup;
3228 if (dn_size != prev_dn_size || memcmp(dn, prev_dn, dn_size) != 0)
3230 ret = gnutls_assert_val(GNUTLS_E_CERTIFICATE_LIST_UNSORTED);
3231 goto cleanup;
3235 prev_dn_size = sizeof(prev_dn);
3236 ret = gnutls_x509_crt_get_issuer_dn(crt[i], prev_dn, &prev_dn_size);
3237 if (ret < 0)
3239 ret = gnutls_assert_val(ret);
3240 goto cleanup;
3245 ret = 0;
3247 cleanup:
3248 return ret;
3253 * gnutls_x509_crt_list_import:
3254 * @certs: The structures to store the parsed certificate. Must not be initialized.
3255 * @cert_max: Initially must hold the maximum number of certs. It will be updated with the number of certs available.
3256 * @data: The PEM encoded certificate.
3257 * @format: One of DER or PEM.
3258 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
3260 * This function will convert the given PEM encoded certificate list
3261 * to the native gnutls_x509_crt_t format. The output will be stored
3262 * in @certs. They will be automatically initialized.
3264 * The flag %GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED will cause
3265 * import to fail if the certificates in the provided buffer are more
3266 * than the available structures. The %GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED
3267 * flag will cause the function to fail if the provided list is not
3268 * sorted from subject to issuer.
3270 * If the Certificate is PEM encoded it should have a header of "X509
3271 * CERTIFICATE", or "CERTIFICATE".
3273 * Returns: the number of certificates read or a negative error value.
3276 gnutls_x509_crt_list_import (gnutls_x509_crt_t * certs,
3277 unsigned int *cert_max,
3278 const gnutls_datum_t * data,
3279 gnutls_x509_crt_fmt_t format, unsigned int flags)
3281 int size;
3282 const char *ptr;
3283 gnutls_datum_t tmp;
3284 int ret, nocopy = 0;
3285 unsigned int count = 0, j;
3287 if (format == GNUTLS_X509_FMT_DER)
3289 if (*cert_max < 1)
3291 *cert_max = 1;
3292 return GNUTLS_E_SHORT_MEMORY_BUFFER;
3295 count = 1; /* import only the first one */
3297 ret = gnutls_x509_crt_init (&certs[0]);
3298 if (ret < 0)
3300 gnutls_assert ();
3301 goto error;
3304 ret = gnutls_x509_crt_import (certs[0], data, format);
3305 if (ret < 0)
3307 gnutls_assert ();
3308 goto error;
3311 *cert_max = 1;
3312 return 1;
3315 /* move to the certificate
3317 ptr = memmem (data->data, data->size,
3318 PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
3319 if (ptr == NULL)
3320 ptr = memmem (data->data, data->size,
3321 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
3323 if (ptr == NULL)
3324 return gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_FOUND);
3326 count = 0;
3330 if (count >= *cert_max)
3332 if (!(flags & GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED))
3333 break;
3334 else
3335 nocopy = 1;
3338 if (!nocopy)
3340 ret = gnutls_x509_crt_init (&certs[count]);
3341 if (ret < 0)
3343 gnutls_assert ();
3344 goto error;
3347 tmp.data = (void *) ptr;
3348 tmp.size = data->size - (ptr - (char *) data->data);
3350 ret =
3351 gnutls_x509_crt_import (certs[count], &tmp, GNUTLS_X509_FMT_PEM);
3352 if (ret < 0)
3354 gnutls_assert ();
3355 goto error;
3359 /* now we move ptr after the pem header
3361 ptr++;
3362 /* find the next certificate (if any)
3364 size = data->size - (ptr - (char *) data->data);
3366 if (size > 0)
3368 char *ptr2;
3370 ptr2 = memmem (ptr, size, PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
3371 if (ptr2 == NULL)
3372 ptr2 = memmem (ptr, size, PEM_CERT_SEP2,
3373 sizeof (PEM_CERT_SEP2) - 1);
3375 ptr = ptr2;
3377 else
3378 ptr = NULL;
3380 count++;
3382 while (ptr != NULL);
3384 *cert_max = count;
3386 if (flags & GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED)
3388 ret = check_if_sorted(certs, *cert_max);
3389 if (ret < 0)
3391 gnutls_assert();
3392 goto error;
3396 if (nocopy == 0)
3397 return count;
3398 else
3399 return GNUTLS_E_SHORT_MEMORY_BUFFER;
3401 error:
3402 for (j = 0; j < count; j++)
3403 gnutls_x509_crt_deinit (certs[j]);
3404 return ret;
3408 * gnutls_x509_crt_get_subject_unique_id:
3409 * @crt: Holds the certificate
3410 * @buf: user allocated memory buffer, will hold the unique id
3411 * @buf_size: size of user allocated memory buffer (on input), will hold
3412 * actual size of the unique ID on return.
3414 * This function will extract the subjectUniqueID value (if present) for
3415 * the given certificate.
3417 * If the user allocated memory buffer is not large enough to hold the
3418 * full subjectUniqueID, then a GNUTLS_E_SHORT_MEMORY_BUFFER error will be
3419 * returned, and buf_size will be set to the actual length.
3421 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3424 gnutls_x509_crt_get_subject_unique_id (gnutls_x509_crt_t crt, char *buf,
3425 size_t * buf_size)
3427 int result;
3428 gnutls_datum_t datum = { NULL, 0 };
3430 result =
3431 _gnutls_x509_read_value (crt->cert, "tbsCertificate.subjectUniqueID",
3432 &datum, 2);
3434 if (datum.size > *buf_size)
3435 { /* then we're not going to fit */
3436 *buf_size = datum.size;
3437 buf[0] = '\0';
3438 result = GNUTLS_E_SHORT_MEMORY_BUFFER;
3440 else
3442 *buf_size = datum.size;
3443 memcpy (buf, datum.data, datum.size);
3446 _gnutls_free_datum (&datum);
3448 return result;
3452 * gnutls_x509_crt_get_issuer_unique_id:
3453 * @crt: Holds the certificate
3454 * @buf: user allocated memory buffer, will hold the unique id
3455 * @buf_size: size of user allocated memory buffer (on input), will hold
3456 * actual size of the unique ID on return.
3458 * This function will extract the issuerUniqueID value (if present) for
3459 * the given certificate.
3461 * If the user allocated memory buffer is not large enough to hold the
3462 * full subjectUniqueID, then a GNUTLS_E_SHORT_MEMORY_BUFFER error will be
3463 * returned, and buf_size will be set to the actual length.
3465 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3467 * Since: 2.12.0
3470 gnutls_x509_crt_get_issuer_unique_id (gnutls_x509_crt_t crt, char *buf,
3471 size_t * buf_size)
3473 int result;
3474 gnutls_datum_t datum = { NULL, 0 };
3476 result =
3477 _gnutls_x509_read_value (crt->cert, "tbsCertificate.issuerUniqueID",
3478 &datum, 2);
3480 if (datum.size > *buf_size)
3481 { /* then we're not going to fit */
3482 *buf_size = datum.size;
3483 buf[0] = '\0';
3484 result = GNUTLS_E_SHORT_MEMORY_BUFFER;
3486 else
3488 *buf_size = datum.size;
3489 memcpy (buf, datum.data, datum.size);
3492 _gnutls_free_datum (&datum);
3494 return result;
3497 static int
3498 _gnutls_parse_aia (ASN1_TYPE src,
3499 unsigned int seq,
3500 int what,
3501 gnutls_datum_t * data)
3503 int len;
3504 char nptr[ASN1_MAX_NAME_SIZE];
3505 int result;
3506 gnutls_datum_t d;
3507 const char *oid = NULL;
3509 seq++; /* 0->1, 1->2 etc */
3510 switch (what)
3512 case GNUTLS_IA_ACCESSMETHOD_OID:
3513 snprintf (nptr, sizeof (nptr), "?%u.accessMethod", seq);
3514 break;
3516 case GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE:
3517 snprintf (nptr, sizeof (nptr), "?%u.accessLocation", seq);
3518 break;
3520 case GNUTLS_IA_CAISSUERS_URI:
3521 oid = GNUTLS_OID_AD_CAISSUERS;
3522 /* fall through */
3524 case GNUTLS_IA_OCSP_URI:
3525 if (oid == NULL)
3526 oid = GNUTLS_OID_AD_OCSP;
3528 char tmpoid[20];
3529 snprintf (nptr, sizeof (nptr), "?%u.accessMethod", seq);
3530 len = sizeof (tmpoid);
3531 result = asn1_read_value (src, nptr, tmpoid, &len);
3533 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
3534 return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
3536 if (result != ASN1_SUCCESS)
3538 gnutls_assert ();
3539 return _gnutls_asn2err (result);
3541 if ((unsigned)len != strlen (oid) + 1 || memcmp (tmpoid, oid, len) != 0)
3542 return gnutls_assert_val(GNUTLS_E_UNKNOWN_ALGORITHM);
3544 /* fall through */
3546 case GNUTLS_IA_URI:
3547 snprintf (nptr, sizeof (nptr),
3548 "?%u.accessLocation.uniformResourceIdentifier", seq);
3549 break;
3551 default:
3552 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
3555 len = 0;
3556 result = asn1_read_value (src, nptr, NULL, &len);
3557 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
3558 return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
3560 if (result != ASN1_MEM_ERROR)
3562 gnutls_assert ();
3563 return _gnutls_asn2err (result);
3566 d.size = len;
3568 d.data = gnutls_malloc (d.size);
3569 if (d.data == NULL)
3570 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
3572 result = asn1_read_value (src, nptr, d.data, &len);
3573 if (result != ASN1_SUCCESS)
3575 gnutls_assert ();
3576 gnutls_free (d.data);
3577 return _gnutls_asn2err (result);
3580 if (data)
3582 data->data = d.data;
3583 data->size = d.size;
3585 else
3586 gnutls_free (d.data);
3588 return 0;
3592 * gnutls_x509_crt_get_authority_info_access:
3593 * @crt: Holds the certificate
3594 * @seq: specifies the sequence number of the access descriptor (0 for the first one, 1 for the second etc.)
3595 * @what: what data to get, a #gnutls_info_access_what_t type.
3596 * @data: output data to be freed with gnutls_free().
3597 * @critical: pointer to output integer that is set to non-0 if the extension is marked as critical (may be %NULL)
3599 * This function extracts the Authority Information Access (AIA)
3600 * extension, see RFC 5280 section 4.2.2.1 for more information. The
3601 * AIA extension holds a sequence of AccessDescription (AD) data:
3603 * <informalexample><programlisting>
3604 * AuthorityInfoAccessSyntax ::=
3605 * SEQUENCE SIZE (1..MAX) OF AccessDescription
3607 * AccessDescription ::= SEQUENCE {
3608 * accessMethod OBJECT IDENTIFIER,
3609 * accessLocation GeneralName }
3610 * </programlisting></informalexample>
3612 * The @seq input parameter is used to indicate which member of the
3613 * sequence the caller is interested in. The first member is 0, the
3614 * second member 1 and so on. When the @seq value is out of bounds,
3615 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
3617 * The type of data returned in @data is specified via @what which
3618 * should be #gnutls_info_access_what_t values.
3620 * If @what is %GNUTLS_IA_ACCESSMETHOD_OID then @data will hold the
3621 * accessMethod OID (e.g., "1.3.6.1.5.5.7.48.1").
3623 * If @what is %GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE, @data will
3624 * hold the accessLocation GeneralName type (e.g.,
3625 * "uniformResourceIdentifier").
3627 * If @what is %GNUTLS_IA_URI, @data will hold the accessLocation URI
3628 * data. Requesting this @what value leads to an error if the
3629 * accessLocation is not of the "uniformResourceIdentifier" type.
3631 * If @what is %GNUTLS_IA_OCSP_URI, @data will hold the OCSP URI.
3632 * Requesting this @what value leads to an error if the accessMethod
3633 * is not 1.3.6.1.5.5.7.48.1 aka OSCP, or if accessLocation is not of
3634 * the "uniformResourceIdentifier" type.
3636 * If @what is %GNUTLS_IA_CAISSUERS_URI, @data will hold the caIssuers
3637 * URI. Requesting this @what value leads to an error if the
3638 * accessMethod is not 1.3.6.1.5.5.7.48.2 aka caIssuers, or if
3639 * accessLocation is not of the "uniformResourceIdentifier" type.
3641 * More @what values may be allocated in the future as needed.
3643 * If @data is NULL, the function does the same without storing the
3644 * output data, that is, it will set @critical and do error checking
3645 * as usual.
3647 * The value of the critical flag is returned in *@critical. Supply a
3648 * NULL @critical if you want the function to make sure the extension
3649 * is non-critical, as required by RFC 5280.
3651 * Returns: %GNUTLS_E_SUCCESS on success, %GNUTLS_E_INVALID_REQUEST on
3652 * invalid @crt, %GNUTLS_E_CONSTRAINT_ERROR if the extension is
3653 * incorrectly marked as critical (use a non-NULL @critical to
3654 * override), %GNUTLS_E_UNKNOWN_ALGORITHM if the requested OID does
3655 * not match (e.g., when using %GNUTLS_IA_OCSP_URI), otherwise a
3656 * negative error code.
3658 * Since: 3.0
3661 gnutls_x509_crt_get_authority_info_access (gnutls_x509_crt_t crt,
3662 unsigned int seq,
3663 int what,
3664 gnutls_datum_t * data,
3665 unsigned int *critical)
3667 int ret;
3668 gnutls_datum_t aia;
3669 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
3671 if (crt == NULL)
3673 gnutls_assert ();
3674 return GNUTLS_E_INVALID_REQUEST;
3677 if ((ret = _gnutls_x509_crt_get_extension (crt, GNUTLS_OID_AIA, 0, &aia,
3678 critical)) < 0)
3679 return ret;
3681 if (aia.size == 0 || aia.data == NULL)
3683 gnutls_assert ();
3684 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3687 if (critical && *critical)
3688 return GNUTLS_E_CONSTRAINT_ERROR;
3690 ret = asn1_create_element (_gnutls_get_pkix (),
3691 "PKIX1.AuthorityInfoAccessSyntax", &c2);
3692 if (ret != ASN1_SUCCESS)
3694 gnutls_assert ();
3695 _gnutls_free_datum (&aia);
3696 return _gnutls_asn2err (ret);
3699 ret = asn1_der_decoding (&c2, aia.data, aia.size, NULL);
3700 /* asn1_print_structure (stdout, c2, "", ASN1_PRINT_ALL); */
3701 _gnutls_free_datum (&aia);
3702 if (ret != ASN1_SUCCESS)
3704 gnutls_assert ();
3705 asn1_delete_structure (&c2);
3706 return _gnutls_asn2err (ret);
3709 ret = _gnutls_parse_aia (c2, seq, what, data);
3711 asn1_delete_structure (&c2);
3712 if (ret < 0)
3713 gnutls_assert ();
3715 return ret;