avoid duplicate asn1 structure initialization.
[gnutls.git] / lib / x509 / x509.c
blob61c85983f611b6a7088f9538b41d27ed63ff91ce
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->expanded)
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 cert->expanded = 1;
236 /* Since we do not want to disable any extension
238 cert->use_extensions = 1;
239 if (need_free)
240 _gnutls_free_datum (&_data);
242 return 0;
244 cleanup:
245 if (need_free)
246 _gnutls_free_datum (&_data);
247 return result;
252 * gnutls_x509_crt_get_issuer_dn:
253 * @cert: should contain a #gnutls_x509_crt_t structure
254 * @buf: a pointer to a structure to hold the name (may be null)
255 * @buf_size: initially holds the size of @buf
257 * This function will copy the name of the Certificate issuer in the
258 * provided buffer. The name will be in the form
259 * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC4514. The output string
260 * will be ASCII or UTF-8 encoded, depending on the certificate data.
262 * If @buf is null then only the size will be filled.
264 * Returns: GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
265 * long enough, and in that case the @buf_size will be updated with
266 * the required size. On success 0 is returned.
269 gnutls_x509_crt_get_issuer_dn (gnutls_x509_crt_t cert, char *buf,
270 size_t * buf_size)
272 if (cert == NULL)
274 gnutls_assert ();
275 return GNUTLS_E_INVALID_REQUEST;
278 return _gnutls_x509_parse_dn (cert->cert,
279 "tbsCertificate.issuer.rdnSequence", buf,
280 buf_size);
284 * gnutls_x509_crt_get_issuer_dn_by_oid:
285 * @cert: should contain a #gnutls_x509_crt_t structure
286 * @oid: holds an Object Identified in null terminated string
287 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use (0) to get the first one.
288 * @raw_flag: If non (0) returns the raw DER data of the DN part.
289 * @buf: a pointer to a structure to hold the name (may be null)
290 * @buf_size: initially holds the size of @buf
292 * This function will extract the part of the name of the Certificate
293 * issuer specified by the given OID. The output, if the raw flag is not
294 * used, will be encoded as described in RFC4514. Thus a string that is
295 * ASCII or UTF-8 encoded, depending on the certificate data.
297 * Some helper macros with popular OIDs can be found in gnutls/x509.h
298 * If raw flag is (0), this function will only return known OIDs as
299 * text. Other OIDs will be DER encoded, as described in RFC4514 --
300 * in hex format with a '#' prefix. You can check about known OIDs
301 * using gnutls_x509_dn_oid_known().
303 * If @buf is null then only the size will be filled. If the @raw_flag
304 * is not specified the output is always null terminated, although the
305 * @buf_size will not include the null character.
307 * Returns: GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
308 * long enough, and in that case the @buf_size will be updated
309 * with the required size. On success 0 is returned.
312 gnutls_x509_crt_get_issuer_dn_by_oid (gnutls_x509_crt_t cert,
313 const char *oid, int indx,
314 unsigned int raw_flag, void *buf,
315 size_t * buf_size)
317 if (cert == NULL)
319 gnutls_assert ();
320 return GNUTLS_E_INVALID_REQUEST;
323 return _gnutls_x509_parse_dn_oid (cert->cert,
324 "tbsCertificate.issuer.rdnSequence",
325 oid, indx, raw_flag, buf, buf_size);
329 * gnutls_x509_crt_get_issuer_dn_oid:
330 * @cert: should contain a #gnutls_x509_crt_t structure
331 * @indx: This specifies which OID to return. Use (0) to get the first one.
332 * @oid: a pointer to a buffer to hold the OID (may be null)
333 * @oid_size: initially holds the size of @oid
335 * This function will extract the OIDs of the name of the Certificate
336 * issuer specified by the given index.
338 * If @oid is null then only the size will be filled. The @oid
339 * returned will be null terminated, although @oid_size will not
340 * account for the trailing null.
342 * Returns: GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
343 * long enough, and in that case the @oid_size will be updated
344 * with the required size. On success 0 is returned.
347 gnutls_x509_crt_get_issuer_dn_oid (gnutls_x509_crt_t cert,
348 int indx, void *oid, size_t * oid_size)
350 if (cert == NULL)
352 gnutls_assert ();
353 return GNUTLS_E_INVALID_REQUEST;
356 return _gnutls_x509_get_dn_oid (cert->cert,
357 "tbsCertificate.issuer.rdnSequence",
358 indx, oid, oid_size);
362 * gnutls_x509_crt_get_dn:
363 * @cert: should contain a #gnutls_x509_crt_t structure
364 * @buf: a pointer to a structure to hold the name (may be null)
365 * @buf_size: initially holds the size of @buf
367 * This function will copy the name of the Certificate in the provided
368 * buffer. The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
369 * described in RFC4514. The output string will be ASCII or UTF-8
370 * encoded, depending on the certificate data.
372 * If @buf is null then only the size will be filled.
374 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
375 * long enough, and in that case the @buf_size will be updated
376 * with the required size. On success 0 is returned.
379 gnutls_x509_crt_get_dn (gnutls_x509_crt_t cert, char *buf,
380 size_t * buf_size)
382 if (cert == NULL)
384 gnutls_assert ();
385 return GNUTLS_E_INVALID_REQUEST;
388 return _gnutls_x509_parse_dn (cert->cert,
389 "tbsCertificate.subject.rdnSequence", buf,
390 buf_size);
394 * gnutls_x509_crt_get_dn_by_oid:
395 * @cert: should contain a #gnutls_x509_crt_t structure
396 * @oid: holds an Object Identified in null terminated string
397 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use (0) to get the first one.
398 * @raw_flag: If non (0) returns the raw DER data of the DN part.
399 * @buf: a pointer where the DN part will be copied (may be null).
400 * @buf_size: initially holds the size of @buf
402 * This function will extract the part of the name of the Certificate
403 * subject specified by the given OID. The output, if the raw flag is
404 * not used, will be encoded as described in RFC4514. Thus a string
405 * that is ASCII or UTF-8 encoded, depending on the certificate data.
407 * Some helper macros with popular OIDs can be found in gnutls/x509.h
408 * If raw flag is (0), this function will only return known OIDs as
409 * text. Other OIDs will be DER encoded, as described in RFC4514 --
410 * in hex format with a '#' prefix. You can check about known OIDs
411 * using gnutls_x509_dn_oid_known().
413 * If @buf is null then only the size will be filled. If the @raw_flag
414 * is not specified the output is always null terminated, although the
415 * @buf_size will not include the null character.
417 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
418 * not long enough, and in that case the *buf_size will be updated
419 * with the required size. On success 0 is returned.
422 gnutls_x509_crt_get_dn_by_oid (gnutls_x509_crt_t cert, const char *oid,
423 int indx, unsigned int raw_flag,
424 void *buf, size_t * buf_size)
426 if (cert == NULL)
428 gnutls_assert ();
429 return GNUTLS_E_INVALID_REQUEST;
432 return _gnutls_x509_parse_dn_oid (cert->cert,
433 "tbsCertificate.subject.rdnSequence",
434 oid, indx, raw_flag, buf, buf_size);
438 * gnutls_x509_crt_get_dn_oid:
439 * @cert: should contain a #gnutls_x509_crt_t structure
440 * @indx: This specifies which OID to return. Use (0) to get the first one.
441 * @oid: a pointer to a buffer to hold the OID (may be null)
442 * @oid_size: initially holds the size of @oid
444 * This function will extract the OIDs of the name of the Certificate
445 * subject specified by the given index.
447 * If @oid is null then only the size will be filled. The @oid
448 * returned will be null terminated, although @oid_size will not
449 * account for the trailing null.
451 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
452 * not long enough, and in that case the @oid_size will be updated
453 * with the required size. On success 0 is returned.
456 gnutls_x509_crt_get_dn_oid (gnutls_x509_crt_t cert,
457 int indx, void *oid, size_t * oid_size)
459 if (cert == NULL)
461 gnutls_assert ();
462 return GNUTLS_E_INVALID_REQUEST;
465 return _gnutls_x509_get_dn_oid (cert->cert,
466 "tbsCertificate.subject.rdnSequence",
467 indx, oid, oid_size);
471 * gnutls_x509_crt_get_signature_algorithm:
472 * @cert: should contain a #gnutls_x509_crt_t structure
474 * This function will return a value of the #gnutls_sign_algorithm_t
475 * enumeration that is the signature algorithm that has been used to
476 * sign this certificate.
478 * Returns: a #gnutls_sign_algorithm_t value, or a negative error code on
479 * error.
482 gnutls_x509_crt_get_signature_algorithm (gnutls_x509_crt_t cert)
484 return _gnutls_x509_get_signature_algorithm(cert->cert, "signatureAlgorithm.algorithm");
488 * gnutls_x509_crt_get_signature:
489 * @cert: should contain a #gnutls_x509_crt_t structure
490 * @sig: a pointer where the signature part will be copied (may be null).
491 * @sizeof_sig: initially holds the size of @sig
493 * This function will extract the signature field of a certificate.
495 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
496 * negative error value. and a negative error code on error.
499 gnutls_x509_crt_get_signature (gnutls_x509_crt_t cert,
500 char *sig, size_t * sizeof_sig)
502 int result;
503 unsigned int bits;
504 int len;
506 if (cert == NULL)
508 gnutls_assert ();
509 return GNUTLS_E_INVALID_REQUEST;
512 len = 0;
513 result = asn1_read_value (cert->cert, "signature", NULL, &len);
514 if (result != ASN1_MEM_ERROR)
516 gnutls_assert ();
517 return _gnutls_asn2err (result);
520 bits = len;
521 if (bits % 8 != 0)
523 gnutls_assert ();
524 return GNUTLS_E_CERTIFICATE_ERROR;
527 len = bits / 8;
529 if (*sizeof_sig < (unsigned int) len)
531 *sizeof_sig = len;
532 return GNUTLS_E_SHORT_MEMORY_BUFFER;
535 result = asn1_read_value (cert->cert, "signature", sig, &len);
536 if (result != ASN1_SUCCESS)
538 gnutls_assert ();
539 return _gnutls_asn2err (result);
542 return 0;
546 * gnutls_x509_crt_get_version:
547 * @cert: should contain a #gnutls_x509_crt_t structure
549 * This function will return the version of the specified Certificate.
551 * Returns: version of certificate, or a negative error code on error.
554 gnutls_x509_crt_get_version (gnutls_x509_crt_t cert)
556 uint8_t version[8];
557 int len, result;
559 if (cert == NULL)
561 gnutls_assert ();
562 return GNUTLS_E_INVALID_REQUEST;
565 len = sizeof (version);
566 if ((result =
567 asn1_read_value (cert->cert, "tbsCertificate.version", version,
568 &len)) != ASN1_SUCCESS)
571 if (result == ASN1_ELEMENT_NOT_FOUND)
572 return 1; /* the DEFAULT version */
573 gnutls_assert ();
574 return _gnutls_asn2err (result);
577 return (int) version[0] + 1;
581 * gnutls_x509_crt_get_activation_time:
582 * @cert: should contain a #gnutls_x509_crt_t structure
584 * This function will return the time this Certificate was or will be
585 * activated.
587 * Returns: activation time, or (time_t)-1 on error.
589 time_t
590 gnutls_x509_crt_get_activation_time (gnutls_x509_crt_t cert)
592 if (cert == NULL)
594 gnutls_assert ();
595 return (time_t) - 1;
598 return _gnutls_x509_get_time (cert->cert,
599 "tbsCertificate.validity.notBefore", 0);
603 * gnutls_x509_crt_get_expiration_time:
604 * @cert: should contain a #gnutls_x509_crt_t structure
606 * This function will return the time this Certificate was or will be
607 * expired.
609 * Returns: expiration time, or (time_t)-1 on error.
611 time_t
612 gnutls_x509_crt_get_expiration_time (gnutls_x509_crt_t cert)
614 if (cert == NULL)
616 gnutls_assert ();
617 return (time_t) - 1;
620 return _gnutls_x509_get_time (cert->cert,
621 "tbsCertificate.validity.notAfter", 0);
625 * gnutls_x509_crt_get_private_key_usage_period:
626 * @cert: should contain a #gnutls_x509_crt_t structure
627 * @activation: The activation time
628 * @expiration: The expiration time
629 * @critical: the extension status
631 * This function will return the expiration and activation
632 * times of the private key of the certificate. It relies on
633 * the PKIX extension 2.5.29.16 being present.
635 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
636 * if the extension is not present, otherwise a negative error value.
639 gnutls_x509_crt_get_private_key_usage_period (gnutls_x509_crt_t cert, time_t* activation, time_t* expiration,
640 unsigned int *critical)
642 int result, ret;
643 gnutls_datum_t der = {NULL, 0};
644 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
646 if (cert == NULL)
648 gnutls_assert ();
649 return GNUTLS_E_INVALID_REQUEST;
652 ret =
653 _gnutls_x509_crt_get_extension (cert, "2.5.29.16", 0, &der,
654 critical);
655 if (ret < 0)
656 return gnutls_assert_val(ret);
658 if (der.size == 0 || der.data == NULL)
659 return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
661 result = asn1_create_element
662 (_gnutls_get_pkix (), "PKIX1.PrivateKeyUsagePeriod", &c2);
663 if (result != ASN1_SUCCESS)
665 gnutls_assert ();
666 ret = _gnutls_asn2err (result);
667 goto cleanup;
670 result = asn1_der_decoding (&c2, der.data, der.size, NULL);
671 if (result != ASN1_SUCCESS)
673 gnutls_assert ();
674 ret = _gnutls_asn2err (result);
675 goto cleanup;
678 if (activation)
679 *activation = _gnutls_x509_get_time (c2,
680 "notBefore", 1);
682 if (expiration)
683 *expiration = _gnutls_x509_get_time (c2,
684 "notAfter", 1);
686 ret = 0;
688 cleanup:
689 _gnutls_free_datum(&der);
690 asn1_delete_structure (&c2);
692 return ret;
697 * gnutls_x509_crt_get_serial:
698 * @cert: should contain a #gnutls_x509_crt_t structure
699 * @result: The place where the serial number will be copied
700 * @result_size: Holds the size of the result field.
702 * This function will return the X.509 certificate's serial number.
703 * This is obtained by the X509 Certificate serialNumber field. Serial
704 * is not always a 32 or 64bit number. Some CAs use large serial
705 * numbers, thus it may be wise to handle it as something uint8_t.
707 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
708 * negative error value.
711 gnutls_x509_crt_get_serial (gnutls_x509_crt_t cert, void *result,
712 size_t * result_size)
714 int ret, len;
716 if (cert == NULL)
718 gnutls_assert ();
719 return GNUTLS_E_INVALID_REQUEST;
722 len = *result_size;
723 ret =
724 asn1_read_value (cert->cert, "tbsCertificate.serialNumber", result, &len);
725 *result_size = len;
727 if (ret != ASN1_SUCCESS)
729 gnutls_assert ();
730 return _gnutls_asn2err (ret);
733 return 0;
737 * gnutls_x509_crt_get_subject_key_id:
738 * @cert: should contain a #gnutls_x509_crt_t structure
739 * @ret: The place where the identifier will be copied
740 * @ret_size: Holds the size of the result field.
741 * @critical: will be non (0) if the extension is marked as critical (may be null)
743 * This function will return the X.509v3 certificate's subject key
744 * identifier. This is obtained by the X.509 Subject Key identifier
745 * extension field (2.5.29.14).
747 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
748 * if the extension is not present, otherwise a negative error value.
751 gnutls_x509_crt_get_subject_key_id (gnutls_x509_crt_t cert, void *ret,
752 size_t * ret_size, unsigned int *critical)
754 int result, len;
755 gnutls_datum_t id;
756 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
758 if (cert == NULL)
760 gnutls_assert ();
761 return GNUTLS_E_INVALID_REQUEST;
765 if (ret)
766 memset (ret, 0, *ret_size);
767 else
768 *ret_size = 0;
770 if ((result =
771 _gnutls_x509_crt_get_extension (cert, "2.5.29.14", 0, &id,
772 critical)) < 0)
774 return result;
777 if (id.size == 0 || id.data == NULL)
779 gnutls_assert ();
780 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
783 result = asn1_create_element
784 (_gnutls_get_pkix (), "PKIX1.SubjectKeyIdentifier", &c2);
785 if (result != ASN1_SUCCESS)
787 gnutls_assert ();
788 _gnutls_free_datum (&id);
789 return _gnutls_asn2err (result);
792 result = asn1_der_decoding (&c2, id.data, id.size, NULL);
793 _gnutls_free_datum (&id);
795 if (result != ASN1_SUCCESS)
797 gnutls_assert ();
798 asn1_delete_structure (&c2);
799 return _gnutls_asn2err (result);
802 len = *ret_size;
803 result = asn1_read_value (c2, "", ret, &len);
805 *ret_size = len;
806 asn1_delete_structure (&c2);
808 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
810 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
813 if (result != ASN1_SUCCESS)
815 if (result != ASN1_MEM_ERROR)
816 gnutls_assert ();
817 return _gnutls_asn2err (result);
820 return 0;
823 static int
824 _get_authority_key_id (gnutls_x509_crt_t cert, ASN1_TYPE *c2,
825 unsigned int *critical)
827 int ret;
828 gnutls_datum_t id;
830 *c2 = ASN1_TYPE_EMPTY;
832 if (cert == NULL)
834 gnutls_assert ();
835 return GNUTLS_E_INVALID_REQUEST;
838 if ((ret =
839 _gnutls_x509_crt_get_extension (cert, "2.5.29.35", 0, &id,
840 critical)) < 0)
842 return gnutls_assert_val(ret);
845 if (id.size == 0 || id.data == NULL)
847 gnutls_assert ();
848 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
851 ret = asn1_create_element
852 (_gnutls_get_pkix (), "PKIX1.AuthorityKeyIdentifier", c2);
853 if (ret != ASN1_SUCCESS)
855 gnutls_assert ();
856 _gnutls_free_datum (&id);
857 return _gnutls_asn2err (ret);
860 ret = asn1_der_decoding (c2, id.data, id.size, NULL);
861 _gnutls_free_datum (&id);
863 if (ret != ASN1_SUCCESS)
865 gnutls_assert ();
866 asn1_delete_structure (c2);
867 return _gnutls_asn2err (ret);
870 return 0;
874 * gnutls_x509_crt_get_authority_key_gn_serial:
875 * @cert: should contain a #gnutls_x509_crt_t structure
876 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
877 * @alt: is the place where the alternative name will be copied to
878 * @alt_size: holds the size of alt.
879 * @alt_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
880 * @serial: buffer to store the serial number (may be null)
881 * @serial_size: Holds the size of the serial field (may be null)
882 * @critical: will be non (0) if the extension is marked as critical (may be null)
884 * This function will return the X.509 authority key
885 * identifier when stored as a general name (authorityCertIssuer)
886 * and serial number.
888 * Because more than one general names might be stored
889 * @seq can be used as a counter to request them all until
890 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
892 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
893 * if the extension is not present, otherwise a negative error value.
895 * Since: 3.0
898 gnutls_x509_crt_get_authority_key_gn_serial (gnutls_x509_crt_t cert, unsigned int seq, void *alt,
899 size_t * alt_size, unsigned int *alt_type,
900 void* serial, size_t *serial_size,
901 unsigned int *critical)
903 int ret, result, len;
904 ASN1_TYPE c2;
906 ret = _get_authority_key_id(cert, &c2, critical);
907 if (ret < 0)
908 return gnutls_assert_val(ret);
910 ret =
911 _gnutls_parse_general_name (c2, "authorityCertIssuer", seq, alt, alt_size, alt_type,
913 if (ret < 0)
915 ret = gnutls_assert_val(ret);
916 goto fail;
919 if (serial)
921 len = *serial_size;
922 result = asn1_read_value (c2, "authorityCertSerialNumber", serial, &len);
924 *serial_size = len;
926 if (result < 0)
928 ret = _gnutls_asn2err(result);
929 goto fail;
934 ret = 0;
936 fail:
937 asn1_delete_structure (&c2);
939 return ret;
943 * gnutls_x509_crt_get_authority_key_id:
944 * @cert: should contain a #gnutls_x509_crt_t structure
945 * @id: The place where the identifier will be copied
946 * @id_size: Holds the size of the id field.
947 * @critical: will be non (0) if the extension is marked as critical (may be null)
949 * This function will return the X.509v3 certificate authority's key
950 * identifier. This is obtained by the X.509 Authority Key
951 * identifier extension field (2.5.29.35). Note that this function
952 * only returns the keyIdentifier field of the extension and
953 * %GNUTLS_E_X509_UNSUPPORTED_EXTENSION, if the extension contains
954 * the name and serial number of the certificate. In that case
955 * gnutls_x509_crt_get_authority_key_gn_serial() may be used.
957 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
958 * if the extension is not present, otherwise a negative error value.
961 gnutls_x509_crt_get_authority_key_id (gnutls_x509_crt_t cert, void *id,
962 size_t * id_size,
963 unsigned int *critical)
965 int ret, result, len;
966 ASN1_TYPE c2;
968 ret = _get_authority_key_id(cert, &c2, critical);
969 if (ret < 0)
970 return gnutls_assert_val(ret);
972 len = *id_size;
973 result = asn1_read_value (c2, "keyIdentifier", id, &len);
975 *id_size = len;
976 asn1_delete_structure (&c2);
978 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
979 return gnutls_assert_val(GNUTLS_E_X509_UNSUPPORTED_EXTENSION);
981 if (result != ASN1_SUCCESS)
983 if (result != ASN1_MEM_ERROR)
984 gnutls_assert ();
985 return _gnutls_asn2err (result);
988 return 0;
992 * gnutls_x509_crt_get_pk_algorithm:
993 * @cert: should contain a #gnutls_x509_crt_t structure
994 * @bits: if bits is non null it will hold the size of the parameters' in bits
996 * This function will return the public key algorithm of an X.509
997 * certificate.
999 * If bits is non null, it should have enough size to hold the parameters
1000 * size in bits. For RSA the bits returned is the modulus.
1001 * For DSA the bits returned are of the public
1002 * exponent.
1004 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
1005 * success, or a negative error code on error.
1008 gnutls_x509_crt_get_pk_algorithm (gnutls_x509_crt_t cert, unsigned int *bits)
1010 int result;
1012 if (cert == NULL)
1014 gnutls_assert ();
1015 return GNUTLS_E_INVALID_REQUEST;
1018 if (bits)
1019 *bits = 0;
1021 result =
1022 _gnutls_x509_get_pk_algorithm (cert->cert,
1023 "tbsCertificate.subjectPublicKeyInfo",
1024 bits);
1026 if (result < 0)
1028 gnutls_assert ();
1029 return result;
1032 return result;
1036 inline static int
1037 is_type_printable (int type)
1039 if (type == GNUTLS_SAN_DNSNAME || type == GNUTLS_SAN_RFC822NAME ||
1040 type == GNUTLS_SAN_URI)
1041 return 1;
1042 else
1043 return 0;
1046 #define XMPP_OID "1.3.6.1.5.5.7.8.5"
1048 /* returns the type and the name on success.
1049 * Type is also returned as a parameter in case of an error.
1052 _gnutls_parse_general_name (ASN1_TYPE src, const char *src_name,
1053 int seq, void *name, size_t * name_size,
1054 unsigned int *ret_type, int othername_oid)
1056 int len;
1057 char nptr[ASN1_MAX_NAME_SIZE];
1058 int result;
1059 char choice_type[128];
1060 gnutls_x509_subject_alt_name_t type;
1062 seq++; /* 0->1, 1->2 etc */
1064 if (src_name[0] != 0)
1065 snprintf (nptr, sizeof (nptr), "%s.?%u", src_name, seq);
1066 else
1067 snprintf (nptr, sizeof (nptr), "?%u", seq);
1069 len = sizeof (choice_type);
1070 result = asn1_read_value (src, nptr, choice_type, &len);
1072 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
1074 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1077 if (result != ASN1_SUCCESS)
1079 gnutls_assert ();
1080 return _gnutls_asn2err (result);
1084 type = _gnutls_x509_san_find_type (choice_type);
1085 if (type == (gnutls_x509_subject_alt_name_t) - 1)
1087 gnutls_assert ();
1088 return GNUTLS_E_X509_UNKNOWN_SAN;
1091 if (ret_type)
1092 *ret_type = type;
1094 if (type == GNUTLS_SAN_OTHERNAME)
1096 if (othername_oid)
1097 _gnutls_str_cat (nptr, sizeof (nptr), ".otherName.type-id");
1098 else
1099 _gnutls_str_cat (nptr, sizeof (nptr), ".otherName.value");
1101 len = *name_size;
1102 result = asn1_read_value (src, nptr, name, &len);
1103 *name_size = len;
1105 if (result == ASN1_MEM_ERROR)
1106 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1108 if (result != ASN1_SUCCESS)
1110 gnutls_assert ();
1111 return _gnutls_asn2err (result);
1114 if (othername_oid)
1116 if ((unsigned)len > strlen (XMPP_OID) && strcmp (name, XMPP_OID) == 0)
1117 type = GNUTLS_SAN_OTHERNAME_XMPP;
1119 else
1121 char oid[42];
1123 if (src_name[0] != 0)
1124 snprintf (nptr, sizeof (nptr), "%s.?%u.otherName.type-id",
1125 src_name, seq);
1126 else
1127 snprintf (nptr, sizeof (nptr), "?%u.otherName.type-id", seq);
1129 len = sizeof (oid);
1130 result = asn1_read_value (src, nptr, oid, &len);
1131 if (result != ASN1_SUCCESS)
1133 gnutls_assert ();
1134 return _gnutls_asn2err (result);
1137 if ((unsigned)len > strlen (XMPP_OID) && strcmp (oid, XMPP_OID) == 0)
1139 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1140 size_t orig_name_size = *name_size;
1142 result = asn1_create_element
1143 (_gnutls_get_pkix (), "PKIX1.UTF8String", &c2);
1144 if (result != ASN1_SUCCESS)
1146 gnutls_assert ();
1147 return _gnutls_asn2err (result);
1150 result = asn1_der_decoding (&c2, name, *name_size, NULL);
1151 if (result != ASN1_SUCCESS)
1153 gnutls_assert ();
1154 asn1_delete_structure (&c2);
1155 return _gnutls_asn2err (result);
1158 len = *name_size;
1159 result = asn1_read_value (c2, "", name, &len);
1160 if (result != ASN1_SUCCESS)
1162 gnutls_assert ();
1163 asn1_delete_structure (&c2);
1164 *name_size = len + 1;
1165 return _gnutls_asn2err (result);
1167 asn1_delete_structure (&c2);
1169 if ((unsigned)len + 1 > orig_name_size)
1171 gnutls_assert ();
1172 *name_size = len + 1;
1173 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1176 *name_size = len;
1177 /* null terminate it */
1178 ((char *) name)[*name_size] = 0;
1182 else if (type == GNUTLS_SAN_DN)
1184 _gnutls_str_cat (nptr, sizeof (nptr), ".directoryName");
1185 result = _gnutls_x509_parse_dn (src, nptr, name, name_size);
1186 if (result < 0)
1188 gnutls_assert ();
1189 return result;
1192 else if (othername_oid)
1193 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1194 else
1196 size_t orig_name_size = *name_size;
1198 _gnutls_str_cat (nptr, sizeof (nptr), ".");
1199 _gnutls_str_cat (nptr, sizeof (nptr), choice_type);
1201 len = *name_size;
1202 result = asn1_read_value (src, nptr, name, &len);
1203 *name_size = len;
1205 if (result == ASN1_MEM_ERROR)
1207 if (is_type_printable (type))
1208 (*name_size)++;
1209 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1212 if (result != ASN1_SUCCESS)
1214 gnutls_assert ();
1215 return _gnutls_asn2err (result);
1218 if (is_type_printable (type))
1221 if ((unsigned)len + 1 > orig_name_size)
1223 gnutls_assert ();
1224 (*name_size)++;
1225 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1228 /* null terminate it */
1229 ((char *) name)[*name_size] = 0;
1234 return type;
1237 static int
1238 get_alt_name (gnutls_x509_crt_t cert, const char *extension_id,
1239 unsigned int seq, void *alt,
1240 size_t * alt_size, unsigned int *alt_type,
1241 unsigned int *critical, int othername_oid)
1243 int result;
1244 gnutls_datum_t dnsname;
1245 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1247 if (cert == NULL)
1249 gnutls_assert ();
1250 return GNUTLS_E_INVALID_REQUEST;
1253 if (alt)
1254 memset (alt, 0, *alt_size);
1255 else
1256 *alt_size = 0;
1258 if ((result =
1259 _gnutls_x509_crt_get_extension (cert, extension_id, 0, &dnsname,
1260 critical)) < 0)
1262 return result;
1265 if (dnsname.size == 0 || dnsname.data == NULL)
1267 gnutls_assert ();
1268 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1271 if (strcmp ("2.5.29.17", extension_id) == 0)
1272 result = asn1_create_element (_gnutls_get_pkix (),
1273 "PKIX1.SubjectAltName", &c2);
1274 else if (strcmp ("2.5.29.18", extension_id) == 0)
1275 result = asn1_create_element (_gnutls_get_pkix (),
1276 "PKIX1.IssuerAltName", &c2);
1277 else
1279 gnutls_assert ();
1280 return GNUTLS_E_INTERNAL_ERROR;
1283 if (result != ASN1_SUCCESS)
1285 gnutls_assert ();
1286 _gnutls_free_datum (&dnsname);
1287 return _gnutls_asn2err (result);
1290 result = asn1_der_decoding (&c2, dnsname.data, dnsname.size, NULL);
1291 _gnutls_free_datum (&dnsname);
1293 if (result != ASN1_SUCCESS)
1295 gnutls_assert ();
1296 asn1_delete_structure (&c2);
1297 return _gnutls_asn2err (result);
1300 result =
1301 _gnutls_parse_general_name (c2, "", seq, alt, alt_size, alt_type,
1302 othername_oid);
1304 asn1_delete_structure (&c2);
1306 if (result < 0)
1308 gnutls_assert ();
1309 return result;
1312 return result;
1316 * gnutls_x509_crt_get_subject_alt_name:
1317 * @cert: should contain a #gnutls_x509_crt_t structure
1318 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1319 * @san: is the place where the alternative name will be copied to
1320 * @san_size: holds the size of san.
1321 * @critical: will be non (0) if the extension is marked as critical (may be null)
1323 * This function retrieves the Alternative Name (2.5.29.17), contained
1324 * in the given certificate in the X509v3 Certificate Extensions.
1326 * When the SAN type is otherName, it will extract the data in the
1327 * otherName's value field, and %GNUTLS_SAN_OTHERNAME is returned.
1328 * You may use gnutls_x509_crt_get_subject_alt_othername_oid() to get
1329 * the corresponding OID and the "virtual" SAN types (e.g.,
1330 * %GNUTLS_SAN_OTHERNAME_XMPP).
1332 * If an otherName OID is known, the data will be decoded. Otherwise
1333 * the returned data will be DER encoded, and you will have to decode
1334 * it yourself. Currently, only the RFC 3920 id-on-xmppAddr SAN is
1335 * recognized.
1337 * Returns: the alternative subject name type on success, one of the
1338 * enumerated #gnutls_x509_subject_alt_name_t. It will return
1339 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @san_size is not large enough to
1340 * hold the value. In that case @san_size will be updated with the
1341 * required size. If the certificate does not have an Alternative
1342 * name with the specified sequence number then
1343 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1346 gnutls_x509_crt_get_subject_alt_name (gnutls_x509_crt_t cert,
1347 unsigned int seq, void *san,
1348 size_t * san_size,
1349 unsigned int *critical)
1351 return get_alt_name (cert, "2.5.29.17", seq, san, san_size, NULL, critical,
1356 * gnutls_x509_crt_get_issuer_alt_name:
1357 * @cert: should contain a #gnutls_x509_crt_t structure
1358 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1359 * @ian: is the place where the alternative name will be copied to
1360 * @ian_size: holds the size of ian.
1361 * @critical: will be non (0) if the extension is marked as critical (may be null)
1363 * This function retrieves the Issuer Alternative Name (2.5.29.18),
1364 * contained in the given certificate in the X509v3 Certificate
1365 * Extensions.
1367 * When the SAN type is otherName, it will extract the data in the
1368 * otherName's value field, and %GNUTLS_SAN_OTHERNAME is returned.
1369 * You may use gnutls_x509_crt_get_subject_alt_othername_oid() to get
1370 * the corresponding OID and the "virtual" SAN types (e.g.,
1371 * %GNUTLS_SAN_OTHERNAME_XMPP).
1373 * If an otherName OID is known, the data will be decoded. Otherwise
1374 * the returned data will be DER encoded, and you will have to decode
1375 * it yourself. Currently, only the RFC 3920 id-on-xmppAddr Issuer
1376 * AltName is recognized.
1378 * Returns: the alternative issuer name type on success, one of the
1379 * enumerated #gnutls_x509_subject_alt_name_t. It will return
1380 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @ian_size is not large enough
1381 * to hold the value. In that case @ian_size will be updated with
1382 * the required size. If the certificate does not have an
1383 * Alternative name with the specified sequence number then
1384 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1386 * Since: 2.10.0
1389 gnutls_x509_crt_get_issuer_alt_name (gnutls_x509_crt_t cert,
1390 unsigned int seq, void *ian,
1391 size_t * ian_size,
1392 unsigned int *critical)
1394 return get_alt_name (cert, "2.5.29.18", seq, ian, ian_size, NULL, critical,
1399 * gnutls_x509_crt_get_subject_alt_name2:
1400 * @cert: should contain a #gnutls_x509_crt_t structure
1401 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1402 * @san: is the place where the alternative name will be copied to
1403 * @san_size: holds the size of ret.
1404 * @san_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
1405 * @critical: will be non (0) if the extension is marked as critical (may be null)
1407 * This function will return the alternative names, contained in the
1408 * given certificate. It is the same as
1409 * gnutls_x509_crt_get_subject_alt_name() except for the fact that it
1410 * will return the type of the alternative name in @san_type even if
1411 * the function fails for some reason (i.e. the buffer provided is
1412 * not enough).
1414 * Returns: the alternative subject name type on success, one of the
1415 * enumerated #gnutls_x509_subject_alt_name_t. It will return
1416 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @san_size is not large enough
1417 * to hold the value. In that case @san_size will be updated with
1418 * the required size. If the certificate does not have an
1419 * Alternative name with the specified sequence number then
1420 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1423 gnutls_x509_crt_get_subject_alt_name2 (gnutls_x509_crt_t cert,
1424 unsigned int seq, void *san,
1425 size_t * san_size,
1426 unsigned int *san_type,
1427 unsigned int *critical)
1429 return get_alt_name (cert, "2.5.29.17", seq, san, san_size, san_type,
1430 critical, 0);
1434 * gnutls_x509_crt_get_issuer_alt_name2:
1435 * @cert: should contain a #gnutls_x509_crt_t structure
1436 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1437 * @ian: is the place where the alternative name will be copied to
1438 * @ian_size: holds the size of ret.
1439 * @ian_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
1440 * @critical: will be non (0) if the extension is marked as critical (may be null)
1442 * This function will return the alternative names, contained in the
1443 * given certificate. It is the same as
1444 * gnutls_x509_crt_get_issuer_alt_name() except for the fact that it
1445 * will return the type of the alternative name in @ian_type even if
1446 * the function fails for some reason (i.e. the buffer provided is
1447 * not enough).
1449 * Returns: the alternative issuer name type on success, one of the
1450 * enumerated #gnutls_x509_subject_alt_name_t. It will return
1451 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @ian_size is not large enough
1452 * to hold the value. In that case @ian_size will be updated with
1453 * the required size. If the certificate does not have an
1454 * Alternative name with the specified sequence number then
1455 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1457 * Since: 2.10.0
1461 gnutls_x509_crt_get_issuer_alt_name2 (gnutls_x509_crt_t cert,
1462 unsigned int seq, void *ian,
1463 size_t * ian_size,
1464 unsigned int *ian_type,
1465 unsigned int *critical)
1467 return get_alt_name (cert, "2.5.29.18", seq, ian, ian_size, ian_type,
1468 critical, 0);
1472 * gnutls_x509_crt_get_subject_alt_othername_oid:
1473 * @cert: should contain a #gnutls_x509_crt_t structure
1474 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1475 * @oid: is the place where the otherName OID will be copied to
1476 * @oid_size: holds the size of ret.
1478 * This function will extract the type OID of an otherName Subject
1479 * Alternative Name, contained in the given certificate, and return
1480 * the type as an enumerated element.
1482 * This function is only useful if
1483 * gnutls_x509_crt_get_subject_alt_name() returned
1484 * %GNUTLS_SAN_OTHERNAME.
1486 * If @oid is null then only the size will be filled. The @oid
1487 * returned will be null terminated, although @oid_size will not
1488 * account for the trailing null.
1490 * Returns: the alternative subject name type on success, one of the
1491 * enumerated gnutls_x509_subject_alt_name_t. For supported OIDs, it
1492 * will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
1493 * e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
1494 * unknown OIDs. It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
1495 * @ian_size is not large enough to hold the value. In that case
1496 * @ian_size will be updated with the required size. If the
1497 * certificate does not have an Alternative name with the specified
1498 * sequence number and with the otherName type then
1499 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1502 gnutls_x509_crt_get_subject_alt_othername_oid (gnutls_x509_crt_t cert,
1503 unsigned int seq,
1504 void *oid, size_t * oid_size)
1506 return get_alt_name (cert, "2.5.29.17", seq, oid, oid_size, NULL, NULL, 1);
1510 * gnutls_x509_crt_get_issuer_alt_othername_oid:
1511 * @cert: should contain a #gnutls_x509_crt_t structure
1512 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1513 * @ret: is the place where the otherName OID will be copied to
1514 * @ret_size: holds the size of ret.
1516 * This function will extract the type OID of an otherName Subject
1517 * Alternative Name, contained in the given certificate, and return
1518 * the type as an enumerated element.
1520 * If @oid is null then only the size will be filled. The @oid
1521 * returned will be null terminated, although @oid_size will not
1522 * account for the trailing null.
1524 * This function is only useful if
1525 * gnutls_x509_crt_get_issuer_alt_name() returned
1526 * %GNUTLS_SAN_OTHERNAME.
1528 * Returns: the alternative issuer name type on success, one of the
1529 * enumerated gnutls_x509_subject_alt_name_t. For supported OIDs, it
1530 * will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
1531 * e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
1532 * unknown OIDs. It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
1533 * @ret_size is not large enough to hold the value. In that case
1534 * @ret_size will be updated with the required size. If the
1535 * certificate does not have an Alternative name with the specified
1536 * sequence number and with the otherName type then
1537 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1539 * Since: 2.10.0
1542 gnutls_x509_crt_get_issuer_alt_othername_oid (gnutls_x509_crt_t cert,
1543 unsigned int seq,
1544 void *ret, size_t * ret_size)
1546 return get_alt_name (cert, "2.5.29.18", seq, ret, ret_size, NULL, NULL, 1);
1550 * gnutls_x509_crt_get_basic_constraints:
1551 * @cert: should contain a #gnutls_x509_crt_t structure
1552 * @critical: will be non (0) if the extension is marked as critical
1553 * @ca: pointer to output integer indicating CA status, may be NULL,
1554 * value is 1 if the certificate CA flag is set, 0 otherwise.
1555 * @pathlen: pointer to output integer indicating path length (may be
1556 * NULL), non-negative error codes indicate a present pathLenConstraint
1557 * field and the actual value, -1 indicate that the field is absent.
1559 * This function will read the certificate's basic constraints, and
1560 * return the certificates CA status. It reads the basicConstraints
1561 * X.509 extension (2.5.29.19).
1563 * Returns: If the certificate is a CA a positive value will be
1564 * returned, or (0) if the certificate does not have CA flag set. A
1565 * negative error code may be returned in case of errors. If the
1566 * certificate does not contain the basicConstraints extension
1567 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1570 gnutls_x509_crt_get_basic_constraints (gnutls_x509_crt_t cert,
1571 unsigned int *critical,
1572 unsigned int *ca, int *pathlen)
1574 int result;
1575 gnutls_datum_t basicConstraints;
1576 unsigned int tmp_ca;
1578 if (cert == NULL)
1580 gnutls_assert ();
1581 return GNUTLS_E_INVALID_REQUEST;
1584 if ((result =
1585 _gnutls_x509_crt_get_extension (cert, "2.5.29.19", 0,
1586 &basicConstraints, critical)) < 0)
1588 return result;
1591 if (basicConstraints.size == 0 || basicConstraints.data == NULL)
1593 gnutls_assert ();
1594 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1597 result =
1598 _gnutls_x509_ext_extract_basicConstraints (&tmp_ca,
1599 pathlen,
1600 basicConstraints.data,
1601 basicConstraints.size);
1602 if (ca)
1603 *ca = tmp_ca;
1604 _gnutls_free_datum (&basicConstraints);
1606 if (result < 0)
1608 gnutls_assert ();
1609 return result;
1612 return tmp_ca;
1616 * gnutls_x509_crt_get_ca_status:
1617 * @cert: should contain a #gnutls_x509_crt_t structure
1618 * @critical: will be non (0) if the extension is marked as critical
1620 * This function will return certificates CA status, by reading the
1621 * basicConstraints X.509 extension (2.5.29.19). If the certificate is
1622 * a CA a positive value will be returned, or (0) if the certificate
1623 * does not have CA flag set.
1625 * Use gnutls_x509_crt_get_basic_constraints() if you want to read the
1626 * pathLenConstraint field too.
1628 * Returns: A negative error code may be returned in case of parsing error.
1629 * If the certificate does not contain the basicConstraints extension
1630 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1633 gnutls_x509_crt_get_ca_status (gnutls_x509_crt_t cert, unsigned int *critical)
1635 int pathlen;
1636 unsigned int ca;
1637 return gnutls_x509_crt_get_basic_constraints (cert, critical, &ca,
1638 &pathlen);
1642 * gnutls_x509_crt_get_key_usage:
1643 * @cert: should contain a #gnutls_x509_crt_t structure
1644 * @key_usage: where the key usage bits will be stored
1645 * @critical: will be non (0) if the extension is marked as critical
1647 * This function will return certificate's key usage, by reading the
1648 * keyUsage X.509 extension (2.5.29.15). The key usage value will ORed
1649 * values of the: %GNUTLS_KEY_DIGITAL_SIGNATURE,
1650 * %GNUTLS_KEY_NON_REPUDIATION, %GNUTLS_KEY_KEY_ENCIPHERMENT,
1651 * %GNUTLS_KEY_DATA_ENCIPHERMENT, %GNUTLS_KEY_KEY_AGREEMENT,
1652 * %GNUTLS_KEY_KEY_CERT_SIGN, %GNUTLS_KEY_CRL_SIGN,
1653 * %GNUTLS_KEY_ENCIPHER_ONLY, %GNUTLS_KEY_DECIPHER_ONLY.
1655 * Returns: the certificate key usage, or a negative error code in case of
1656 * parsing error. If the certificate does not contain the keyUsage
1657 * extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
1658 * returned.
1661 gnutls_x509_crt_get_key_usage (gnutls_x509_crt_t cert,
1662 unsigned int *key_usage,
1663 unsigned int *critical)
1665 int result;
1666 gnutls_datum_t keyUsage;
1667 uint16_t _usage;
1669 if (cert == NULL)
1671 gnutls_assert ();
1672 return GNUTLS_E_INVALID_REQUEST;
1675 if ((result =
1676 _gnutls_x509_crt_get_extension (cert, "2.5.29.15", 0, &keyUsage,
1677 critical)) < 0)
1679 return result;
1682 if (keyUsage.size == 0 || keyUsage.data == NULL)
1684 gnutls_assert ();
1685 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1688 result = _gnutls_x509_ext_extract_keyUsage (&_usage, keyUsage.data,
1689 keyUsage.size);
1690 _gnutls_free_datum (&keyUsage);
1692 *key_usage = _usage;
1694 if (result < 0)
1696 gnutls_assert ();
1697 return result;
1700 return 0;
1704 * gnutls_x509_crt_get_proxy:
1705 * @cert: should contain a #gnutls_x509_crt_t structure
1706 * @critical: will be non (0) if the extension is marked as critical
1707 * @pathlen: pointer to output integer indicating path length (may be
1708 * NULL), non-negative error codes indicate a present pCPathLenConstraint
1709 * field and the actual value, -1 indicate that the field is absent.
1710 * @policyLanguage: output variable with OID of policy language
1711 * @policy: output variable with policy data
1712 * @sizeof_policy: output variable size of policy data
1714 * This function will get information from a proxy certificate. It
1715 * reads the ProxyCertInfo X.509 extension (1.3.6.1.5.5.7.1.14).
1717 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1718 * otherwise a negative error code is returned.
1721 gnutls_x509_crt_get_proxy (gnutls_x509_crt_t cert,
1722 unsigned int *critical,
1723 int *pathlen,
1724 char **policyLanguage,
1725 char **policy, size_t * sizeof_policy)
1727 int result;
1728 gnutls_datum_t proxyCertInfo;
1730 if (cert == NULL)
1732 gnutls_assert ();
1733 return GNUTLS_E_INVALID_REQUEST;
1736 if ((result =
1737 _gnutls_x509_crt_get_extension (cert, "1.3.6.1.5.5.7.1.14", 0,
1738 &proxyCertInfo, critical)) < 0)
1740 return result;
1743 if (proxyCertInfo.size == 0 || proxyCertInfo.data == NULL)
1745 gnutls_assert ();
1746 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1749 result = _gnutls_x509_ext_extract_proxyCertInfo (pathlen,
1750 policyLanguage,
1751 policy,
1752 sizeof_policy,
1753 proxyCertInfo.data,
1754 proxyCertInfo.size);
1755 _gnutls_free_datum (&proxyCertInfo);
1756 if (result < 0)
1758 gnutls_assert ();
1759 return result;
1762 return 0;
1766 * gnutls_x509_crt_get_extension_by_oid:
1767 * @cert: should contain a #gnutls_x509_crt_t structure
1768 * @oid: holds an Object Identified in null terminated string
1769 * @indx: In case multiple same OIDs exist in the extensions, this specifies which to send. Use (0) to get the first one.
1770 * @buf: a pointer to a structure to hold the name (may be null)
1771 * @buf_size: initially holds the size of @buf
1772 * @critical: will be non (0) if the extension is marked as critical
1774 * This function will return the extension specified by the OID in the
1775 * certificate. The extensions will be returned as binary data DER
1776 * encoded, in the provided buffer.
1778 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1779 * otherwise a negative error code is returned. If the certificate does not
1780 * contain the specified extension
1781 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1784 gnutls_x509_crt_get_extension_by_oid (gnutls_x509_crt_t cert,
1785 const char *oid, int indx,
1786 void *buf, size_t * buf_size,
1787 unsigned int *critical)
1789 int result;
1790 gnutls_datum_t output;
1792 if (cert == NULL)
1794 gnutls_assert ();
1795 return GNUTLS_E_INVALID_REQUEST;
1798 if ((result =
1799 _gnutls_x509_crt_get_extension (cert, oid, indx, &output,
1800 critical)) < 0)
1802 gnutls_assert ();
1803 return result;
1806 if (output.size == 0 || output.data == NULL)
1808 gnutls_assert ();
1809 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1812 if (output.size > (unsigned int) *buf_size)
1814 *buf_size = output.size;
1815 _gnutls_free_datum (&output);
1816 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1819 *buf_size = output.size;
1821 if (buf)
1822 memcpy (buf, output.data, output.size);
1824 _gnutls_free_datum (&output);
1826 return 0;
1831 * gnutls_x509_crt_get_extension_oid:
1832 * @cert: should contain a #gnutls_x509_crt_t structure
1833 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
1834 * @oid: a pointer to a structure to hold the OID (may be null)
1835 * @oid_size: initially holds the size of @oid
1837 * This function will return the requested extension OID in the certificate.
1838 * The extension OID will be stored as a string in the provided buffer.
1840 * The @oid returned will be null terminated, although @oid_size will not
1841 * account for the trailing null.
1843 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1844 * otherwise a negative error code is returned. If you have reached the
1845 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1846 * will be returned.
1849 gnutls_x509_crt_get_extension_oid (gnutls_x509_crt_t cert, int indx,
1850 void *oid, size_t * oid_size)
1852 int result;
1854 if (cert == NULL)
1856 gnutls_assert ();
1857 return GNUTLS_E_INVALID_REQUEST;
1860 result = _gnutls_x509_crt_get_extension_oid (cert, indx, oid, oid_size);
1861 if (result < 0)
1863 return result;
1866 return 0;
1871 * gnutls_x509_crt_get_extension_info:
1872 * @cert: should contain a #gnutls_x509_crt_t structure
1873 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
1874 * @oid: a pointer to a structure to hold the OID
1875 * @oid_size: initially holds the maximum size of @oid, on return
1876 * holds actual size of @oid.
1877 * @critical: output variable with critical flag, may be NULL.
1879 * This function will return the requested extension OID in the
1880 * certificate, and the critical flag for it. The extension OID will
1881 * be stored as a string in the provided buffer. Use
1882 * gnutls_x509_crt_get_extension_data() to extract the data.
1884 * If the buffer provided is not long enough to hold the output, then
1885 * @oid_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
1886 * returned. The @oid returned will be null terminated, although
1887 * @oid_size will not account for the trailing null.
1889 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1890 * otherwise a negative error code is returned. If you have reached the
1891 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1892 * will be returned.
1895 gnutls_x509_crt_get_extension_info (gnutls_x509_crt_t cert, int indx,
1896 void *oid, size_t * oid_size,
1897 unsigned int *critical)
1899 int result;
1900 char str_critical[10];
1901 char name[ASN1_MAX_NAME_SIZE];
1902 int len;
1904 if (!cert)
1906 gnutls_assert ();
1907 return GNUTLS_E_INVALID_REQUEST;
1910 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u.extnID",
1911 indx + 1);
1913 len = *oid_size;
1914 result = asn1_read_value (cert->cert, name, oid, &len);
1915 *oid_size = len;
1917 if (result == ASN1_ELEMENT_NOT_FOUND)
1918 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1919 else if (result != ASN1_SUCCESS)
1921 gnutls_assert ();
1922 return _gnutls_asn2err (result);
1925 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u.critical",
1926 indx + 1);
1927 len = sizeof (str_critical);
1928 result = asn1_read_value (cert->cert, name, str_critical, &len);
1929 if (result != ASN1_SUCCESS)
1931 gnutls_assert ();
1932 return _gnutls_asn2err (result);
1935 if (critical)
1937 if (str_critical[0] == 'T')
1938 *critical = 1;
1939 else
1940 *critical = 0;
1943 return 0;
1948 * gnutls_x509_crt_get_extension_data:
1949 * @cert: should contain a #gnutls_x509_crt_t structure
1950 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
1951 * @data: a pointer to a structure to hold the data (may be null)
1952 * @sizeof_data: initially holds the size of @oid
1954 * This function will return the requested extension data in the
1955 * certificate. The extension data will be stored as a string in the
1956 * provided buffer.
1958 * Use gnutls_x509_crt_get_extension_info() to extract the OID and
1959 * critical flag. Use gnutls_x509_crt_get_extension_by_oid() instead,
1960 * if you want to get data indexed by the extension OID rather than
1961 * sequence.
1963 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1964 * otherwise a negative error code is returned. If you have reached the
1965 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1966 * will be returned.
1969 gnutls_x509_crt_get_extension_data (gnutls_x509_crt_t cert, int indx,
1970 void *data, size_t * sizeof_data)
1972 int result, len;
1973 char name[ASN1_MAX_NAME_SIZE];
1975 if (!cert)
1977 gnutls_assert ();
1978 return GNUTLS_E_INVALID_REQUEST;
1981 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u.extnValue",
1982 indx + 1);
1984 len = *sizeof_data;
1985 result = asn1_read_value (cert->cert, name, data, &len);
1986 *sizeof_data = len;
1988 if (result == ASN1_ELEMENT_NOT_FOUND)
1989 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1990 else if (result < 0)
1992 gnutls_assert ();
1993 return _gnutls_asn2err (result);
1996 return 0;
1999 static int
2000 _gnutls_x509_crt_get_raw_dn2 (gnutls_x509_crt_t cert,
2001 const char *whom, gnutls_datum_t * start)
2003 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2004 int result, len1;
2005 int start1, end1;
2006 gnutls_datum_t signed_data = { NULL, 0 };
2008 /* get the issuer of 'cert'
2010 if ((result =
2011 asn1_create_element (_gnutls_get_pkix (), "PKIX1.TBSCertificate",
2012 &c2)) != ASN1_SUCCESS)
2014 gnutls_assert ();
2015 return _gnutls_asn2err (result);
2018 result =
2019 _gnutls_x509_get_signed_data (cert->cert, "tbsCertificate", &signed_data);
2020 if (result < 0)
2022 gnutls_assert ();
2023 goto cleanup;
2026 result = asn1_der_decoding (&c2, signed_data.data, signed_data.size, NULL);
2027 if (result != ASN1_SUCCESS)
2029 gnutls_assert ();
2030 asn1_delete_structure (&c2);
2031 result = _gnutls_asn2err (result);
2032 goto cleanup;
2035 result =
2036 asn1_der_decoding_startEnd (c2, signed_data.data, signed_data.size,
2037 whom, &start1, &end1);
2039 if (result != ASN1_SUCCESS)
2041 gnutls_assert ();
2042 result = _gnutls_asn2err (result);
2043 goto cleanup;
2046 len1 = end1 - start1 + 1;
2048 _gnutls_set_datum (start, &signed_data.data[start1], len1);
2050 result = 0;
2052 cleanup:
2053 asn1_delete_structure (&c2);
2054 _gnutls_free_datum (&signed_data);
2055 return result;
2059 * gnutls_x509_crt_get_raw_issuer_dn:
2060 * @cert: should contain a #gnutls_x509_crt_t structure
2061 * @start: will hold the starting point of the DN
2063 * This function will return a pointer to the DER encoded DN structure
2064 * and the length. This points to allocated data that must be free'd using gnutls_free().
2066 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2067 * negative error value.or a negative error code on error.
2071 gnutls_x509_crt_get_raw_issuer_dn (gnutls_x509_crt_t cert,
2072 gnutls_datum_t * start)
2074 return _gnutls_x509_crt_get_raw_dn2 (cert, "issuer", start);
2078 * gnutls_x509_crt_get_raw_dn:
2079 * @cert: should contain a #gnutls_x509_crt_t structure
2080 * @start: will hold the starting point of the DN
2082 * This function will return a pointer to the DER encoded DN structure and
2083 * the length. This points to allocated data that must be free'd using gnutls_free().
2085 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2086 * negative error value. or a negative error code on error.
2090 gnutls_x509_crt_get_raw_dn (gnutls_x509_crt_t cert, gnutls_datum_t * start)
2092 return _gnutls_x509_crt_get_raw_dn2 (cert, "subject", start);
2095 static int
2096 get_dn (gnutls_x509_crt_t cert, const char *whom, gnutls_x509_dn_t * dn)
2098 *dn = asn1_find_node (cert->cert, whom);
2099 if (!*dn)
2100 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2101 return 0;
2105 * gnutls_x509_crt_get_subject:
2106 * @cert: should contain a #gnutls_x509_crt_t structure
2107 * @dn: output variable with pointer to uint8_t DN.
2109 * Return the Certificate's Subject DN as an uint8_t data type. You
2110 * may use gnutls_x509_dn_get_rdn_ava() to decode the DN.
2112 * Note that @dn should be treated as constant. Because points
2113 * into the @cert object, you may not deallocate @cert
2114 * and continue to access @dn.
2116 * Returns: Returns 0 on success, or an error code.
2119 gnutls_x509_crt_get_subject (gnutls_x509_crt_t cert, gnutls_x509_dn_t * dn)
2121 return get_dn (cert, "tbsCertificate.subject.rdnSequence", dn);
2125 * gnutls_x509_crt_get_issuer:
2126 * @cert: should contain a #gnutls_x509_crt_t structure
2127 * @dn: output variable with pointer to uint8_t DN
2129 * Return the Certificate's Issuer DN as an uint8_t data type. You may
2130 * use gnutls_x509_dn_get_rdn_ava() to decode the DN.
2132 * Note that @dn should be treated as constant. Because points
2133 * into the @cert object, you may not deallocate @cert
2134 * and continue to access @dn.
2136 * Returns: Returns 0 on success, or an error code.
2139 gnutls_x509_crt_get_issuer (gnutls_x509_crt_t cert, gnutls_x509_dn_t * dn)
2141 return get_dn (cert, "tbsCertificate.issuer.rdnSequence", dn);
2145 * gnutls_x509_dn_get_rdn_ava:
2146 * @dn: input variable with uint8_t DN pointer
2147 * @irdn: index of RDN
2148 * @iava: index of AVA.
2149 * @ava: Pointer to structure which will hold output information.
2151 * Get pointers to data within the DN.
2153 * Note that @ava will contain pointers into the @dn structure, so you
2154 * should not modify any data or deallocate it. Note also that the DN
2155 * in turn points into the original certificate structure, and thus
2156 * you may not deallocate the certificate and continue to access @dn.
2158 * Returns: Returns 0 on success, or an error code.
2161 gnutls_x509_dn_get_rdn_ava (gnutls_x509_dn_t dn,
2162 int irdn, int iava, gnutls_x509_ava_st * ava)
2164 ASN1_TYPE rdn, elem;
2165 ASN1_DATA_NODE vnode;
2166 long len;
2167 int lenlen, remlen, ret;
2168 char rbuf[ASN1_MAX_NAME_SIZE];
2169 unsigned char cls;
2170 const unsigned char *ptr;
2172 iava++;
2173 irdn++; /* 0->1, 1->2 etc */
2175 snprintf (rbuf, sizeof (rbuf), "rdnSequence.?%d.?%d", irdn, iava);
2176 rdn = asn1_find_node (dn, rbuf);
2177 if (!rdn)
2179 gnutls_assert ();
2180 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2183 snprintf (rbuf, sizeof (rbuf), "?%d.type", iava);
2184 elem = asn1_find_node (rdn, rbuf);
2185 if (!elem)
2187 gnutls_assert ();
2188 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2191 ret = asn1_read_node_value(elem, &vnode);
2192 if (ret != ASN1_SUCCESS)
2194 gnutls_assert ();
2195 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2198 ava->oid.data = (void*)vnode.value;
2199 ava->oid.size = vnode.value_len;
2201 snprintf (rbuf, sizeof (rbuf), "?%d.value", iava);
2202 elem = asn1_find_node (rdn, rbuf);
2203 if (!elem)
2205 gnutls_assert ();
2206 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2209 ret = asn1_read_node_value(elem, &vnode);
2210 if (ret != ASN1_SUCCESS)
2212 gnutls_assert ();
2213 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2215 /* The value still has the previous tag's length bytes, plus the
2216 * current value's tag and length bytes. Decode them.
2219 ptr = vnode.value;
2220 remlen = vnode.value_len;
2221 len = asn1_get_length_der (ptr, remlen, &lenlen);
2222 if (len < 0)
2224 gnutls_assert ();
2225 return GNUTLS_E_ASN1_DER_ERROR;
2228 ptr += lenlen;
2229 remlen -= lenlen;
2230 ret = asn1_get_tag_der (ptr, remlen, &cls, &lenlen, &ava->value_tag);
2231 if (ret)
2233 gnutls_assert ();
2234 return _gnutls_asn2err (ret);
2237 ptr += lenlen;
2238 remlen -= lenlen;
2241 signed long tmp;
2243 tmp = asn1_get_length_der (ptr, remlen, &lenlen);
2244 if (tmp < 0)
2246 gnutls_assert ();
2247 return GNUTLS_E_ASN1_DER_ERROR;
2249 ava->value.size = tmp;
2251 ava->value.data = (void*)(ptr + lenlen);
2253 return 0;
2257 * gnutls_x509_crt_get_fingerprint:
2258 * @cert: should contain a #gnutls_x509_crt_t structure
2259 * @algo: is a digest algorithm
2260 * @buf: a pointer to a structure to hold the fingerprint (may be null)
2261 * @buf_size: initially holds the size of @buf
2263 * This function will calculate and copy the certificate's fingerprint
2264 * in the provided buffer.
2266 * If the buffer is null then only the size will be filled.
2268 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
2269 * not long enough, and in that case the *buf_size will be updated
2270 * with the required size. On success 0 is returned.
2273 gnutls_x509_crt_get_fingerprint (gnutls_x509_crt_t cert,
2274 gnutls_digest_algorithm_t algo,
2275 void *buf, size_t * buf_size)
2277 uint8_t *cert_buf;
2278 int cert_buf_size;
2279 int result;
2280 gnutls_datum_t tmp;
2282 if (buf_size == 0 || cert == NULL)
2284 return GNUTLS_E_INVALID_REQUEST;
2287 cert_buf_size = 0;
2288 asn1_der_coding (cert->cert, "", NULL, &cert_buf_size, NULL);
2290 cert_buf = gnutls_malloc (cert_buf_size);
2291 if (cert_buf == NULL)
2293 gnutls_assert ();
2294 return GNUTLS_E_MEMORY_ERROR;
2297 result = asn1_der_coding (cert->cert, "", cert_buf, &cert_buf_size, NULL);
2299 if (result != ASN1_SUCCESS)
2301 gnutls_assert ();
2302 gnutls_free (cert_buf);
2303 return _gnutls_asn2err (result);
2306 tmp.data = cert_buf;
2307 tmp.size = cert_buf_size;
2309 result = gnutls_fingerprint (algo, &tmp, buf, buf_size);
2310 gnutls_free (cert_buf);
2312 return result;
2316 * gnutls_x509_crt_export:
2317 * @cert: Holds the certificate
2318 * @format: the format of output params. One of PEM or DER.
2319 * @output_data: will contain a certificate PEM or DER encoded
2320 * @output_data_size: holds the size of output_data (and will be
2321 * replaced by the actual size of parameters)
2323 * This function will export the certificate to DER or PEM format.
2325 * If the buffer provided is not long enough to hold the output, then
2326 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2327 * be returned.
2329 * If the structure is PEM encoded, it will have a header
2330 * of "BEGIN CERTIFICATE".
2332 * Returns: In case of failure a negative error code will be
2333 * returned, and 0 on success.
2336 gnutls_x509_crt_export (gnutls_x509_crt_t cert,
2337 gnutls_x509_crt_fmt_t format, void *output_data,
2338 size_t * output_data_size)
2340 if (cert == NULL)
2342 gnutls_assert ();
2343 return GNUTLS_E_INVALID_REQUEST;
2346 return _gnutls_x509_export_int (cert->cert, format, "CERTIFICATE",
2347 output_data, output_data_size);
2351 _gnutls_get_key_id (gnutls_pk_algorithm_t pk, gnutls_pk_params_st * params,
2352 unsigned char *output_data,
2353 size_t * output_data_size)
2355 int ret = 0;
2356 gnutls_datum_t der = { NULL, 0 };
2357 const gnutls_digest_algorithm_t hash = GNUTLS_DIG_SHA1;
2358 unsigned int digest_len = _gnutls_hash_get_algo_len(hash);
2360 if (output_data == NULL || *output_data_size < digest_len)
2362 gnutls_assert ();
2363 *output_data_size = digest_len;
2364 return GNUTLS_E_SHORT_MEMORY_BUFFER;
2367 ret = _gnutls_x509_encode_PKI_params(&der, pk, params);
2368 if (ret < 0)
2369 return gnutls_assert_val(ret);
2371 ret = _gnutls_hash_fast(hash, der.data, der.size, output_data);
2372 if (ret < 0)
2374 gnutls_assert ();
2375 goto cleanup;
2377 *output_data_size = digest_len;
2379 ret = 0;
2381 cleanup:
2383 _gnutls_free_datum (&der);
2384 return ret;
2388 * gnutls_x509_crt_get_key_id:
2389 * @crt: Holds the certificate
2390 * @flags: should be 0 for now
2391 * @output_data: will contain the key ID
2392 * @output_data_size: holds the size of output_data (and will be
2393 * replaced by the actual size of parameters)
2395 * This function will return a unique ID the depends on the public
2396 * key parameters. This ID can be used in checking whether a
2397 * certificate corresponds to the given private key.
2399 * If the buffer provided is not long enough to hold the output, then
2400 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2401 * be returned. The output will normally be a SHA-1 hash output,
2402 * which is 20 bytes.
2404 * Returns: In case of failure a negative error code will be
2405 * returned, and 0 on success.
2408 gnutls_x509_crt_get_key_id (gnutls_x509_crt_t crt, unsigned int flags,
2409 unsigned char *output_data,
2410 size_t * output_data_size)
2412 int pk, ret = 0;
2413 gnutls_pk_params_st params;
2415 if (crt == NULL)
2417 gnutls_assert ();
2418 return GNUTLS_E_INVALID_REQUEST;
2421 pk = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
2422 if (pk < 0)
2424 gnutls_assert ();
2425 return pk;
2428 ret = _gnutls_x509_crt_get_mpis (crt, &params);
2429 if (ret < 0)
2431 gnutls_assert ();
2432 return ret;
2435 ret = _gnutls_get_key_id(pk, &params, output_data, output_data_size);
2437 gnutls_pk_params_release(&params);
2439 return ret;
2443 /* This is exactly as gnutls_x509_crt_check_revocation() except that
2444 * it calls func.
2447 _gnutls_x509_crt_check_revocation (gnutls_x509_crt_t cert,
2448 const gnutls_x509_crl_t * crl_list,
2449 int crl_list_length,
2450 gnutls_verify_output_function func)
2452 uint8_t serial[128];
2453 uint8_t cert_serial[128];
2454 size_t serial_size, cert_serial_size;
2455 int ncerts, ret, i, j;
2456 gnutls_datum_t dn1, dn2;
2458 if (cert == NULL)
2460 gnutls_assert ();
2461 return GNUTLS_E_INVALID_REQUEST;
2464 for (j = 0; j < crl_list_length; j++)
2465 { /* do for all the crls */
2467 /* Step 1. check if issuer's DN match
2469 ret = gnutls_x509_crl_get_raw_issuer_dn (crl_list[j], &dn1);
2470 if (ret < 0)
2472 gnutls_assert ();
2473 return ret;
2476 ret = gnutls_x509_crt_get_raw_issuer_dn (cert, &dn2);
2477 if (ret < 0)
2479 gnutls_assert ();
2480 return ret;
2483 ret = _gnutls_x509_compare_raw_dn (&dn1, &dn2);
2484 _gnutls_free_datum (&dn1);
2485 _gnutls_free_datum (&dn2);
2486 if (ret == 0)
2488 /* issuers do not match so don't even
2489 * bother checking.
2491 continue;
2494 /* Step 2. Read the certificate's serial number
2496 cert_serial_size = sizeof (cert_serial);
2497 ret = gnutls_x509_crt_get_serial (cert, cert_serial, &cert_serial_size);
2498 if (ret < 0)
2500 gnutls_assert ();
2501 return ret;
2504 /* Step 3. cycle through the CRL serials and compare with
2505 * certificate serial we have.
2508 ncerts = gnutls_x509_crl_get_crt_count (crl_list[j]);
2509 if (ncerts < 0)
2511 gnutls_assert ();
2512 return ncerts;
2515 for (i = 0; i < ncerts; i++)
2517 serial_size = sizeof (serial);
2518 ret =
2519 gnutls_x509_crl_get_crt_serial (crl_list[j], i, serial,
2520 &serial_size, NULL);
2522 if (ret < 0)
2524 gnutls_assert ();
2525 return ret;
2528 if (serial_size == cert_serial_size)
2530 if (memcmp (serial, cert_serial, serial_size) == 0)
2532 /* serials match */
2533 if (func) func(cert, NULL, crl_list[j], GNUTLS_CERT_REVOKED|GNUTLS_CERT_INVALID);
2534 return 1; /* revoked! */
2538 if (func) func(cert, NULL, crl_list[j], 0);
2541 return 0; /* not revoked. */
2546 * gnutls_x509_crt_check_revocation:
2547 * @cert: should contain a #gnutls_x509_crt_t structure
2548 * @crl_list: should contain a list of gnutls_x509_crl_t structures
2549 * @crl_list_length: the length of the crl_list
2551 * This function will return check if the given certificate is
2552 * revoked. It is assumed that the CRLs have been verified before.
2554 * Returns: 0 if the certificate is NOT revoked, and 1 if it is. A
2555 * negative error code is returned on error.
2558 gnutls_x509_crt_check_revocation (gnutls_x509_crt_t cert,
2559 const gnutls_x509_crl_t * crl_list,
2560 int crl_list_length)
2562 return _gnutls_x509_crt_check_revocation(cert, crl_list, crl_list_length, NULL);
2566 * gnutls_x509_crt_get_verify_algorithm:
2567 * @crt: Holds the certificate
2568 * @signature: contains the signature
2569 * @hash: The result of the call with the hash algorithm used for signature
2571 * This function will read the certifcate and the signed data to
2572 * determine the hash algorithm used to generate the signature.
2574 * Deprecated: Use gnutls_pubkey_get_verify_algorithm() instead.
2576 * Returns: the 0 if the hash algorithm is found. A negative error code is
2577 * returned on error.
2579 * Since: 2.8.0
2582 gnutls_x509_crt_get_verify_algorithm (gnutls_x509_crt_t crt,
2583 const gnutls_datum_t * signature,
2584 gnutls_digest_algorithm_t * hash)
2586 gnutls_pk_params_st issuer_params;
2587 int ret;
2589 if (crt == NULL)
2591 gnutls_assert ();
2592 return GNUTLS_E_INVALID_REQUEST;
2595 ret = _gnutls_x509_crt_get_mpis (crt, &issuer_params);
2596 if (ret < 0)
2598 gnutls_assert ();
2599 return ret;
2602 ret = _gnutls_x509_verify_algorithm (hash,
2603 signature,
2604 gnutls_x509_crt_get_pk_algorithm (crt,
2605 NULL),
2606 &issuer_params);
2608 /* release allocated mpis */
2609 gnutls_pk_params_release(&issuer_params);
2611 return ret;
2617 * gnutls_x509_crt_get_preferred_hash_algorithm:
2618 * @crt: Holds the certificate
2619 * @hash: The result of the call with the hash algorithm used for signature
2620 * @mand: If non (0) it means that the algorithm MUST use this hash. May be NULL.
2622 * This function will read the certifcate and return the appropriate digest
2623 * algorithm to use for signing with this certificate. Some certificates (i.e.
2624 * DSA might not be able to sign without the preferred algorithm).
2626 * Deprecated: Please use gnutls_pubkey_get_preferred_hash_algorithm().
2628 * Returns: the 0 if the hash algorithm is found. A negative error code is
2629 * returned on error.
2631 * Since: 2.12.0
2634 gnutls_x509_crt_get_preferred_hash_algorithm (gnutls_x509_crt_t crt,
2635 gnutls_digest_algorithm_t *
2636 hash, unsigned int *mand)
2638 gnutls_pk_params_st issuer_params;
2639 int ret;
2641 if (crt == NULL)
2643 gnutls_assert ();
2644 return GNUTLS_E_INVALID_REQUEST;
2647 ret = _gnutls_x509_crt_get_mpis (crt, &issuer_params);
2648 if (ret < 0)
2650 gnutls_assert ();
2651 return ret;
2654 ret =
2655 _gnutls_pk_get_hash_algorithm (gnutls_x509_crt_get_pk_algorithm
2656 (crt, NULL), &issuer_params,
2657 hash, mand);
2659 /* release allocated mpis */
2660 gnutls_pk_params_release(&issuer_params);
2662 return ret;
2666 * gnutls_x509_crt_verify_data:
2667 * @crt: Holds the certificate
2668 * @flags: should be 0 for now
2669 * @data: holds the data to be signed
2670 * @signature: contains the signature
2672 * This function will verify the given signed data, using the
2673 * parameters from the certificate.
2675 * Deprecated. Please use gnutls_pubkey_verify_data().
2677 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
2678 * is returned, and zero or positive code on success.
2681 gnutls_x509_crt_verify_data (gnutls_x509_crt_t crt, unsigned int flags,
2682 const gnutls_datum_t * data,
2683 const gnutls_datum_t * signature)
2685 int result;
2687 if (crt == NULL)
2689 gnutls_assert ();
2690 return GNUTLS_E_INVALID_REQUEST;
2693 result = _gnutls_x509_verify_data (GNUTLS_DIG_UNKNOWN, data, signature, crt);
2694 if (result < 0)
2696 gnutls_assert ();
2697 return result;
2700 return result;
2704 * gnutls_x509_crt_verify_hash:
2705 * @crt: Holds the certificate
2706 * @flags: should be 0 for now
2707 * @hash: holds the hash digest to be verified
2708 * @signature: contains the signature
2710 * This function will verify the given signed digest, using the
2711 * parameters from the certificate.
2713 * Deprecated. Please use gnutls_pubkey_verify_data2() or gnutls_pubkey_verify_hash2().
2715 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
2716 * is returned, and zero or positive code on success.
2719 gnutls_x509_crt_verify_hash (gnutls_x509_crt_t crt, unsigned int flags,
2720 const gnutls_datum_t * hash,
2721 const gnutls_datum_t * signature)
2723 gnutls_pk_params_st params;
2724 gnutls_digest_algorithm_t algo;
2725 int ret;
2727 if (crt == NULL)
2729 gnutls_assert ();
2730 return GNUTLS_E_INVALID_REQUEST;
2733 ret = gnutls_x509_crt_get_verify_algorithm (crt, signature, &algo);
2734 if (ret < 0)
2735 return gnutls_assert_val(ret);
2737 /* Read the MPI parameters from the issuer's certificate.
2739 ret =
2740 _gnutls_x509_crt_get_mpis (crt, &params);
2741 if (ret < 0)
2743 gnutls_assert ();
2744 return ret;
2747 ret =
2748 pubkey_verify_hashed_data (gnutls_x509_crt_get_pk_algorithm (crt, NULL), algo,
2749 hash, signature, &params);
2750 if (ret < 0)
2752 gnutls_assert ();
2755 /* release all allocated MPIs
2757 gnutls_pk_params_release(&params);
2759 return ret;
2763 * gnutls_x509_crt_get_crl_dist_points:
2764 * @cert: should contain a #gnutls_x509_crt_t structure
2765 * @seq: specifies the sequence number of the distribution point (0 for the first one, 1 for the second etc.)
2766 * @ret: is the place where the distribution point will be copied to
2767 * @ret_size: holds the size of ret.
2768 * @reason_flags: Revocation reasons flags.
2769 * @critical: will be non (0) if the extension is marked as critical (may be null)
2771 * This function retrieves the CRL distribution points (2.5.29.31),
2772 * contained in the given certificate in the X509v3 Certificate
2773 * Extensions.
2775 * @reason_flags should be an ORed sequence of
2776 * %GNUTLS_CRL_REASON_UNUSED, %GNUTLS_CRL_REASON_KEY_COMPROMISE,
2777 * %GNUTLS_CRL_REASON_CA_COMPROMISE,
2778 * %GNUTLS_CRL_REASON_AFFILIATION_CHANGED,
2779 * %GNUTLS_CRL_REASON_SUPERSEEDED,
2780 * %GNUTLS_CRL_REASON_CESSATION_OF_OPERATION,
2781 * %GNUTLS_CRL_REASON_CERTIFICATE_HOLD,
2782 * %GNUTLS_CRL_REASON_PRIVILEGE_WITHDRAWN,
2783 * %GNUTLS_CRL_REASON_AA_COMPROMISE, or (0) for all possible reasons.
2785 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER and updates @ret_size if
2786 * @ret_size is not enough to hold the distribution point, or the
2787 * type of the distribution point if everything was ok. The type is
2788 * one of the enumerated %gnutls_x509_subject_alt_name_t. If the
2789 * certificate does not have an Alternative name with the specified
2790 * sequence number then %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is
2791 * returned.
2794 gnutls_x509_crt_get_crl_dist_points (gnutls_x509_crt_t cert,
2795 unsigned int seq, void *ret,
2796 size_t * ret_size,
2797 unsigned int *reason_flags,
2798 unsigned int *critical)
2800 int result;
2801 gnutls_datum_t dist_points = { NULL, 0 };
2802 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2803 char name[ASN1_MAX_NAME_SIZE];
2804 int len;
2805 gnutls_x509_subject_alt_name_t type;
2806 uint8_t reasons[2];
2808 if (cert == NULL)
2810 gnutls_assert ();
2811 return GNUTLS_E_INVALID_REQUEST;
2814 if (*ret_size > 0 && ret)
2815 memset (ret, 0, *ret_size);
2816 else
2817 *ret_size = 0;
2819 if (reason_flags)
2820 *reason_flags = 0;
2822 result =
2823 _gnutls_x509_crt_get_extension (cert, "2.5.29.31", 0, &dist_points,
2824 critical);
2825 if (result < 0)
2827 return result;
2830 if (dist_points.size == 0 || dist_points.data == NULL)
2832 gnutls_assert ();
2833 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2836 result = asn1_create_element
2837 (_gnutls_get_pkix (), "PKIX1.CRLDistributionPoints", &c2);
2838 if (result != ASN1_SUCCESS)
2840 gnutls_assert ();
2841 _gnutls_free_datum (&dist_points);
2842 return _gnutls_asn2err (result);
2845 result = asn1_der_decoding (&c2, dist_points.data, dist_points.size, NULL);
2846 _gnutls_free_datum (&dist_points);
2848 if (result != ASN1_SUCCESS)
2850 gnutls_assert ();
2851 asn1_delete_structure (&c2);
2852 return _gnutls_asn2err (result);
2855 /* Return the different names from the first CRLDistr. point.
2856 * The whole thing is a mess.
2858 _gnutls_str_cpy (name, sizeof (name), "?1.distributionPoint.fullName");
2860 result = _gnutls_parse_general_name (c2, name, seq, ret, ret_size, NULL, 0);
2861 if (result < 0)
2863 asn1_delete_structure (&c2);
2864 return result;
2867 type = result;
2870 /* Read the CRL reasons.
2872 if (reason_flags)
2874 _gnutls_str_cpy (name, sizeof (name), "?1.reasons");
2876 reasons[0] = reasons[1] = 0;
2878 len = sizeof (reasons);
2879 result = asn1_read_value (c2, name, reasons, &len);
2881 if (result != ASN1_VALUE_NOT_FOUND && result != ASN1_SUCCESS)
2883 gnutls_assert ();
2884 asn1_delete_structure (&c2);
2885 return _gnutls_asn2err (result);
2888 *reason_flags = reasons[0] | (reasons[1] << 8);
2891 asn1_delete_structure (&c2);
2893 return type;
2897 * gnutls_x509_crt_get_key_purpose_oid:
2898 * @cert: should contain a #gnutls_x509_crt_t structure
2899 * @indx: This specifies which OID to return. Use (0) to get the first one.
2900 * @oid: a pointer to a buffer to hold the OID (may be null)
2901 * @oid_size: initially holds the size of @oid
2902 * @critical: output flag to indicate criticality of extension
2904 * This function will extract the key purpose OIDs of the Certificate
2905 * specified by the given index. These are stored in the Extended Key
2906 * Usage extension (2.5.29.37) See the GNUTLS_KP_* definitions for
2907 * human readable names.
2909 * If @oid is null then only the size will be filled. The @oid
2910 * returned will be null terminated, although @oid_size will not
2911 * account for the trailing null.
2913 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
2914 * not long enough, and in that case the *oid_size will be updated
2915 * with the required size. On success 0 is returned.
2918 gnutls_x509_crt_get_key_purpose_oid (gnutls_x509_crt_t cert,
2919 int indx, void *oid, size_t * oid_size,
2920 unsigned int *critical)
2922 char tmpstr[ASN1_MAX_NAME_SIZE];
2923 int result, len;
2924 gnutls_datum_t id;
2925 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2927 if (cert == NULL)
2929 gnutls_assert ();
2930 return GNUTLS_E_INVALID_REQUEST;
2933 if (oid)
2934 memset (oid, 0, *oid_size);
2935 else
2936 *oid_size = 0;
2938 if ((result =
2939 _gnutls_x509_crt_get_extension (cert, "2.5.29.37", 0, &id,
2940 critical)) < 0)
2942 return result;
2945 if (id.size == 0 || id.data == NULL)
2947 gnutls_assert ();
2948 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2951 result = asn1_create_element
2952 (_gnutls_get_pkix (), "PKIX1.ExtKeyUsageSyntax", &c2);
2953 if (result != ASN1_SUCCESS)
2955 gnutls_assert ();
2956 _gnutls_free_datum (&id);
2957 return _gnutls_asn2err (result);
2960 result = asn1_der_decoding (&c2, id.data, id.size, NULL);
2961 _gnutls_free_datum (&id);
2963 if (result != ASN1_SUCCESS)
2965 gnutls_assert ();
2966 asn1_delete_structure (&c2);
2967 return _gnutls_asn2err (result);
2970 indx++;
2971 /* create a string like "?1"
2973 snprintf (tmpstr, sizeof (tmpstr), "?%u", indx);
2975 len = *oid_size;
2976 result = asn1_read_value (c2, tmpstr, oid, &len);
2978 *oid_size = len;
2979 asn1_delete_structure (&c2);
2981 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
2983 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2986 if (result != ASN1_SUCCESS)
2988 gnutls_assert ();
2989 return _gnutls_asn2err (result);
2992 return 0;
2997 * gnutls_x509_crt_get_pk_rsa_raw:
2998 * @crt: Holds the certificate
2999 * @m: will hold the modulus
3000 * @e: will hold the public exponent
3002 * This function will export the RSA public key's parameters found in
3003 * the given structure. The new parameters will be allocated using
3004 * gnutls_malloc() and will be stored in the appropriate datum.
3006 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3009 gnutls_x509_crt_get_pk_rsa_raw (gnutls_x509_crt_t crt,
3010 gnutls_datum_t * m, gnutls_datum_t * e)
3012 int ret;
3013 gnutls_pk_params_st params;
3015 if (crt == NULL)
3017 gnutls_assert ();
3018 return GNUTLS_E_INVALID_REQUEST;
3021 ret = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
3022 if (ret != GNUTLS_PK_RSA)
3024 gnutls_assert ();
3025 return GNUTLS_E_INVALID_REQUEST;
3028 ret = _gnutls_x509_crt_get_mpis (crt, &params);
3029 if (ret < 0)
3031 gnutls_assert ();
3032 return ret;
3035 ret = _gnutls_mpi_dprint_lz (params.params[0], m);
3036 if (ret < 0)
3038 gnutls_assert ();
3039 goto cleanup;
3042 ret = _gnutls_mpi_dprint_lz (params.params[1], e);
3043 if (ret < 0)
3045 gnutls_assert ();
3046 _gnutls_free_datum (m);
3047 goto cleanup;
3050 ret = 0;
3052 cleanup:
3053 gnutls_pk_params_release(&params);
3054 return ret;
3058 * gnutls_x509_crt_get_pk_dsa_raw:
3059 * @crt: Holds the certificate
3060 * @p: will hold the p
3061 * @q: will hold the q
3062 * @g: will hold the g
3063 * @y: will hold the y
3065 * This function will export the DSA public key's parameters found in
3066 * the given certificate. The new parameters will be allocated using
3067 * gnutls_malloc() and will be stored in the appropriate datum.
3069 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3072 gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt,
3073 gnutls_datum_t * p, gnutls_datum_t * q,
3074 gnutls_datum_t * g, gnutls_datum_t * y)
3076 int ret;
3077 gnutls_pk_params_st params;
3079 if (crt == NULL)
3081 gnutls_assert ();
3082 return GNUTLS_E_INVALID_REQUEST;
3085 ret = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
3086 if (ret != GNUTLS_PK_DSA)
3088 gnutls_assert ();
3089 return GNUTLS_E_INVALID_REQUEST;
3092 ret = _gnutls_x509_crt_get_mpis (crt, &params);
3093 if (ret < 0)
3095 gnutls_assert ();
3096 return ret;
3100 /* P */
3101 ret = _gnutls_mpi_dprint_lz (params.params[0], p);
3102 if (ret < 0)
3104 gnutls_assert ();
3105 goto cleanup;
3108 /* Q */
3109 ret = _gnutls_mpi_dprint_lz (params.params[1], q);
3110 if (ret < 0)
3112 gnutls_assert ();
3113 _gnutls_free_datum (p);
3114 goto cleanup;
3118 /* G */
3119 ret = _gnutls_mpi_dprint_lz (params.params[2], g);
3120 if (ret < 0)
3122 gnutls_assert ();
3123 _gnutls_free_datum (p);
3124 _gnutls_free_datum (q);
3125 goto cleanup;
3129 /* Y */
3130 ret = _gnutls_mpi_dprint_lz (params.params[3], y);
3131 if (ret < 0)
3133 gnutls_assert ();
3134 _gnutls_free_datum (p);
3135 _gnutls_free_datum (g);
3136 _gnutls_free_datum (q);
3137 goto cleanup;
3140 ret = 0;
3142 cleanup:
3143 gnutls_pk_params_release(&params);
3144 return ret;
3149 * gnutls_x509_crt_list_import2:
3150 * @certs: The structures to store the parsed certificate. Must not be initialized.
3151 * @size: It will contain the size of the list.
3152 * @data: The PEM encoded certificate.
3153 * @format: One of DER or PEM.
3154 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
3156 * This function will convert the given PEM encoded certificate list
3157 * to the native gnutls_x509_crt_t format. The output will be stored
3158 * in @certs. They will be automatically initialized.
3160 * If the Certificate is PEM encoded it should have a header of "X509
3161 * CERTIFICATE", or "CERTIFICATE".
3163 * Returns: the number of certificates read or a negative error value.
3165 * Since: 3.0
3168 gnutls_x509_crt_list_import2 (gnutls_x509_crt_t ** certs,
3169 unsigned int * size,
3170 const gnutls_datum_t * data,
3171 gnutls_x509_crt_fmt_t format, unsigned int flags)
3173 unsigned int init = 1024;
3174 int ret;
3176 *certs = gnutls_malloc(sizeof(gnutls_x509_crt_t)*init);
3177 if (*certs == NULL)
3179 gnutls_assert();
3180 return GNUTLS_E_MEMORY_ERROR;
3183 ret = gnutls_x509_crt_list_import(*certs, &init, data, format, GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
3184 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
3186 *certs = gnutls_realloc_fast(*certs, sizeof(gnutls_x509_crt_t)*init);
3187 if (*certs == NULL)
3189 gnutls_assert();
3190 return GNUTLS_E_MEMORY_ERROR;
3193 ret = gnutls_x509_crt_list_import(*certs, &init, data, format, flags);
3196 if (ret < 0)
3198 gnutls_free(*certs);
3199 *certs = NULL;
3200 return ret;
3203 *size = init;
3204 return 0;
3207 static int check_if_sorted(gnutls_x509_crt_t * crt, int nr)
3209 char prev_dn[MAX_DN];
3210 char dn[MAX_DN];
3211 size_t prev_dn_size, dn_size;
3212 int i, ret;
3214 /* check if the X.509 list is ordered */
3215 if (nr > 1)
3218 for (i=0;i<nr;i++)
3220 if (i>0)
3222 dn_size = sizeof(dn);
3223 ret = gnutls_x509_crt_get_dn(crt[i], dn, &dn_size);
3224 if (ret < 0)
3226 ret = gnutls_assert_val(ret);
3227 goto cleanup;
3230 if (dn_size != prev_dn_size || memcmp(dn, prev_dn, dn_size) != 0)
3232 ret = gnutls_assert_val(GNUTLS_E_CERTIFICATE_LIST_UNSORTED);
3233 goto cleanup;
3237 prev_dn_size = sizeof(prev_dn);
3238 ret = gnutls_x509_crt_get_issuer_dn(crt[i], prev_dn, &prev_dn_size);
3239 if (ret < 0)
3241 ret = gnutls_assert_val(ret);
3242 goto cleanup;
3247 ret = 0;
3249 cleanup:
3250 return ret;
3255 * gnutls_x509_crt_list_import:
3256 * @certs: The structures to store the parsed certificate. Must not be initialized.
3257 * @cert_max: Initially must hold the maximum number of certs. It will be updated with the number of certs available.
3258 * @data: The PEM encoded certificate.
3259 * @format: One of DER or PEM.
3260 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
3262 * This function will convert the given PEM encoded certificate list
3263 * to the native gnutls_x509_crt_t format. The output will be stored
3264 * in @certs. They will be automatically initialized.
3266 * The flag %GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED will cause
3267 * import to fail if the certificates in the provided buffer are more
3268 * than the available structures. The %GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED
3269 * flag will cause the function to fail if the provided list is not
3270 * sorted from subject to issuer.
3272 * If the Certificate is PEM encoded it should have a header of "X509
3273 * CERTIFICATE", or "CERTIFICATE".
3275 * Returns: the number of certificates read or a negative error value.
3278 gnutls_x509_crt_list_import (gnutls_x509_crt_t * certs,
3279 unsigned int *cert_max,
3280 const gnutls_datum_t * data,
3281 gnutls_x509_crt_fmt_t format, unsigned int flags)
3283 int size;
3284 const char *ptr;
3285 gnutls_datum_t tmp;
3286 int ret, nocopy = 0;
3287 unsigned int count = 0, j;
3289 if (format == GNUTLS_X509_FMT_DER)
3291 if (*cert_max < 1)
3293 *cert_max = 1;
3294 return GNUTLS_E_SHORT_MEMORY_BUFFER;
3297 count = 1; /* import only the first one */
3299 ret = gnutls_x509_crt_init (&certs[0]);
3300 if (ret < 0)
3302 gnutls_assert ();
3303 goto error;
3306 ret = gnutls_x509_crt_import (certs[0], data, format);
3307 if (ret < 0)
3309 gnutls_assert ();
3310 goto error;
3313 *cert_max = 1;
3314 return 1;
3317 /* move to the certificate
3319 ptr = memmem (data->data, data->size,
3320 PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
3321 if (ptr == NULL)
3322 ptr = memmem (data->data, data->size,
3323 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
3325 if (ptr == NULL)
3326 return gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_FOUND);
3328 count = 0;
3332 if (count >= *cert_max)
3334 if (!(flags & GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED))
3335 break;
3336 else
3337 nocopy = 1;
3340 if (!nocopy)
3342 ret = gnutls_x509_crt_init (&certs[count]);
3343 if (ret < 0)
3345 gnutls_assert ();
3346 goto error;
3349 tmp.data = (void *) ptr;
3350 tmp.size = data->size - (ptr - (char *) data->data);
3352 ret =
3353 gnutls_x509_crt_import (certs[count], &tmp, GNUTLS_X509_FMT_PEM);
3354 if (ret < 0)
3356 gnutls_assert ();
3357 goto error;
3361 /* now we move ptr after the pem header
3363 ptr++;
3364 /* find the next certificate (if any)
3366 size = data->size - (ptr - (char *) data->data);
3368 if (size > 0)
3370 char *ptr2;
3372 ptr2 = memmem (ptr, size, PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
3373 if (ptr2 == NULL)
3374 ptr2 = memmem (ptr, size, PEM_CERT_SEP2,
3375 sizeof (PEM_CERT_SEP2) - 1);
3377 ptr = ptr2;
3379 else
3380 ptr = NULL;
3382 count++;
3384 while (ptr != NULL);
3386 *cert_max = count;
3388 if (flags & GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED)
3390 ret = check_if_sorted(certs, *cert_max);
3391 if (ret < 0)
3393 gnutls_assert();
3394 goto error;
3398 if (nocopy == 0)
3399 return count;
3400 else
3401 return GNUTLS_E_SHORT_MEMORY_BUFFER;
3403 error:
3404 for (j = 0; j < count; j++)
3405 gnutls_x509_crt_deinit (certs[j]);
3406 return ret;
3410 * gnutls_x509_crt_get_subject_unique_id:
3411 * @crt: Holds the certificate
3412 * @buf: user allocated memory buffer, will hold the unique id
3413 * @buf_size: size of user allocated memory buffer (on input), will hold
3414 * actual size of the unique ID on return.
3416 * This function will extract the subjectUniqueID value (if present) for
3417 * the given certificate.
3419 * If the user allocated memory buffer is not large enough to hold the
3420 * full subjectUniqueID, then a GNUTLS_E_SHORT_MEMORY_BUFFER error will be
3421 * returned, and buf_size will be set to the actual length.
3423 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3426 gnutls_x509_crt_get_subject_unique_id (gnutls_x509_crt_t crt, char *buf,
3427 size_t * buf_size)
3429 int result;
3430 gnutls_datum_t datum = { NULL, 0 };
3432 result =
3433 _gnutls_x509_read_value (crt->cert, "tbsCertificate.subjectUniqueID",
3434 &datum, 2);
3436 if (datum.size > *buf_size)
3437 { /* then we're not going to fit */
3438 *buf_size = datum.size;
3439 buf[0] = '\0';
3440 result = GNUTLS_E_SHORT_MEMORY_BUFFER;
3442 else
3444 *buf_size = datum.size;
3445 memcpy (buf, datum.data, datum.size);
3448 _gnutls_free_datum (&datum);
3450 return result;
3454 * gnutls_x509_crt_get_issuer_unique_id:
3455 * @crt: Holds the certificate
3456 * @buf: user allocated memory buffer, will hold the unique id
3457 * @buf_size: size of user allocated memory buffer (on input), will hold
3458 * actual size of the unique ID on return.
3460 * This function will extract the issuerUniqueID value (if present) for
3461 * the given certificate.
3463 * If the user allocated memory buffer is not large enough to hold the
3464 * full subjectUniqueID, then a GNUTLS_E_SHORT_MEMORY_BUFFER error will be
3465 * returned, and buf_size will be set to the actual length.
3467 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3469 * Since: 2.12.0
3472 gnutls_x509_crt_get_issuer_unique_id (gnutls_x509_crt_t crt, char *buf,
3473 size_t * buf_size)
3475 int result;
3476 gnutls_datum_t datum = { NULL, 0 };
3478 result =
3479 _gnutls_x509_read_value (crt->cert, "tbsCertificate.issuerUniqueID",
3480 &datum, 2);
3482 if (datum.size > *buf_size)
3483 { /* then we're not going to fit */
3484 *buf_size = datum.size;
3485 buf[0] = '\0';
3486 result = GNUTLS_E_SHORT_MEMORY_BUFFER;
3488 else
3490 *buf_size = datum.size;
3491 memcpy (buf, datum.data, datum.size);
3494 _gnutls_free_datum (&datum);
3496 return result;
3499 static int
3500 _gnutls_parse_aia (ASN1_TYPE src,
3501 unsigned int seq,
3502 int what,
3503 gnutls_datum_t * data)
3505 int len;
3506 char nptr[ASN1_MAX_NAME_SIZE];
3507 int result;
3508 gnutls_datum_t d;
3509 const char *oid = NULL;
3511 seq++; /* 0->1, 1->2 etc */
3512 switch (what)
3514 case GNUTLS_IA_ACCESSMETHOD_OID:
3515 snprintf (nptr, sizeof (nptr), "?%u.accessMethod", seq);
3516 break;
3518 case GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE:
3519 snprintf (nptr, sizeof (nptr), "?%u.accessLocation", seq);
3520 break;
3522 case GNUTLS_IA_CAISSUERS_URI:
3523 oid = GNUTLS_OID_AD_CAISSUERS;
3524 /* fall through */
3526 case GNUTLS_IA_OCSP_URI:
3527 if (oid == NULL)
3528 oid = GNUTLS_OID_AD_OCSP;
3530 char tmpoid[20];
3531 snprintf (nptr, sizeof (nptr), "?%u.accessMethod", seq);
3532 len = sizeof (tmpoid);
3533 result = asn1_read_value (src, nptr, tmpoid, &len);
3535 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
3536 return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
3538 if (result != ASN1_SUCCESS)
3540 gnutls_assert ();
3541 return _gnutls_asn2err (result);
3543 if ((unsigned)len != strlen (oid) + 1 || memcmp (tmpoid, oid, len) != 0)
3544 return gnutls_assert_val(GNUTLS_E_UNKNOWN_ALGORITHM);
3546 /* fall through */
3548 case GNUTLS_IA_URI:
3549 snprintf (nptr, sizeof (nptr),
3550 "?%u.accessLocation.uniformResourceIdentifier", seq);
3551 break;
3553 default:
3554 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
3557 len = 0;
3558 result = asn1_read_value (src, nptr, NULL, &len);
3559 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
3560 return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
3562 if (result != ASN1_MEM_ERROR)
3564 gnutls_assert ();
3565 return _gnutls_asn2err (result);
3568 d.size = len;
3570 d.data = gnutls_malloc (d.size);
3571 if (d.data == NULL)
3572 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
3574 result = asn1_read_value (src, nptr, d.data, &len);
3575 if (result != ASN1_SUCCESS)
3577 gnutls_assert ();
3578 gnutls_free (d.data);
3579 return _gnutls_asn2err (result);
3582 if (data)
3584 data->data = d.data;
3585 data->size = d.size;
3587 else
3588 gnutls_free (d.data);
3590 return 0;
3594 * gnutls_x509_crt_get_authority_info_access:
3595 * @crt: Holds the certificate
3596 * @seq: specifies the sequence number of the access descriptor (0 for the first one, 1 for the second etc.)
3597 * @what: what data to get, a #gnutls_info_access_what_t type.
3598 * @data: output data to be freed with gnutls_free().
3599 * @critical: pointer to output integer that is set to non-0 if the extension is marked as critical (may be %NULL)
3601 * This function extracts the Authority Information Access (AIA)
3602 * extension, see RFC 5280 section 4.2.2.1 for more information. The
3603 * AIA extension holds a sequence of AccessDescription (AD) data:
3605 * <informalexample><programlisting>
3606 * AuthorityInfoAccessSyntax ::=
3607 * SEQUENCE SIZE (1..MAX) OF AccessDescription
3609 * AccessDescription ::= SEQUENCE {
3610 * accessMethod OBJECT IDENTIFIER,
3611 * accessLocation GeneralName }
3612 * </programlisting></informalexample>
3614 * The @seq input parameter is used to indicate which member of the
3615 * sequence the caller is interested in. The first member is 0, the
3616 * second member 1 and so on. When the @seq value is out of bounds,
3617 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
3619 * The type of data returned in @data is specified via @what which
3620 * should be #gnutls_info_access_what_t values.
3622 * If @what is %GNUTLS_IA_ACCESSMETHOD_OID then @data will hold the
3623 * accessMethod OID (e.g., "1.3.6.1.5.5.7.48.1").
3625 * If @what is %GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE, @data will
3626 * hold the accessLocation GeneralName type (e.g.,
3627 * "uniformResourceIdentifier").
3629 * If @what is %GNUTLS_IA_URI, @data will hold the accessLocation URI
3630 * data. Requesting this @what value leads to an error if the
3631 * accessLocation is not of the "uniformResourceIdentifier" type.
3633 * If @what is %GNUTLS_IA_OCSP_URI, @data will hold the OCSP URI.
3634 * Requesting this @what value leads to an error if the accessMethod
3635 * is not 1.3.6.1.5.5.7.48.1 aka OSCP, or if accessLocation is not of
3636 * the "uniformResourceIdentifier" type.
3638 * If @what is %GNUTLS_IA_CAISSUERS_URI, @data will hold the caIssuers
3639 * URI. Requesting this @what value leads to an error if the
3640 * accessMethod is not 1.3.6.1.5.5.7.48.2 aka caIssuers, or if
3641 * accessLocation is not of the "uniformResourceIdentifier" type.
3643 * More @what values may be allocated in the future as needed.
3645 * If @data is NULL, the function does the same without storing the
3646 * output data, that is, it will set @critical and do error checking
3647 * as usual.
3649 * The value of the critical flag is returned in *@critical. Supply a
3650 * NULL @critical if you want the function to make sure the extension
3651 * is non-critical, as required by RFC 5280.
3653 * Returns: %GNUTLS_E_SUCCESS on success, %GNUTLS_E_INVALID_REQUEST on
3654 * invalid @crt, %GNUTLS_E_CONSTRAINT_ERROR if the extension is
3655 * incorrectly marked as critical (use a non-NULL @critical to
3656 * override), %GNUTLS_E_UNKNOWN_ALGORITHM if the requested OID does
3657 * not match (e.g., when using %GNUTLS_IA_OCSP_URI), otherwise a
3658 * negative error code.
3660 * Since: 3.0
3663 gnutls_x509_crt_get_authority_info_access (gnutls_x509_crt_t crt,
3664 unsigned int seq,
3665 int what,
3666 gnutls_datum_t * data,
3667 unsigned int *critical)
3669 int ret;
3670 gnutls_datum_t aia;
3671 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
3673 if (crt == NULL)
3675 gnutls_assert ();
3676 return GNUTLS_E_INVALID_REQUEST;
3679 if ((ret = _gnutls_x509_crt_get_extension (crt, GNUTLS_OID_AIA, 0, &aia,
3680 critical)) < 0)
3681 return ret;
3683 if (aia.size == 0 || aia.data == NULL)
3685 gnutls_assert ();
3686 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3689 if (critical && *critical)
3690 return GNUTLS_E_CONSTRAINT_ERROR;
3692 ret = asn1_create_element (_gnutls_get_pkix (),
3693 "PKIX1.AuthorityInfoAccessSyntax", &c2);
3694 if (ret != ASN1_SUCCESS)
3696 gnutls_assert ();
3697 _gnutls_free_datum (&aia);
3698 return _gnutls_asn2err (ret);
3701 ret = asn1_der_decoding (&c2, aia.data, aia.size, NULL);
3702 /* asn1_print_structure (stdout, c2, "", ASN1_PRINT_ALL); */
3703 _gnutls_free_datum (&aia);
3704 if (ret != ASN1_SUCCESS)
3706 gnutls_assert ();
3707 asn1_delete_structure (&c2);
3708 return _gnutls_asn2err (ret);
3711 ret = _gnutls_parse_aia (c2, seq, what, data);
3713 asn1_delete_structure (&c2);
3714 if (ret < 0)
3715 gnutls_assert ();
3717 return ret;