check for either iconv or libiconv.
[gnutls.git] / lib / x509 / x509.c
blob7c65e7d65646524042968f974c941d64a8155a49
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 /* Try the first header */
182 result =
183 _gnutls_fbase64_decode (PEM_X509_CERT2, data->data, data->size, &_data);
185 if (result <= 0)
187 /* try for the second header */
188 result =
189 _gnutls_fbase64_decode (PEM_X509_CERT, data->data,
190 data->size, &_data);
192 if (result < 0)
194 gnutls_assert ();
195 return result;
199 need_free = 1;
202 if (cert->expanded)
204 /* Any earlier asn1_der_decoding will modify the ASN.1
205 structure, so we need to replace it with a fresh
206 structure. */
207 asn1_delete_structure (&cert->cert);
209 result = asn1_create_element (_gnutls_get_pkix (),
210 "PKIX1.Certificate", &cert->cert);
211 if (result != ASN1_SUCCESS)
213 result = _gnutls_asn2err (result);
214 gnutls_assert ();
215 goto cleanup;
219 result = asn1_der_decoding (&cert->cert, _data.data, _data.size, NULL);
220 if (result != ASN1_SUCCESS)
222 result = _gnutls_asn2err (result);
223 gnutls_assert ();
224 goto cleanup;
227 cert->expanded = 1;
229 /* Since we do not want to disable any extension
231 cert->use_extensions = 1;
232 if (need_free)
233 _gnutls_free_datum (&_data);
235 return 0;
237 cleanup:
238 if (need_free)
239 _gnutls_free_datum (&_data);
240 return result;
245 * gnutls_x509_crt_get_issuer_dn:
246 * @cert: should contain a #gnutls_x509_crt_t structure
247 * @buf: a pointer to a structure to hold the name (may be null)
248 * @buf_size: initially holds the size of @buf
250 * This function will copy the name of the Certificate issuer in the
251 * provided buffer. The name will be in the form
252 * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC4514. The output string
253 * will be ASCII or UTF-8 encoded, depending on the certificate data.
255 * If @buf is null then only the size will be filled.
257 * Returns: GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
258 * long enough, and in that case the @buf_size will be updated with
259 * the required size. On success 0 is returned.
262 gnutls_x509_crt_get_issuer_dn (gnutls_x509_crt_t cert, char *buf,
263 size_t * buf_size)
265 if (cert == NULL)
267 gnutls_assert ();
268 return GNUTLS_E_INVALID_REQUEST;
271 return _gnutls_x509_parse_dn (cert->cert,
272 "tbsCertificate.issuer.rdnSequence", buf,
273 buf_size);
277 * gnutls_x509_crt_get_issuer_dn_by_oid:
278 * @cert: should contain a #gnutls_x509_crt_t structure
279 * @oid: holds an Object Identified in null terminated string
280 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use (0) to get the first one.
281 * @raw_flag: If non-zero returns the raw DER data of the DN part.
282 * @buf: a pointer to a structure to hold the name (may be null)
283 * @buf_size: initially holds the size of @buf
285 * This function will extract the part of the name of the Certificate
286 * issuer specified by the given OID. The output, if the raw flag is not
287 * used, will be encoded as described in RFC4514. Thus a string that is
288 * ASCII or UTF-8 encoded, depending on the certificate data.
290 * Some helper macros with popular OIDs can be found in gnutls/x509.h
291 * If raw flag is (0), this function will only return known OIDs as
292 * text. Other OIDs will be DER encoded, as described in RFC4514 --
293 * in hex format with a '#' prefix. You can check about known OIDs
294 * using gnutls_x509_dn_oid_known().
296 * If @buf is null then only the size will be filled. If the @raw_flag
297 * is not specified the output is always null terminated, although the
298 * @buf_size will not include the null character.
300 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
301 * long enough, and in that case the @buf_size will be updated with
302 * the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there
303 * are no data in the current index. On success 0 is returned.
306 gnutls_x509_crt_get_issuer_dn_by_oid (gnutls_x509_crt_t cert,
307 const char *oid, int indx,
308 unsigned int raw_flag, void *buf,
309 size_t * buf_size)
311 if (cert == NULL)
313 gnutls_assert ();
314 return GNUTLS_E_INVALID_REQUEST;
317 return _gnutls_x509_parse_dn_oid (cert->cert,
318 "tbsCertificate.issuer.rdnSequence",
319 oid, indx, raw_flag, buf, buf_size);
323 * gnutls_x509_crt_get_issuer_dn_oid:
324 * @cert: should contain a #gnutls_x509_crt_t structure
325 * @indx: This specifies which OID to return. Use (0) to get the first one.
326 * @oid: a pointer to a buffer to hold the OID (may be null)
327 * @oid_size: initially holds the size of @oid
329 * This function will extract the OIDs of the name of the Certificate
330 * issuer specified by the given index.
332 * If @oid is null then only the size will be filled. The @oid
333 * returned will be null terminated, although @oid_size will not
334 * account for the trailing null.
336 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
337 * long enough, and in that case the @buf_size will be updated with
338 * the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there
339 * are no data in the current index. On success 0 is returned.
342 gnutls_x509_crt_get_issuer_dn_oid (gnutls_x509_crt_t cert,
343 int indx, void *oid, size_t * oid_size)
345 if (cert == NULL)
347 gnutls_assert ();
348 return GNUTLS_E_INVALID_REQUEST;
351 return _gnutls_x509_get_dn_oid (cert->cert,
352 "tbsCertificate.issuer.rdnSequence",
353 indx, oid, oid_size);
357 * gnutls_x509_crt_get_dn:
358 * @cert: should contain a #gnutls_x509_crt_t structure
359 * @buf: a pointer to a structure to hold the name (may be null)
360 * @buf_size: initially holds the size of @buf
362 * This function will copy the name of the Certificate in the provided
363 * buffer. The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
364 * described in RFC4514. The output string will be ASCII or UTF-8
365 * encoded, depending on the certificate data.
367 * If @buf is null then only the size will be filled.
369 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
370 * long enough, and in that case the @buf_size will be updated
371 * with the required size. On success 0 is returned.
374 gnutls_x509_crt_get_dn (gnutls_x509_crt_t cert, char *buf,
375 size_t * buf_size)
377 if (cert == NULL)
379 gnutls_assert ();
380 return GNUTLS_E_INVALID_REQUEST;
383 return _gnutls_x509_parse_dn (cert->cert,
384 "tbsCertificate.subject.rdnSequence", buf,
385 buf_size);
389 * gnutls_x509_crt_get_dn_by_oid:
390 * @cert: should contain a #gnutls_x509_crt_t structure
391 * @oid: holds an Object Identified in null terminated string
392 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use (0) to get the first one.
393 * @raw_flag: If non-zero returns the raw DER data of the DN part.
394 * @buf: a pointer where the DN part will be copied (may be null).
395 * @buf_size: initially holds the size of @buf
397 * This function will extract the part of the name of the Certificate
398 * subject specified by the given OID. The output, if the raw flag is
399 * not used, will be encoded as described in RFC4514. Thus a string
400 * that is ASCII or UTF-8 encoded, depending on the certificate data.
402 * Some helper macros with popular OIDs can be found in gnutls/x509.h
403 * If raw flag is (0), this function will only return known OIDs as
404 * text. Other OIDs will be DER encoded, as described in RFC4514 --
405 * in hex format with a '#' prefix. You can check about known OIDs
406 * using gnutls_x509_dn_oid_known().
408 * If @buf is null then only the size will be filled. If the @raw_flag
409 * is not specified the output is always null terminated, although the
410 * @buf_size will not include the null character.
412 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
413 * long enough, and in that case the @buf_size will be updated with
414 * the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there
415 * are no data in the current index. On success 0 is returned.
418 gnutls_x509_crt_get_dn_by_oid (gnutls_x509_crt_t cert, const char *oid,
419 int indx, unsigned int raw_flag,
420 void *buf, size_t * buf_size)
422 if (cert == NULL)
424 gnutls_assert ();
425 return GNUTLS_E_INVALID_REQUEST;
428 return _gnutls_x509_parse_dn_oid (cert->cert,
429 "tbsCertificate.subject.rdnSequence",
430 oid, indx, raw_flag, buf, buf_size);
434 * gnutls_x509_crt_get_dn_oid:
435 * @cert: should contain a #gnutls_x509_crt_t structure
436 * @indx: This specifies which OID to return. Use (0) to get the first one.
437 * @oid: a pointer to a buffer to hold the OID (may be null)
438 * @oid_size: initially holds the size of @oid
440 * This function will extract the OIDs of the name of the Certificate
441 * subject specified by the given index.
443 * If @oid is null then only the size will be filled. The @oid
444 * returned will be null terminated, although @oid_size will not
445 * account for the trailing null.
447 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
448 * long enough, and in that case the @buf_size will be updated with
449 * the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there
450 * are no data in the current index. On success 0 is returned.
453 gnutls_x509_crt_get_dn_oid (gnutls_x509_crt_t cert,
454 int indx, void *oid, size_t * oid_size)
456 if (cert == NULL)
458 gnutls_assert ();
459 return GNUTLS_E_INVALID_REQUEST;
462 return _gnutls_x509_get_dn_oid (cert->cert,
463 "tbsCertificate.subject.rdnSequence",
464 indx, oid, oid_size);
468 * gnutls_x509_crt_get_signature_algorithm:
469 * @cert: should contain a #gnutls_x509_crt_t structure
471 * This function will return a value of the #gnutls_sign_algorithm_t
472 * enumeration that is the signature algorithm that has been used to
473 * sign this certificate.
475 * Returns: a #gnutls_sign_algorithm_t value, or a negative error code on
476 * error.
479 gnutls_x509_crt_get_signature_algorithm (gnutls_x509_crt_t cert)
481 return _gnutls_x509_get_signature_algorithm(cert->cert, "signatureAlgorithm.algorithm");
485 * gnutls_x509_crt_get_signature:
486 * @cert: should contain a #gnutls_x509_crt_t structure
487 * @sig: a pointer where the signature part will be copied (may be null).
488 * @sizeof_sig: initially holds the size of @sig
490 * This function will extract the signature field of a certificate.
492 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
493 * negative error value. and a negative error code on error.
496 gnutls_x509_crt_get_signature (gnutls_x509_crt_t cert,
497 char *sig, size_t * sizeof_sig)
499 int result;
500 unsigned int bits;
501 int len;
503 if (cert == NULL)
505 gnutls_assert ();
506 return GNUTLS_E_INVALID_REQUEST;
509 len = 0;
510 result = asn1_read_value (cert->cert, "signature", NULL, &len);
511 if (result != ASN1_MEM_ERROR)
513 gnutls_assert ();
514 return _gnutls_asn2err (result);
517 bits = len;
518 if (bits % 8 != 0)
520 gnutls_assert ();
521 return GNUTLS_E_CERTIFICATE_ERROR;
524 len = bits / 8;
526 if (*sizeof_sig < (unsigned int) len)
528 *sizeof_sig = len;
529 return GNUTLS_E_SHORT_MEMORY_BUFFER;
532 result = asn1_read_value (cert->cert, "signature", sig, &len);
533 if (result != ASN1_SUCCESS)
535 gnutls_assert ();
536 return _gnutls_asn2err (result);
539 return 0;
543 * gnutls_x509_crt_get_version:
544 * @cert: should contain a #gnutls_x509_crt_t structure
546 * This function will return the version of the specified Certificate.
548 * Returns: version of certificate, or a negative error code on error.
551 gnutls_x509_crt_get_version (gnutls_x509_crt_t cert)
553 uint8_t version[8];
554 int len, result;
556 if (cert == NULL)
558 gnutls_assert ();
559 return GNUTLS_E_INVALID_REQUEST;
562 len = sizeof (version);
563 if ((result =
564 asn1_read_value (cert->cert, "tbsCertificate.version", version,
565 &len)) != ASN1_SUCCESS)
568 if (result == ASN1_ELEMENT_NOT_FOUND)
569 return 1; /* the DEFAULT version */
570 gnutls_assert ();
571 return _gnutls_asn2err (result);
574 return (int) version[0] + 1;
578 * gnutls_x509_crt_get_activation_time:
579 * @cert: should contain a #gnutls_x509_crt_t structure
581 * This function will return the time this Certificate was or will be
582 * activated.
584 * Returns: activation time, or (time_t)-1 on error.
586 time_t
587 gnutls_x509_crt_get_activation_time (gnutls_x509_crt_t cert)
589 if (cert == NULL)
591 gnutls_assert ();
592 return (time_t) - 1;
595 return _gnutls_x509_get_time (cert->cert,
596 "tbsCertificate.validity.notBefore", 0);
600 * gnutls_x509_crt_get_expiration_time:
601 * @cert: should contain a #gnutls_x509_crt_t structure
603 * This function will return the time this Certificate was or will be
604 * expired.
606 * Returns: expiration time, or (time_t)-1 on error.
608 time_t
609 gnutls_x509_crt_get_expiration_time (gnutls_x509_crt_t cert)
611 if (cert == NULL)
613 gnutls_assert ();
614 return (time_t) - 1;
617 return _gnutls_x509_get_time (cert->cert,
618 "tbsCertificate.validity.notAfter", 0);
622 * gnutls_x509_crt_get_private_key_usage_period:
623 * @cert: should contain a #gnutls_x509_crt_t structure
624 * @activation: The activation time
625 * @expiration: The expiration time
626 * @critical: the extension status
628 * This function will return the expiration and activation
629 * times of the private key of the certificate. It relies on
630 * the PKIX extension 2.5.29.16 being present.
632 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
633 * if the extension is not present, otherwise a negative error value.
636 gnutls_x509_crt_get_private_key_usage_period (gnutls_x509_crt_t cert, time_t* activation, time_t* expiration,
637 unsigned int *critical)
639 int result, ret;
640 gnutls_datum_t der = {NULL, 0};
641 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
643 if (cert == NULL)
645 gnutls_assert ();
646 return GNUTLS_E_INVALID_REQUEST;
649 ret =
650 _gnutls_x509_crt_get_extension (cert, "2.5.29.16", 0, &der,
651 critical);
652 if (ret < 0)
653 return gnutls_assert_val(ret);
655 if (der.size == 0 || der.data == NULL)
656 return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
658 result = asn1_create_element
659 (_gnutls_get_pkix (), "PKIX1.PrivateKeyUsagePeriod", &c2);
660 if (result != ASN1_SUCCESS)
662 gnutls_assert ();
663 ret = _gnutls_asn2err (result);
664 goto cleanup;
667 result = asn1_der_decoding (&c2, der.data, der.size, NULL);
668 if (result != ASN1_SUCCESS)
670 gnutls_assert ();
671 ret = _gnutls_asn2err (result);
672 goto cleanup;
675 if (activation)
676 *activation = _gnutls_x509_get_time (c2,
677 "notBefore", 1);
679 if (expiration)
680 *expiration = _gnutls_x509_get_time (c2,
681 "notAfter", 1);
683 ret = 0;
685 cleanup:
686 _gnutls_free_datum(&der);
687 asn1_delete_structure (&c2);
689 return ret;
694 * gnutls_x509_crt_get_serial:
695 * @cert: should contain a #gnutls_x509_crt_t structure
696 * @result: The place where the serial number will be copied
697 * @result_size: Holds the size of the result field.
699 * This function will return the X.509 certificate's serial number.
700 * This is obtained by the X509 Certificate serialNumber field. Serial
701 * is not always a 32 or 64bit number. Some CAs use large serial
702 * numbers, thus it may be wise to handle it as something uint8_t.
704 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
705 * negative error value.
708 gnutls_x509_crt_get_serial (gnutls_x509_crt_t cert, void *result,
709 size_t * result_size)
711 int ret, len;
713 if (cert == NULL)
715 gnutls_assert ();
716 return GNUTLS_E_INVALID_REQUEST;
719 len = *result_size;
720 ret =
721 asn1_read_value (cert->cert, "tbsCertificate.serialNumber", result, &len);
722 *result_size = len;
724 if (ret != ASN1_SUCCESS)
726 gnutls_assert ();
727 return _gnutls_asn2err (ret);
730 return 0;
734 * gnutls_x509_crt_get_subject_key_id:
735 * @cert: should contain a #gnutls_x509_crt_t structure
736 * @ret: The place where the identifier will be copied
737 * @ret_size: Holds the size of the result field.
738 * @critical: will be non-zero if the extension is marked as critical (may be null)
740 * This function will return the X.509v3 certificate's subject key
741 * identifier. This is obtained by the X.509 Subject Key identifier
742 * extension field (2.5.29.14).
744 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
745 * if the extension is not present, otherwise a negative error value.
748 gnutls_x509_crt_get_subject_key_id (gnutls_x509_crt_t cert, void *ret,
749 size_t * ret_size, unsigned int *critical)
751 int result, len;
752 gnutls_datum_t id;
753 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
755 if (cert == NULL)
757 gnutls_assert ();
758 return GNUTLS_E_INVALID_REQUEST;
762 if (ret)
763 memset (ret, 0, *ret_size);
764 else
765 *ret_size = 0;
767 if ((result =
768 _gnutls_x509_crt_get_extension (cert, "2.5.29.14", 0, &id,
769 critical)) < 0)
771 return result;
774 if (id.size == 0 || id.data == NULL)
776 gnutls_assert ();
777 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
780 result = asn1_create_element
781 (_gnutls_get_pkix (), "PKIX1.SubjectKeyIdentifier", &c2);
782 if (result != ASN1_SUCCESS)
784 gnutls_assert ();
785 _gnutls_free_datum (&id);
786 return _gnutls_asn2err (result);
789 result = asn1_der_decoding (&c2, id.data, id.size, NULL);
790 _gnutls_free_datum (&id);
792 if (result != ASN1_SUCCESS)
794 gnutls_assert ();
795 asn1_delete_structure (&c2);
796 return _gnutls_asn2err (result);
799 len = *ret_size;
800 result = asn1_read_value (c2, "", ret, &len);
802 *ret_size = len;
803 asn1_delete_structure (&c2);
805 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
807 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
810 if (result != ASN1_SUCCESS)
812 if (result != ASN1_MEM_ERROR)
813 gnutls_assert ();
814 return _gnutls_asn2err (result);
817 return 0;
820 static int
821 _get_authority_key_id (gnutls_x509_crt_t cert, ASN1_TYPE *c2,
822 unsigned int *critical)
824 int ret;
825 gnutls_datum_t id;
827 *c2 = ASN1_TYPE_EMPTY;
829 if (cert == NULL)
831 gnutls_assert ();
832 return GNUTLS_E_INVALID_REQUEST;
835 if ((ret =
836 _gnutls_x509_crt_get_extension (cert, "2.5.29.35", 0, &id,
837 critical)) < 0)
839 return gnutls_assert_val(ret);
842 if (id.size == 0 || id.data == NULL)
844 gnutls_assert ();
845 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
848 ret = asn1_create_element
849 (_gnutls_get_pkix (), "PKIX1.AuthorityKeyIdentifier", c2);
850 if (ret != ASN1_SUCCESS)
852 gnutls_assert ();
853 _gnutls_free_datum (&id);
854 return _gnutls_asn2err (ret);
857 ret = asn1_der_decoding (c2, id.data, id.size, NULL);
858 _gnutls_free_datum (&id);
860 if (ret != ASN1_SUCCESS)
862 gnutls_assert ();
863 asn1_delete_structure (c2);
864 return _gnutls_asn2err (ret);
867 return 0;
871 * gnutls_x509_crt_get_authority_key_gn_serial:
872 * @cert: should contain a #gnutls_x509_crt_t structure
873 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
874 * @alt: is the place where the alternative name will be copied to
875 * @alt_size: holds the size of alt.
876 * @alt_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
877 * @serial: buffer to store the serial number (may be null)
878 * @serial_size: Holds the size of the serial field (may be null)
879 * @critical: will be non-zero if the extension is marked as critical (may be null)
881 * This function will return the X.509 authority key
882 * identifier when stored as a general name (authorityCertIssuer)
883 * and serial number.
885 * Because more than one general names might be stored
886 * @seq can be used as a counter to request them all until
887 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
889 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
890 * if the extension is not present, otherwise a negative error value.
892 * Since: 3.0
895 gnutls_x509_crt_get_authority_key_gn_serial (gnutls_x509_crt_t cert, unsigned int seq, void *alt,
896 size_t * alt_size, unsigned int *alt_type,
897 void* serial, size_t *serial_size,
898 unsigned int *critical)
900 int ret, result, len;
901 ASN1_TYPE c2;
903 ret = _get_authority_key_id(cert, &c2, critical);
904 if (ret < 0)
905 return gnutls_assert_val(ret);
907 ret =
908 _gnutls_parse_general_name (c2, "authorityCertIssuer", seq, alt, alt_size, alt_type,
910 if (ret < 0)
912 ret = gnutls_assert_val(ret);
913 goto fail;
916 if (serial)
918 len = *serial_size;
919 result = asn1_read_value (c2, "authorityCertSerialNumber", serial, &len);
921 *serial_size = len;
923 if (result < 0)
925 ret = _gnutls_asn2err(result);
926 goto fail;
931 ret = 0;
933 fail:
934 asn1_delete_structure (&c2);
936 return ret;
940 * gnutls_x509_crt_get_authority_key_id:
941 * @cert: should contain a #gnutls_x509_crt_t structure
942 * @id: The place where the identifier will be copied
943 * @id_size: Holds the size of the id field.
944 * @critical: will be non-zero if the extension is marked as critical (may be null)
946 * This function will return the X.509v3 certificate authority's key
947 * identifier. This is obtained by the X.509 Authority Key
948 * identifier extension field (2.5.29.35). Note that this function
949 * only returns the keyIdentifier field of the extension and
950 * %GNUTLS_E_X509_UNSUPPORTED_EXTENSION, if the extension contains
951 * the name and serial number of the certificate. In that case
952 * gnutls_x509_crt_get_authority_key_gn_serial() may be used.
954 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
955 * if the extension is not present, otherwise a negative error value.
958 gnutls_x509_crt_get_authority_key_id (gnutls_x509_crt_t cert, void *id,
959 size_t * id_size,
960 unsigned int *critical)
962 int ret, result, len;
963 ASN1_TYPE c2;
965 ret = _get_authority_key_id(cert, &c2, critical);
966 if (ret < 0)
967 return gnutls_assert_val(ret);
969 len = *id_size;
970 result = asn1_read_value (c2, "keyIdentifier", id, &len);
972 *id_size = len;
973 asn1_delete_structure (&c2);
975 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
976 return gnutls_assert_val(GNUTLS_E_X509_UNSUPPORTED_EXTENSION);
978 if (result != ASN1_SUCCESS)
980 if (result != ASN1_MEM_ERROR)
981 gnutls_assert ();
982 return _gnutls_asn2err (result);
985 return 0;
989 * gnutls_x509_crt_get_pk_algorithm:
990 * @cert: should contain a #gnutls_x509_crt_t structure
991 * @bits: if bits is non null it will hold the size of the parameters' in bits
993 * This function will return the public key algorithm of an X.509
994 * certificate.
996 * If bits is non null, it should have enough size to hold the parameters
997 * size in bits. For RSA the bits returned is the modulus.
998 * For DSA the bits returned are of the public
999 * exponent.
1001 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
1002 * success, or a negative error code on error.
1005 gnutls_x509_crt_get_pk_algorithm (gnutls_x509_crt_t cert, unsigned int *bits)
1007 int result;
1009 if (cert == NULL)
1011 gnutls_assert ();
1012 return GNUTLS_E_INVALID_REQUEST;
1015 if (bits)
1016 *bits = 0;
1018 result =
1019 _gnutls_x509_get_pk_algorithm (cert->cert,
1020 "tbsCertificate.subjectPublicKeyInfo",
1021 bits);
1023 if (result < 0)
1025 gnutls_assert ();
1026 return result;
1029 return result;
1033 inline static int
1034 is_type_printable (int type)
1036 if (type == GNUTLS_SAN_DNSNAME || type == GNUTLS_SAN_RFC822NAME ||
1037 type == GNUTLS_SAN_URI)
1038 return 1;
1039 else
1040 return 0;
1043 #define XMPP_OID "1.3.6.1.5.5.7.8.5"
1045 /* returns the type and the name on success.
1046 * Type is also returned as a parameter in case of an error.
1049 _gnutls_parse_general_name (ASN1_TYPE src, const char *src_name,
1050 int seq, void *name, size_t * name_size,
1051 unsigned int *ret_type, int othername_oid)
1053 int len;
1054 char nptr[ASN1_MAX_NAME_SIZE];
1055 int result;
1056 char choice_type[128];
1057 gnutls_x509_subject_alt_name_t type;
1059 seq++; /* 0->1, 1->2 etc */
1061 if (src_name[0] != 0)
1062 snprintf (nptr, sizeof (nptr), "%s.?%u", src_name, seq);
1063 else
1064 snprintf (nptr, sizeof (nptr), "?%u", seq);
1066 len = sizeof (choice_type);
1067 result = asn1_read_value (src, nptr, choice_type, &len);
1069 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
1071 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1074 if (result != ASN1_SUCCESS)
1076 gnutls_assert ();
1077 return _gnutls_asn2err (result);
1081 type = _gnutls_x509_san_find_type (choice_type);
1082 if (type == (gnutls_x509_subject_alt_name_t) - 1)
1084 gnutls_assert ();
1085 return GNUTLS_E_X509_UNKNOWN_SAN;
1088 if (ret_type)
1089 *ret_type = type;
1091 if (type == GNUTLS_SAN_OTHERNAME)
1093 if (othername_oid)
1094 _gnutls_str_cat (nptr, sizeof (nptr), ".otherName.type-id");
1095 else
1096 _gnutls_str_cat (nptr, sizeof (nptr), ".otherName.value");
1098 len = *name_size;
1099 result = asn1_read_value (src, nptr, name, &len);
1100 *name_size = len;
1102 if (result == ASN1_MEM_ERROR)
1103 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1105 if (result != ASN1_SUCCESS)
1107 gnutls_assert ();
1108 return _gnutls_asn2err (result);
1111 if (othername_oid)
1113 if ((unsigned)len > strlen (XMPP_OID) && strcmp (name, XMPP_OID) == 0)
1114 type = GNUTLS_SAN_OTHERNAME_XMPP;
1116 else
1118 char oid[42];
1120 if (src_name[0] != 0)
1121 snprintf (nptr, sizeof (nptr), "%s.?%u.otherName.type-id",
1122 src_name, seq);
1123 else
1124 snprintf (nptr, sizeof (nptr), "?%u.otherName.type-id", seq);
1126 len = sizeof (oid);
1127 result = asn1_read_value (src, nptr, oid, &len);
1128 if (result != ASN1_SUCCESS)
1130 gnutls_assert ();
1131 return _gnutls_asn2err (result);
1134 if ((unsigned)len > strlen (XMPP_OID) && strcmp (oid, XMPP_OID) == 0)
1136 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1137 size_t orig_name_size = *name_size;
1139 result = asn1_create_element
1140 (_gnutls_get_pkix (), "PKIX1.UTF8String", &c2);
1141 if (result != ASN1_SUCCESS)
1143 gnutls_assert ();
1144 return _gnutls_asn2err (result);
1147 result = asn1_der_decoding (&c2, name, *name_size, NULL);
1148 if (result != ASN1_SUCCESS)
1150 gnutls_assert ();
1151 asn1_delete_structure (&c2);
1152 return _gnutls_asn2err (result);
1155 len = *name_size;
1156 result = asn1_read_value (c2, "", name, &len);
1157 if (result != ASN1_SUCCESS)
1159 gnutls_assert ();
1160 asn1_delete_structure (&c2);
1161 *name_size = len + 1;
1162 return _gnutls_asn2err (result);
1164 asn1_delete_structure (&c2);
1166 if ((unsigned)len + 1 > orig_name_size)
1168 gnutls_assert ();
1169 *name_size = len + 1;
1170 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1173 *name_size = len;
1174 /* null terminate it */
1175 ((char *) name)[*name_size] = 0;
1179 else if (type == GNUTLS_SAN_DN)
1181 _gnutls_str_cat (nptr, sizeof (nptr), ".directoryName");
1182 result = _gnutls_x509_parse_dn (src, nptr, name, name_size);
1183 if (result < 0)
1185 gnutls_assert ();
1186 return result;
1189 else if (othername_oid)
1190 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1191 else
1193 size_t orig_name_size = *name_size;
1195 _gnutls_str_cat (nptr, sizeof (nptr), ".");
1196 _gnutls_str_cat (nptr, sizeof (nptr), choice_type);
1198 len = *name_size;
1199 result = asn1_read_value (src, nptr, name, &len);
1200 *name_size = len;
1202 if (result == ASN1_MEM_ERROR)
1204 if (is_type_printable (type))
1205 (*name_size)++;
1206 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1209 if (result != ASN1_SUCCESS)
1211 gnutls_assert ();
1212 return _gnutls_asn2err (result);
1215 if (is_type_printable (type))
1218 if ((unsigned)len + 1 > orig_name_size)
1220 gnutls_assert ();
1221 (*name_size)++;
1222 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1225 /* null terminate it */
1226 ((char *) name)[*name_size] = 0;
1231 return type;
1234 static int
1235 get_alt_name (gnutls_x509_crt_t cert, const char *extension_id,
1236 unsigned int seq, void *alt,
1237 size_t * alt_size, unsigned int *alt_type,
1238 unsigned int *critical, int othername_oid)
1240 int result;
1241 gnutls_datum_t dnsname;
1242 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1244 if (cert == NULL)
1246 gnutls_assert ();
1247 return GNUTLS_E_INVALID_REQUEST;
1250 if (alt)
1251 memset (alt, 0, *alt_size);
1252 else
1253 *alt_size = 0;
1255 if ((result =
1256 _gnutls_x509_crt_get_extension (cert, extension_id, 0, &dnsname,
1257 critical)) < 0)
1259 return result;
1262 if (dnsname.size == 0 || dnsname.data == NULL)
1264 gnutls_assert ();
1265 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1268 if (strcmp ("2.5.29.17", extension_id) == 0)
1269 result = asn1_create_element (_gnutls_get_pkix (),
1270 "PKIX1.SubjectAltName", &c2);
1271 else if (strcmp ("2.5.29.18", extension_id) == 0)
1272 result = asn1_create_element (_gnutls_get_pkix (),
1273 "PKIX1.IssuerAltName", &c2);
1274 else
1276 gnutls_assert ();
1277 return GNUTLS_E_INTERNAL_ERROR;
1280 if (result != ASN1_SUCCESS)
1282 gnutls_assert ();
1283 _gnutls_free_datum (&dnsname);
1284 return _gnutls_asn2err (result);
1287 result = asn1_der_decoding (&c2, dnsname.data, dnsname.size, NULL);
1288 _gnutls_free_datum (&dnsname);
1290 if (result != ASN1_SUCCESS)
1292 gnutls_assert ();
1293 asn1_delete_structure (&c2);
1294 return _gnutls_asn2err (result);
1297 result =
1298 _gnutls_parse_general_name (c2, "", seq, alt, alt_size, alt_type,
1299 othername_oid);
1301 asn1_delete_structure (&c2);
1303 if (result < 0)
1305 gnutls_assert ();
1306 return result;
1309 return result;
1313 * gnutls_x509_crt_get_subject_alt_name:
1314 * @cert: should contain a #gnutls_x509_crt_t structure
1315 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1316 * @san: is the place where the alternative name will be copied to
1317 * @san_size: holds the size of san.
1318 * @critical: will be non-zero if the extension is marked as critical (may be null)
1320 * This function retrieves the Alternative Name (2.5.29.17), contained
1321 * in the given certificate in the X509v3 Certificate Extensions.
1323 * When the SAN type is otherName, it will extract the data in the
1324 * otherName's value field, and %GNUTLS_SAN_OTHERNAME is returned.
1325 * You may use gnutls_x509_crt_get_subject_alt_othername_oid() to get
1326 * the corresponding OID and the "virtual" SAN types (e.g.,
1327 * %GNUTLS_SAN_OTHERNAME_XMPP).
1329 * If an otherName OID is known, the data will be decoded. Otherwise
1330 * the returned data will be DER encoded, and you will have to decode
1331 * it yourself. Currently, only the RFC 3920 id-on-xmppAddr SAN is
1332 * recognized.
1334 * Returns: the alternative subject name type on success, one of the
1335 * enumerated #gnutls_x509_subject_alt_name_t. It will return
1336 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @san_size is not large enough to
1337 * hold the value. In that case @san_size will be updated with the
1338 * required size. If the certificate does not have an Alternative
1339 * name with the specified sequence number then
1340 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1343 gnutls_x509_crt_get_subject_alt_name (gnutls_x509_crt_t cert,
1344 unsigned int seq, void *san,
1345 size_t * san_size,
1346 unsigned int *critical)
1348 return get_alt_name (cert, "2.5.29.17", seq, san, san_size, NULL, critical,
1353 * gnutls_x509_crt_get_issuer_alt_name:
1354 * @cert: should contain a #gnutls_x509_crt_t structure
1355 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1356 * @ian: is the place where the alternative name will be copied to
1357 * @ian_size: holds the size of ian.
1358 * @critical: will be non-zero if the extension is marked as critical (may be null)
1360 * This function retrieves the Issuer Alternative Name (2.5.29.18),
1361 * contained in the given certificate in the X509v3 Certificate
1362 * Extensions.
1364 * When the SAN type is otherName, it will extract the data in the
1365 * otherName's value field, and %GNUTLS_SAN_OTHERNAME is returned.
1366 * You may use gnutls_x509_crt_get_subject_alt_othername_oid() to get
1367 * the corresponding OID and the "virtual" SAN types (e.g.,
1368 * %GNUTLS_SAN_OTHERNAME_XMPP).
1370 * If an otherName OID is known, the data will be decoded. Otherwise
1371 * the returned data will be DER encoded, and you will have to decode
1372 * it yourself. Currently, only the RFC 3920 id-on-xmppAddr Issuer
1373 * AltName is recognized.
1375 * Returns: the alternative issuer name type on success, one of the
1376 * enumerated #gnutls_x509_subject_alt_name_t. It will return
1377 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @ian_size is not large enough
1378 * to hold the value. In that case @ian_size will be updated with
1379 * the required size. If the certificate does not have an
1380 * Alternative name with the specified sequence number then
1381 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1383 * Since: 2.10.0
1386 gnutls_x509_crt_get_issuer_alt_name (gnutls_x509_crt_t cert,
1387 unsigned int seq, void *ian,
1388 size_t * ian_size,
1389 unsigned int *critical)
1391 return get_alt_name (cert, "2.5.29.18", seq, ian, ian_size, NULL, critical,
1396 * gnutls_x509_crt_get_subject_alt_name2:
1397 * @cert: should contain a #gnutls_x509_crt_t structure
1398 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1399 * @san: is the place where the alternative name will be copied to
1400 * @san_size: holds the size of ret.
1401 * @san_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
1402 * @critical: will be non-zero if the extension is marked as critical (may be null)
1404 * This function will return the alternative names, contained in the
1405 * given certificate. It is the same as
1406 * gnutls_x509_crt_get_subject_alt_name() except for the fact that it
1407 * will return the type of the alternative name in @san_type even if
1408 * the function fails for some reason (i.e. the buffer provided is
1409 * not enough).
1411 * Returns: the alternative subject name type on success, one of the
1412 * enumerated #gnutls_x509_subject_alt_name_t. It will return
1413 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @san_size is not large enough
1414 * to hold the value. In that case @san_size will be updated with
1415 * the required size. If the certificate does not have an
1416 * Alternative name with the specified sequence number then
1417 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1420 gnutls_x509_crt_get_subject_alt_name2 (gnutls_x509_crt_t cert,
1421 unsigned int seq, void *san,
1422 size_t * san_size,
1423 unsigned int *san_type,
1424 unsigned int *critical)
1426 return get_alt_name (cert, "2.5.29.17", seq, san, san_size, san_type,
1427 critical, 0);
1431 * gnutls_x509_crt_get_issuer_alt_name2:
1432 * @cert: should contain a #gnutls_x509_crt_t structure
1433 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1434 * @ian: is the place where the alternative name will be copied to
1435 * @ian_size: holds the size of ret.
1436 * @ian_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
1437 * @critical: will be non-zero if the extension is marked as critical (may be null)
1439 * This function will return the alternative names, contained in the
1440 * given certificate. It is the same as
1441 * gnutls_x509_crt_get_issuer_alt_name() except for the fact that it
1442 * will return the type of the alternative name in @ian_type even if
1443 * the function fails for some reason (i.e. the buffer provided is
1444 * not enough).
1446 * Returns: the alternative issuer name type on success, one of the
1447 * enumerated #gnutls_x509_subject_alt_name_t. It will return
1448 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @ian_size is not large enough
1449 * to hold the value. In that case @ian_size will be updated with
1450 * the required size. If the certificate does not have an
1451 * Alternative name with the specified sequence number then
1452 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1454 * Since: 2.10.0
1458 gnutls_x509_crt_get_issuer_alt_name2 (gnutls_x509_crt_t cert,
1459 unsigned int seq, void *ian,
1460 size_t * ian_size,
1461 unsigned int *ian_type,
1462 unsigned int *critical)
1464 return get_alt_name (cert, "2.5.29.18", seq, ian, ian_size, ian_type,
1465 critical, 0);
1469 * gnutls_x509_crt_get_subject_alt_othername_oid:
1470 * @cert: should contain a #gnutls_x509_crt_t structure
1471 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1472 * @oid: is the place where the otherName OID will be copied to
1473 * @oid_size: holds the size of ret.
1475 * This function will extract the type OID of an otherName Subject
1476 * Alternative Name, contained in the given certificate, and return
1477 * the type as an enumerated element.
1479 * This function is only useful if
1480 * gnutls_x509_crt_get_subject_alt_name() returned
1481 * %GNUTLS_SAN_OTHERNAME.
1483 * If @oid is null then only the size will be filled. The @oid
1484 * returned will be null terminated, although @oid_size will not
1485 * account for the trailing null.
1487 * Returns: the alternative subject name type on success, one of the
1488 * enumerated gnutls_x509_subject_alt_name_t. For supported OIDs, it
1489 * will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
1490 * e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
1491 * unknown OIDs. It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
1492 * @ian_size is not large enough to hold the value. In that case
1493 * @ian_size will be updated with the required size. If the
1494 * certificate does not have an Alternative name with the specified
1495 * sequence number and with the otherName type then
1496 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1499 gnutls_x509_crt_get_subject_alt_othername_oid (gnutls_x509_crt_t cert,
1500 unsigned int seq,
1501 void *oid, size_t * oid_size)
1503 return get_alt_name (cert, "2.5.29.17", seq, oid, oid_size, NULL, NULL, 1);
1507 * gnutls_x509_crt_get_issuer_alt_othername_oid:
1508 * @cert: should contain a #gnutls_x509_crt_t structure
1509 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1510 * @ret: is the place where the otherName OID will be copied to
1511 * @ret_size: holds the size of ret.
1513 * This function will extract the type OID of an otherName Subject
1514 * Alternative Name, contained in the given certificate, and return
1515 * the type as an enumerated element.
1517 * If @oid is null then only the size will be filled. The @oid
1518 * returned will be null terminated, although @oid_size will not
1519 * account for the trailing null.
1521 * This function is only useful if
1522 * gnutls_x509_crt_get_issuer_alt_name() returned
1523 * %GNUTLS_SAN_OTHERNAME.
1525 * Returns: the alternative issuer name type on success, one of the
1526 * enumerated gnutls_x509_subject_alt_name_t. For supported OIDs, it
1527 * will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
1528 * e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
1529 * unknown OIDs. It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
1530 * @ret_size is not large enough to hold the value. In that case
1531 * @ret_size will be updated with the required size. If the
1532 * certificate does not have an Alternative name with the specified
1533 * sequence number and with the otherName type then
1534 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1536 * Since: 2.10.0
1539 gnutls_x509_crt_get_issuer_alt_othername_oid (gnutls_x509_crt_t cert,
1540 unsigned int seq,
1541 void *ret, size_t * ret_size)
1543 return get_alt_name (cert, "2.5.29.18", seq, ret, ret_size, NULL, NULL, 1);
1547 * gnutls_x509_crt_get_basic_constraints:
1548 * @cert: should contain a #gnutls_x509_crt_t structure
1549 * @critical: will be non-zero if the extension is marked as critical
1550 * @ca: pointer to output integer indicating CA status, may be NULL,
1551 * value is 1 if the certificate CA flag is set, 0 otherwise.
1552 * @pathlen: pointer to output integer indicating path length (may be
1553 * NULL), non-negative error codes indicate a present pathLenConstraint
1554 * field and the actual value, -1 indicate that the field is absent.
1556 * This function will read the certificate's basic constraints, and
1557 * return the certificates CA status. It reads the basicConstraints
1558 * X.509 extension (2.5.29.19).
1560 * Returns: If the certificate is a CA a positive value will be
1561 * returned, or (0) if the certificate does not have CA flag set. A
1562 * negative error code may be returned in case of errors. If the
1563 * certificate does not contain the basicConstraints extension
1564 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1567 gnutls_x509_crt_get_basic_constraints (gnutls_x509_crt_t cert,
1568 unsigned int *critical,
1569 unsigned int *ca, int *pathlen)
1571 int result;
1572 gnutls_datum_t basicConstraints;
1573 unsigned int tmp_ca;
1575 if (cert == NULL)
1577 gnutls_assert ();
1578 return GNUTLS_E_INVALID_REQUEST;
1581 if ((result =
1582 _gnutls_x509_crt_get_extension (cert, "2.5.29.19", 0,
1583 &basicConstraints, critical)) < 0)
1585 return result;
1588 if (basicConstraints.size == 0 || basicConstraints.data == NULL)
1590 gnutls_assert ();
1591 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1594 result =
1595 _gnutls_x509_ext_extract_basicConstraints (&tmp_ca,
1596 pathlen,
1597 basicConstraints.data,
1598 basicConstraints.size);
1599 if (ca)
1600 *ca = tmp_ca;
1601 _gnutls_free_datum (&basicConstraints);
1603 if (result < 0)
1605 gnutls_assert ();
1606 return result;
1609 return tmp_ca;
1613 * gnutls_x509_crt_get_ca_status:
1614 * @cert: should contain a #gnutls_x509_crt_t structure
1615 * @critical: will be non-zero if the extension is marked as critical
1617 * This function will return certificates CA status, by reading the
1618 * basicConstraints X.509 extension (2.5.29.19). If the certificate is
1619 * a CA a positive value will be returned, or (0) if the certificate
1620 * does not have CA flag set.
1622 * Use gnutls_x509_crt_get_basic_constraints() if you want to read the
1623 * pathLenConstraint field too.
1625 * Returns: A negative error code may be returned in case of parsing error.
1626 * If the certificate does not contain the basicConstraints extension
1627 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1630 gnutls_x509_crt_get_ca_status (gnutls_x509_crt_t cert, unsigned int *critical)
1632 int pathlen;
1633 unsigned int ca;
1634 return gnutls_x509_crt_get_basic_constraints (cert, critical, &ca,
1635 &pathlen);
1639 * gnutls_x509_crt_get_key_usage:
1640 * @cert: should contain a #gnutls_x509_crt_t structure
1641 * @key_usage: where the key usage bits will be stored
1642 * @critical: will be non-zero if the extension is marked as critical
1644 * This function will return certificate's key usage, by reading the
1645 * keyUsage X.509 extension (2.5.29.15). The key usage value will ORed
1646 * values of the: %GNUTLS_KEY_DIGITAL_SIGNATURE,
1647 * %GNUTLS_KEY_NON_REPUDIATION, %GNUTLS_KEY_KEY_ENCIPHERMENT,
1648 * %GNUTLS_KEY_DATA_ENCIPHERMENT, %GNUTLS_KEY_KEY_AGREEMENT,
1649 * %GNUTLS_KEY_KEY_CERT_SIGN, %GNUTLS_KEY_CRL_SIGN,
1650 * %GNUTLS_KEY_ENCIPHER_ONLY, %GNUTLS_KEY_DECIPHER_ONLY.
1652 * Returns: the certificate key usage, or a negative error code in case of
1653 * parsing error. If the certificate does not contain the keyUsage
1654 * extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
1655 * returned.
1658 gnutls_x509_crt_get_key_usage (gnutls_x509_crt_t cert,
1659 unsigned int *key_usage,
1660 unsigned int *critical)
1662 int result;
1663 gnutls_datum_t keyUsage;
1664 uint16_t _usage;
1666 if (cert == NULL)
1668 gnutls_assert ();
1669 return GNUTLS_E_INVALID_REQUEST;
1672 if ((result =
1673 _gnutls_x509_crt_get_extension (cert, "2.5.29.15", 0, &keyUsage,
1674 critical)) < 0)
1676 return result;
1679 if (keyUsage.size == 0 || keyUsage.data == NULL)
1681 gnutls_assert ();
1682 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1685 result = _gnutls_x509_ext_extract_keyUsage (&_usage, keyUsage.data,
1686 keyUsage.size);
1687 _gnutls_free_datum (&keyUsage);
1689 *key_usage = _usage;
1691 if (result < 0)
1693 gnutls_assert ();
1694 return result;
1697 return 0;
1701 * gnutls_x509_crt_get_proxy:
1702 * @cert: should contain a #gnutls_x509_crt_t structure
1703 * @critical: will be non-zero if the extension is marked as critical
1704 * @pathlen: pointer to output integer indicating path length (may be
1705 * NULL), non-negative error codes indicate a present pCPathLenConstraint
1706 * field and the actual value, -1 indicate that the field is absent.
1707 * @policyLanguage: output variable with OID of policy language
1708 * @policy: output variable with policy data
1709 * @sizeof_policy: output variable size of policy data
1711 * This function will get information from a proxy certificate. It
1712 * reads the ProxyCertInfo X.509 extension (1.3.6.1.5.5.7.1.14).
1714 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1715 * otherwise a negative error code is returned.
1718 gnutls_x509_crt_get_proxy (gnutls_x509_crt_t cert,
1719 unsigned int *critical,
1720 int *pathlen,
1721 char **policyLanguage,
1722 char **policy, size_t * sizeof_policy)
1724 int result;
1725 gnutls_datum_t proxyCertInfo;
1727 if (cert == NULL)
1729 gnutls_assert ();
1730 return GNUTLS_E_INVALID_REQUEST;
1733 if ((result =
1734 _gnutls_x509_crt_get_extension (cert, "1.3.6.1.5.5.7.1.14", 0,
1735 &proxyCertInfo, critical)) < 0)
1737 return result;
1740 if (proxyCertInfo.size == 0 || proxyCertInfo.data == NULL)
1742 gnutls_assert ();
1743 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1746 result = _gnutls_x509_ext_extract_proxyCertInfo (pathlen,
1747 policyLanguage,
1748 policy,
1749 sizeof_policy,
1750 proxyCertInfo.data,
1751 proxyCertInfo.size);
1752 _gnutls_free_datum (&proxyCertInfo);
1753 if (result < 0)
1755 gnutls_assert ();
1756 return result;
1759 return 0;
1763 * gnutls_x509_policy_release:
1764 * @policy: a certificate policy
1766 * This function will deinitialize all memory associated with the provided
1767 * @policy. The policy is allocated using gnutls_x509_crt_get_policy().
1770 void gnutls_x509_policy_release(struct gnutls_x509_policy_st* policy)
1772 unsigned i;
1774 gnutls_free(policy->oid);
1775 for (i=0;i<policy->qualifiers;i++)
1776 gnutls_free(policy->qualifier[i].data);
1779 static int decode_user_notice(const void* data, size_t size, gnutls_datum_t *txt)
1781 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1782 int ret, len;
1783 char choice_type[64];
1784 char name[128];
1785 gnutls_datum_t td, utd;
1787 ret = asn1_create_element
1788 (_gnutls_get_pkix (), "PKIX1.UserNotice", &c2);
1789 if (ret != ASN1_SUCCESS)
1791 gnutls_assert ();
1792 ret = GNUTLS_E_PARSING_ERROR;
1793 goto cleanup;
1796 ret = asn1_der_decoding (&c2, data, size, NULL);
1797 if (ret != ASN1_SUCCESS)
1799 gnutls_assert ();
1800 ret = GNUTLS_E_PARSING_ERROR;
1801 goto cleanup;
1804 len = sizeof(choice_type);
1805 ret = asn1_read_value(c2, "explicitText", choice_type, &len);
1806 if (ret != ASN1_SUCCESS)
1808 gnutls_assert ();
1809 ret = GNUTLS_E_PARSING_ERROR;
1810 goto cleanup;
1813 if (strcmp(choice_type, "utf8String") != 0 && strcmp(choice_type, "IA5String") != 0 &&
1814 strcmp(choice_type, "bmpString") != 0 && strcmp(choice_type, "visibleString") != 0)
1816 gnutls_assert();
1817 ret = GNUTLS_E_PARSING_ERROR;
1818 goto cleanup;
1821 snprintf (name, sizeof (name), "explicitText.%s", choice_type);
1823 ret = _gnutls_x509_read_value(c2, name, &td);
1824 if (ret < 0)
1826 gnutls_assert ();
1827 goto cleanup;
1830 if (strcmp(choice_type, "bmpString") == 0)
1831 { /* convert to UTF-8 */
1832 ret = _gnutls_ucs2_to_utf8(td.data, td.size, &utd);
1833 _gnutls_free_datum(&td);
1834 if (ret < 0)
1836 gnutls_assert();
1837 goto cleanup;
1840 td.data = utd.data;
1841 td.size = utd.size;
1843 else
1845 /* _gnutls_x509_read_value allows that */
1846 td.data[td.size] = 0;
1849 txt->data = (void*)td.data;
1850 txt->size = td.size;
1851 ret = 0;
1853 cleanup:
1854 asn1_delete_structure (&c2);
1855 return ret;
1860 * gnutls_x509_crt_get_policy:
1861 * @cert: should contain a #gnutls_x509_crt_t structure
1862 * @indx: This specifies which policy to return. Use (0) to get the first one.
1863 * @policy: A pointer to a policy structure.
1864 * @critical: will be non-zero if the extension is marked as critical
1866 * This function will extract the certificate policy (extension 2.5.29.32)
1867 * specified by the given index.
1869 * The policy returned by this function must be deinitialized by using
1870 * gnutls_x509_policy_release().
1872 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1873 * if the extension is not present, otherwise a negative error value.
1876 gnutls_x509_crt_get_policy (gnutls_x509_crt_t crt, int indx,
1877 struct gnutls_x509_policy_st* policy,
1878 unsigned int *critical)
1880 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1881 char tmpstr[128];
1882 char tmpoid[MAX_OID_SIZE];
1883 gnutls_datum_t tmpd = {NULL, 0};
1884 int ret, len;
1885 unsigned i;
1887 if (crt == NULL)
1889 gnutls_assert ();
1890 return GNUTLS_E_INVALID_REQUEST;
1893 memset(policy, 0, sizeof(*policy));
1895 if ((ret =
1896 _gnutls_x509_crt_get_extension (crt, "2.5.29.32", 0, &tmpd,
1897 critical)) < 0)
1899 return ret;
1902 if (tmpd.size == 0 || tmpd .data == NULL)
1904 gnutls_assert ();
1905 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1908 ret = asn1_create_element
1909 (_gnutls_get_pkix (), "PKIX1.certificatePolicies", &c2);
1910 if (ret != ASN1_SUCCESS)
1912 gnutls_assert ();
1913 ret = _gnutls_asn2err (ret);
1914 goto cleanup;
1917 ret = asn1_der_decoding (&c2, tmpd.data, tmpd.size, NULL);
1918 if (ret != ASN1_SUCCESS)
1920 gnutls_assert ();
1921 ret = _gnutls_asn2err (ret);
1922 goto cleanup;
1924 _gnutls_free_datum (&tmpd);
1926 indx++;
1927 /* create a string like "?1"
1929 snprintf (tmpstr, sizeof (tmpstr), "?%u.policyIdentifier", indx);
1931 ret = _gnutls_x509_read_value(c2, tmpstr, &tmpd);
1933 if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1934 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1936 if (ret < 0)
1938 gnutls_assert();
1939 goto cleanup;
1941 policy->oid = (void*)tmpd.data;
1942 tmpd.data = NULL;
1944 for (i=0;i<GNUTLS_MAX_QUALIFIERS;i++)
1946 gnutls_datum_t td;
1948 snprintf (tmpstr, sizeof (tmpstr), "?%u.policyQualifiers.?%u.policyQualifierId", indx, i+1);
1950 len = sizeof(tmpoid);
1951 ret = asn1_read_value(c2, tmpstr, tmpoid, &len);
1953 if (ret == ASN1_ELEMENT_NOT_FOUND && i > 0)
1954 break; /* finished */
1956 if (ret != ASN1_SUCCESS)
1958 gnutls_assert();
1959 ret = _gnutls_asn2err (ret);
1960 goto cleanup;
1963 if (strcmp(tmpoid, "1.3.6.1.5.5.7.2.1") == 0)
1965 snprintf (tmpstr, sizeof (tmpstr), "?%u.policyQualifiers.?%u.qualifier", indx, i+1);
1967 ret = _gnutls_x509_read_string(c2, tmpstr, &td, RV_IA5STRING);
1968 if (ret < 0)
1970 gnutls_assert();
1971 goto full_cleanup;
1974 policy->qualifier[i].data = (void*)td.data;
1975 policy->qualifier[i].size = td.size;
1976 td.data = NULL;
1977 policy->qualifier[i].type = GNUTLS_X509_QUALIFIER_URI;
1979 else if (strcmp(tmpoid, "1.3.6.1.5.5.7.2.2") == 0)
1981 gnutls_datum_t txt;
1983 snprintf (tmpstr, sizeof (tmpstr), "?%u.policyQualifiers.?%u.qualifier", indx, i+1);
1985 ret = _gnutls_x509_read_string(c2, tmpstr, &td, RV_RAW);
1986 if (ret < 0)
1988 gnutls_assert();
1989 goto full_cleanup;
1992 ret = decode_user_notice(td.data, td.size, &txt);
1993 gnutls_free(td.data);
1994 td.data = NULL;
1996 if (ret < 0)
1998 gnutls_assert();
1999 goto full_cleanup;
2002 policy->qualifier[i].data = (void*)txt.data;
2003 policy->qualifier[i].size = txt.size;
2004 policy->qualifier[i].type = GNUTLS_X509_QUALIFIER_NOTICE;
2006 else
2007 policy->qualifier[i].type = GNUTLS_X509_QUALIFIER_UNKNOWN;
2009 policy->qualifiers++;
2013 ret = 0;
2014 goto cleanup;
2016 full_cleanup:
2017 gnutls_x509_policy_release(policy);
2019 cleanup:
2020 _gnutls_free_datum (&tmpd);
2021 asn1_delete_structure (&c2);
2022 return ret;
2027 * gnutls_x509_crt_get_extension_by_oid:
2028 * @cert: should contain a #gnutls_x509_crt_t structure
2029 * @oid: holds an Object Identified in null terminated string
2030 * @indx: In case multiple same OIDs exist in the extensions, this specifies which to send. Use (0) to get the first one.
2031 * @buf: a pointer to a structure to hold the name (may be null)
2032 * @buf_size: initially holds the size of @buf
2033 * @critical: will be non-zero if the extension is marked as critical
2035 * This function will return the extension specified by the OID in the
2036 * certificate. The extensions will be returned as binary data DER
2037 * encoded, in the provided buffer.
2039 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2040 * otherwise a negative error code is returned. If the certificate does not
2041 * contain the specified extension
2042 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
2045 gnutls_x509_crt_get_extension_by_oid (gnutls_x509_crt_t cert,
2046 const char *oid, int indx,
2047 void *buf, size_t * buf_size,
2048 unsigned int *critical)
2050 int result;
2051 gnutls_datum_t output;
2053 if (cert == NULL)
2055 gnutls_assert ();
2056 return GNUTLS_E_INVALID_REQUEST;
2059 if ((result =
2060 _gnutls_x509_crt_get_extension (cert, oid, indx, &output,
2061 critical)) < 0)
2063 gnutls_assert ();
2064 return result;
2067 if (output.size == 0 || output.data == NULL)
2069 gnutls_assert ();
2070 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2073 if (output.size > (unsigned int) *buf_size)
2075 *buf_size = output.size;
2076 _gnutls_free_datum (&output);
2077 return GNUTLS_E_SHORT_MEMORY_BUFFER;
2080 *buf_size = output.size;
2082 if (buf)
2083 memcpy (buf, output.data, output.size);
2085 _gnutls_free_datum (&output);
2087 return 0;
2092 * gnutls_x509_crt_get_extension_oid:
2093 * @cert: should contain a #gnutls_x509_crt_t structure
2094 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
2095 * @oid: a pointer to a structure to hold the OID (may be null)
2096 * @oid_size: initially holds the size of @oid
2098 * This function will return the requested extension OID in the certificate.
2099 * The extension OID will be stored as a string in the provided buffer.
2101 * The @oid returned will be null terminated, although @oid_size will not
2102 * account for the trailing null.
2104 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2105 * otherwise a negative error code is returned. If you have reached the
2106 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2107 * will be returned.
2110 gnutls_x509_crt_get_extension_oid (gnutls_x509_crt_t cert, int indx,
2111 void *oid, size_t * oid_size)
2113 int result;
2115 if (cert == NULL)
2117 gnutls_assert ();
2118 return GNUTLS_E_INVALID_REQUEST;
2121 result = _gnutls_x509_crt_get_extension_oid (cert, indx, oid, oid_size);
2122 if (result < 0)
2124 return result;
2127 return 0;
2132 * gnutls_x509_crt_get_extension_info:
2133 * @cert: should contain a #gnutls_x509_crt_t structure
2134 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
2135 * @oid: a pointer to a structure to hold the OID
2136 * @oid_size: initially holds the maximum size of @oid, on return
2137 * holds actual size of @oid.
2138 * @critical: output variable with critical flag, may be NULL.
2140 * This function will return the requested extension OID in the
2141 * certificate, and the critical flag for it. The extension OID will
2142 * be stored as a string in the provided buffer. Use
2143 * gnutls_x509_crt_get_extension_data() to extract the data.
2145 * If the buffer provided is not long enough to hold the output, then
2146 * @oid_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
2147 * returned. The @oid returned will be null terminated, although
2148 * @oid_size will not account for the trailing null.
2150 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2151 * otherwise a negative error code is returned. If you have reached the
2152 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2153 * will be returned.
2156 gnutls_x509_crt_get_extension_info (gnutls_x509_crt_t cert, int indx,
2157 void *oid, size_t * oid_size,
2158 unsigned int *critical)
2160 int result;
2161 char str_critical[10];
2162 char name[ASN1_MAX_NAME_SIZE];
2163 int len;
2165 if (!cert)
2167 gnutls_assert ();
2168 return GNUTLS_E_INVALID_REQUEST;
2171 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u.extnID",
2172 indx + 1);
2174 len = *oid_size;
2175 result = asn1_read_value (cert->cert, name, oid, &len);
2176 *oid_size = len;
2178 if (result == ASN1_ELEMENT_NOT_FOUND)
2179 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2180 else if (result != ASN1_SUCCESS)
2182 gnutls_assert ();
2183 return _gnutls_asn2err (result);
2186 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u.critical",
2187 indx + 1);
2188 len = sizeof (str_critical);
2189 result = asn1_read_value (cert->cert, name, str_critical, &len);
2190 if (result != ASN1_SUCCESS)
2192 gnutls_assert ();
2193 return _gnutls_asn2err (result);
2196 if (critical)
2198 if (str_critical[0] == 'T')
2199 *critical = 1;
2200 else
2201 *critical = 0;
2204 return 0;
2209 * gnutls_x509_crt_get_extension_data:
2210 * @cert: should contain a #gnutls_x509_crt_t structure
2211 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
2212 * @data: a pointer to a structure to hold the data (may be null)
2213 * @sizeof_data: initially holds the size of @oid
2215 * This function will return the requested extension data in the
2216 * certificate. The extension data will be stored as a string in the
2217 * provided buffer.
2219 * Use gnutls_x509_crt_get_extension_info() to extract the OID and
2220 * critical flag. Use gnutls_x509_crt_get_extension_by_oid() instead,
2221 * if you want to get data indexed by the extension OID rather than
2222 * sequence.
2224 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2225 * otherwise a negative error code is returned. If you have reached the
2226 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2227 * will be returned.
2230 gnutls_x509_crt_get_extension_data (gnutls_x509_crt_t cert, int indx,
2231 void *data, size_t * sizeof_data)
2233 int result, len;
2234 char name[ASN1_MAX_NAME_SIZE];
2236 if (!cert)
2238 gnutls_assert ();
2239 return GNUTLS_E_INVALID_REQUEST;
2242 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u.extnValue",
2243 indx + 1);
2245 len = *sizeof_data;
2246 result = asn1_read_value (cert->cert, name, data, &len);
2247 *sizeof_data = len;
2249 if (result == ASN1_ELEMENT_NOT_FOUND)
2250 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2251 else if (result < 0)
2253 gnutls_assert ();
2254 return _gnutls_asn2err (result);
2257 return 0;
2260 static int
2261 _gnutls_x509_crt_get_raw_dn2 (gnutls_x509_crt_t cert,
2262 const char *whom, gnutls_datum_t * start)
2264 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2265 int result, len1;
2266 int start1, end1;
2267 gnutls_datum_t signed_data = { NULL, 0 };
2269 /* get the issuer of 'cert'
2271 if ((result =
2272 asn1_create_element (_gnutls_get_pkix (), "PKIX1.TBSCertificate",
2273 &c2)) != ASN1_SUCCESS)
2275 gnutls_assert ();
2276 return _gnutls_asn2err (result);
2279 result =
2280 _gnutls_x509_get_signed_data (cert->cert, "tbsCertificate", &signed_data);
2281 if (result < 0)
2283 gnutls_assert ();
2284 goto cleanup;
2287 result = asn1_der_decoding (&c2, signed_data.data, signed_data.size, NULL);
2288 if (result != ASN1_SUCCESS)
2290 gnutls_assert ();
2291 asn1_delete_structure (&c2);
2292 result = _gnutls_asn2err (result);
2293 goto cleanup;
2296 result =
2297 asn1_der_decoding_startEnd (c2, signed_data.data, signed_data.size,
2298 whom, &start1, &end1);
2300 if (result != ASN1_SUCCESS)
2302 gnutls_assert ();
2303 result = _gnutls_asn2err (result);
2304 goto cleanup;
2307 len1 = end1 - start1 + 1;
2309 _gnutls_set_datum (start, &signed_data.data[start1], len1);
2311 result = 0;
2313 cleanup:
2314 asn1_delete_structure (&c2);
2315 _gnutls_free_datum (&signed_data);
2316 return result;
2320 * gnutls_x509_crt_get_raw_issuer_dn:
2321 * @cert: should contain a #gnutls_x509_crt_t structure
2322 * @start: will hold the starting point of the DN
2324 * This function will return a pointer to the DER encoded DN structure
2325 * and the length. This points to allocated data that must be free'd using gnutls_free().
2327 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2328 * negative error value.or a negative error code on error.
2332 gnutls_x509_crt_get_raw_issuer_dn (gnutls_x509_crt_t cert,
2333 gnutls_datum_t * start)
2335 return _gnutls_x509_crt_get_raw_dn2 (cert, "issuer", start);
2339 * gnutls_x509_crt_get_raw_dn:
2340 * @cert: should contain a #gnutls_x509_crt_t structure
2341 * @start: will hold the starting point of the DN
2343 * This function will return a pointer to the DER encoded DN structure and
2344 * the length. This points to allocated data that must be free'd using gnutls_free().
2346 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2347 * negative error value. or a negative error code on error.
2351 gnutls_x509_crt_get_raw_dn (gnutls_x509_crt_t cert, gnutls_datum_t * start)
2353 return _gnutls_x509_crt_get_raw_dn2 (cert, "subject", start);
2356 static int
2357 get_dn (gnutls_x509_crt_t cert, const char *whom, gnutls_x509_dn_t * dn)
2359 *dn = asn1_find_node (cert->cert, whom);
2360 if (!*dn)
2361 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2362 return 0;
2366 * gnutls_x509_crt_get_subject:
2367 * @cert: should contain a #gnutls_x509_crt_t structure
2368 * @dn: output variable with pointer to uint8_t DN.
2370 * Return the Certificate's Subject DN as an uint8_t data type. You
2371 * may use gnutls_x509_dn_get_rdn_ava() to decode the DN.
2373 * Note that @dn should be treated as constant. Because points
2374 * into the @cert object, you may not deallocate @cert
2375 * and continue to access @dn.
2377 * Returns: Returns 0 on success, or an error code.
2380 gnutls_x509_crt_get_subject (gnutls_x509_crt_t cert, gnutls_x509_dn_t * dn)
2382 return get_dn (cert, "tbsCertificate.subject.rdnSequence", dn);
2386 * gnutls_x509_crt_get_issuer:
2387 * @cert: should contain a #gnutls_x509_crt_t structure
2388 * @dn: output variable with pointer to uint8_t DN
2390 * Return the Certificate's Issuer DN as an uint8_t data type. You may
2391 * use gnutls_x509_dn_get_rdn_ava() to decode the DN.
2393 * Note that @dn should be treated as constant. Because points
2394 * into the @cert object, you may not deallocate @cert
2395 * and continue to access @dn.
2397 * Returns: Returns 0 on success, or an error code.
2400 gnutls_x509_crt_get_issuer (gnutls_x509_crt_t cert, gnutls_x509_dn_t * dn)
2402 return get_dn (cert, "tbsCertificate.issuer.rdnSequence", dn);
2406 * gnutls_x509_dn_get_rdn_ava:
2407 * @dn: input variable with uint8_t DN pointer
2408 * @irdn: index of RDN
2409 * @iava: index of AVA.
2410 * @ava: Pointer to structure which will hold output information.
2412 * Get pointers to data within the DN.
2414 * Note that @ava will contain pointers into the @dn structure, so you
2415 * should not modify any data or deallocate it. Note also that the DN
2416 * in turn points into the original certificate structure, and thus
2417 * you may not deallocate the certificate and continue to access @dn.
2419 * Returns: Returns 0 on success, or an error code.
2422 gnutls_x509_dn_get_rdn_ava (gnutls_x509_dn_t dn,
2423 int irdn, int iava, gnutls_x509_ava_st * ava)
2425 ASN1_TYPE rdn, elem;
2426 ASN1_DATA_NODE vnode;
2427 long len;
2428 int lenlen, remlen, ret;
2429 char rbuf[ASN1_MAX_NAME_SIZE];
2430 unsigned char cls;
2431 const unsigned char *ptr;
2433 iava++;
2434 irdn++; /* 0->1, 1->2 etc */
2436 snprintf (rbuf, sizeof (rbuf), "rdnSequence.?%d.?%d", irdn, iava);
2437 rdn = asn1_find_node (dn, rbuf);
2438 if (!rdn)
2440 gnutls_assert ();
2441 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2444 snprintf (rbuf, sizeof (rbuf), "?%d.type", iava);
2445 elem = asn1_find_node (rdn, rbuf);
2446 if (!elem)
2448 gnutls_assert ();
2449 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2452 ret = asn1_read_node_value(elem, &vnode);
2453 if (ret != ASN1_SUCCESS)
2455 gnutls_assert ();
2456 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2459 ava->oid.data = (void*)vnode.value;
2460 ava->oid.size = vnode.value_len;
2462 snprintf (rbuf, sizeof (rbuf), "?%d.value", iava);
2463 elem = asn1_find_node (rdn, rbuf);
2464 if (!elem)
2466 gnutls_assert ();
2467 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2470 ret = asn1_read_node_value(elem, &vnode);
2471 if (ret != ASN1_SUCCESS)
2473 gnutls_assert ();
2474 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2476 /* The value still has the previous tag's length bytes, plus the
2477 * current value's tag and length bytes. Decode them.
2480 ptr = vnode.value;
2481 remlen = vnode.value_len;
2482 len = asn1_get_length_der (ptr, remlen, &lenlen);
2483 if (len < 0)
2485 gnutls_assert ();
2486 return GNUTLS_E_ASN1_DER_ERROR;
2489 ptr += lenlen;
2490 remlen -= lenlen;
2491 ret = asn1_get_tag_der (ptr, remlen, &cls, &lenlen, &ava->value_tag);
2492 if (ret)
2494 gnutls_assert ();
2495 return _gnutls_asn2err (ret);
2498 ptr += lenlen;
2499 remlen -= lenlen;
2502 signed long tmp;
2504 tmp = asn1_get_length_der (ptr, remlen, &lenlen);
2505 if (tmp < 0)
2507 gnutls_assert ();
2508 return GNUTLS_E_ASN1_DER_ERROR;
2510 ava->value.size = tmp;
2512 ava->value.data = (void*)(ptr + lenlen);
2514 return 0;
2518 * gnutls_x509_crt_get_fingerprint:
2519 * @cert: should contain a #gnutls_x509_crt_t structure
2520 * @algo: is a digest algorithm
2521 * @buf: a pointer to a structure to hold the fingerprint (may be null)
2522 * @buf_size: initially holds the size of @buf
2524 * This function will calculate and copy the certificate's fingerprint
2525 * in the provided buffer.
2527 * If the buffer is null then only the size will be filled.
2529 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
2530 * not long enough, and in that case the *buf_size will be updated
2531 * with the required size. On success 0 is returned.
2534 gnutls_x509_crt_get_fingerprint (gnutls_x509_crt_t cert,
2535 gnutls_digest_algorithm_t algo,
2536 void *buf, size_t * buf_size)
2538 uint8_t *cert_buf;
2539 int cert_buf_size;
2540 int result;
2541 gnutls_datum_t tmp;
2543 if (buf_size == 0 || cert == NULL)
2545 return GNUTLS_E_INVALID_REQUEST;
2548 cert_buf_size = 0;
2549 asn1_der_coding (cert->cert, "", NULL, &cert_buf_size, NULL);
2551 cert_buf = gnutls_malloc (cert_buf_size);
2552 if (cert_buf == NULL)
2554 gnutls_assert ();
2555 return GNUTLS_E_MEMORY_ERROR;
2558 result = asn1_der_coding (cert->cert, "", cert_buf, &cert_buf_size, NULL);
2560 if (result != ASN1_SUCCESS)
2562 gnutls_assert ();
2563 gnutls_free (cert_buf);
2564 return _gnutls_asn2err (result);
2567 tmp.data = cert_buf;
2568 tmp.size = cert_buf_size;
2570 result = gnutls_fingerprint (algo, &tmp, buf, buf_size);
2571 gnutls_free (cert_buf);
2573 return result;
2577 * gnutls_x509_crt_export:
2578 * @cert: Holds the certificate
2579 * @format: the format of output params. One of PEM or DER.
2580 * @output_data: will contain a certificate PEM or DER encoded
2581 * @output_data_size: holds the size of output_data (and will be
2582 * replaced by the actual size of parameters)
2584 * This function will export the certificate to DER or PEM format.
2586 * If the buffer provided is not long enough to hold the output, then
2587 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2588 * be returned.
2590 * If the structure is PEM encoded, it will have a header
2591 * of "BEGIN CERTIFICATE".
2593 * Returns: In case of failure a negative error code will be
2594 * returned, and 0 on success.
2597 gnutls_x509_crt_export (gnutls_x509_crt_t cert,
2598 gnutls_x509_crt_fmt_t format, void *output_data,
2599 size_t * output_data_size)
2601 if (cert == NULL)
2603 gnutls_assert ();
2604 return GNUTLS_E_INVALID_REQUEST;
2607 return _gnutls_x509_export_int (cert->cert, format, "CERTIFICATE",
2608 output_data, output_data_size);
2612 * gnutls_x509_crt_export2:
2613 * @cert: Holds the certificate
2614 * @format: the format of output params. One of PEM or DER.
2615 * @out: will contain a certificate PEM or DER encoded
2617 * This function will export the certificate to DER or PEM format.
2618 * The output buffer is allocated using gnutls_malloc().
2620 * If the structure is PEM encoded, it will have a header
2621 * of "BEGIN CERTIFICATE".
2623 * Returns: In case of failure a negative error code will be
2624 * returned, and 0 on success.
2626 * Since: 3.1
2629 gnutls_x509_crt_export2 (gnutls_x509_crt_t cert,
2630 gnutls_x509_crt_fmt_t format, gnutls_datum_t * out)
2632 if (cert == NULL)
2634 gnutls_assert ();
2635 return GNUTLS_E_INVALID_REQUEST;
2638 return _gnutls_x509_export_int2 (cert->cert, format, "CERTIFICATE", out);
2642 _gnutls_get_key_id (gnutls_pk_algorithm_t pk, gnutls_pk_params_st * params,
2643 unsigned char *output_data,
2644 size_t * output_data_size)
2646 int ret = 0;
2647 gnutls_datum_t der = { NULL, 0 };
2648 const gnutls_digest_algorithm_t hash = GNUTLS_DIG_SHA1;
2649 unsigned int digest_len = _gnutls_hash_get_algo_len(hash);
2651 if (output_data == NULL || *output_data_size < digest_len)
2653 gnutls_assert ();
2654 *output_data_size = digest_len;
2655 return GNUTLS_E_SHORT_MEMORY_BUFFER;
2658 ret = _gnutls_x509_encode_PKI_params(&der, pk, params);
2659 if (ret < 0)
2660 return gnutls_assert_val(ret);
2662 ret = _gnutls_hash_fast(hash, der.data, der.size, output_data);
2663 if (ret < 0)
2665 gnutls_assert ();
2666 goto cleanup;
2668 *output_data_size = digest_len;
2670 ret = 0;
2672 cleanup:
2674 _gnutls_free_datum (&der);
2675 return ret;
2679 * gnutls_x509_crt_get_key_id:
2680 * @crt: Holds the certificate
2681 * @flags: should be 0 for now
2682 * @output_data: will contain the key ID
2683 * @output_data_size: holds the size of output_data (and will be
2684 * replaced by the actual size of parameters)
2686 * This function will return a unique ID that depends on the public
2687 * key parameters. This ID can be used in checking whether a
2688 * certificate corresponds to the given private key.
2690 * If the buffer provided is not long enough to hold the output, then
2691 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2692 * be returned. The output will normally be a SHA-1 hash output,
2693 * which is 20 bytes.
2695 * Returns: In case of failure a negative error code will be
2696 * returned, and 0 on success.
2699 gnutls_x509_crt_get_key_id (gnutls_x509_crt_t crt, unsigned int flags,
2700 unsigned char *output_data,
2701 size_t * output_data_size)
2703 int pk, ret = 0;
2704 gnutls_pk_params_st params;
2706 if (crt == NULL)
2708 gnutls_assert ();
2709 return GNUTLS_E_INVALID_REQUEST;
2712 pk = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
2713 if (pk < 0)
2715 gnutls_assert ();
2716 return pk;
2719 ret = _gnutls_x509_crt_get_mpis (crt, &params);
2720 if (ret < 0)
2722 gnutls_assert ();
2723 return ret;
2726 ret = _gnutls_get_key_id(pk, &params, output_data, output_data_size);
2728 gnutls_pk_params_release(&params);
2730 return ret;
2734 /* This is exactly as gnutls_x509_crt_check_revocation() except that
2735 * it calls func.
2738 _gnutls_x509_crt_check_revocation (gnutls_x509_crt_t cert,
2739 const gnutls_x509_crl_t * crl_list,
2740 int crl_list_length,
2741 gnutls_verify_output_function func)
2743 uint8_t serial[128];
2744 uint8_t cert_serial[128];
2745 size_t serial_size, cert_serial_size;
2746 int ncerts, ret, i, j;
2747 gnutls_datum_t dn1, dn2;
2749 if (cert == NULL)
2751 gnutls_assert ();
2752 return GNUTLS_E_INVALID_REQUEST;
2755 for (j = 0; j < crl_list_length; j++)
2756 { /* do for all the crls */
2758 /* Step 1. check if issuer's DN match
2760 ret = gnutls_x509_crl_get_raw_issuer_dn (crl_list[j], &dn1);
2761 if (ret < 0)
2763 gnutls_assert ();
2764 return ret;
2767 ret = gnutls_x509_crt_get_raw_issuer_dn (cert, &dn2);
2768 if (ret < 0)
2770 gnutls_assert ();
2771 return ret;
2774 ret = _gnutls_x509_compare_raw_dn (&dn1, &dn2);
2775 _gnutls_free_datum (&dn1);
2776 _gnutls_free_datum (&dn2);
2777 if (ret == 0)
2779 /* issuers do not match so don't even
2780 * bother checking.
2782 continue;
2785 /* Step 2. Read the certificate's serial number
2787 cert_serial_size = sizeof (cert_serial);
2788 ret = gnutls_x509_crt_get_serial (cert, cert_serial, &cert_serial_size);
2789 if (ret < 0)
2791 gnutls_assert ();
2792 return ret;
2795 /* Step 3. cycle through the CRL serials and compare with
2796 * certificate serial we have.
2799 ncerts = gnutls_x509_crl_get_crt_count (crl_list[j]);
2800 if (ncerts < 0)
2802 gnutls_assert ();
2803 return ncerts;
2806 for (i = 0; i < ncerts; i++)
2808 serial_size = sizeof (serial);
2809 ret =
2810 gnutls_x509_crl_get_crt_serial (crl_list[j], i, serial,
2811 &serial_size, NULL);
2813 if (ret < 0)
2815 gnutls_assert ();
2816 return ret;
2819 if (serial_size == cert_serial_size)
2821 if (memcmp (serial, cert_serial, serial_size) == 0)
2823 /* serials match */
2824 if (func) func(cert, NULL, crl_list[j], GNUTLS_CERT_REVOKED|GNUTLS_CERT_INVALID);
2825 return 1; /* revoked! */
2829 if (func) func(cert, NULL, crl_list[j], 0);
2832 return 0; /* not revoked. */
2837 * gnutls_x509_crt_check_revocation:
2838 * @cert: should contain a #gnutls_x509_crt_t structure
2839 * @crl_list: should contain a list of gnutls_x509_crl_t structures
2840 * @crl_list_length: the length of the crl_list
2842 * This function will return check if the given certificate is
2843 * revoked. It is assumed that the CRLs have been verified before.
2845 * Returns: 0 if the certificate is NOT revoked, and 1 if it is. A
2846 * negative error code is returned on error.
2849 gnutls_x509_crt_check_revocation (gnutls_x509_crt_t cert,
2850 const gnutls_x509_crl_t * crl_list,
2851 int crl_list_length)
2853 return _gnutls_x509_crt_check_revocation(cert, crl_list, crl_list_length, NULL);
2857 * gnutls_x509_crt_get_verify_algorithm:
2858 * @crt: Holds the certificate
2859 * @signature: contains the signature
2860 * @hash: The result of the call with the hash algorithm used for signature
2862 * This function will read the certifcate and the signed data to
2863 * determine the hash algorithm used to generate the signature.
2865 * Deprecated: Use gnutls_pubkey_get_verify_algorithm() instead.
2867 * Returns: the 0 if the hash algorithm is found. A negative error code is
2868 * returned on error.
2870 * Since: 2.8.0
2873 gnutls_x509_crt_get_verify_algorithm (gnutls_x509_crt_t crt,
2874 const gnutls_datum_t * signature,
2875 gnutls_digest_algorithm_t * hash)
2877 gnutls_pk_params_st issuer_params;
2878 int ret;
2880 if (crt == NULL)
2882 gnutls_assert ();
2883 return GNUTLS_E_INVALID_REQUEST;
2886 ret = _gnutls_x509_crt_get_mpis (crt, &issuer_params);
2887 if (ret < 0)
2889 gnutls_assert ();
2890 return ret;
2893 ret = _gnutls_x509_verify_algorithm (hash,
2894 signature,
2895 gnutls_x509_crt_get_pk_algorithm (crt,
2896 NULL),
2897 &issuer_params);
2899 /* release allocated mpis */
2900 gnutls_pk_params_release(&issuer_params);
2902 return ret;
2908 * gnutls_x509_crt_get_preferred_hash_algorithm:
2909 * @crt: Holds the certificate
2910 * @hash: The result of the call with the hash algorithm used for signature
2911 * @mand: If non-zero it means that the algorithm MUST use this hash. May be NULL.
2913 * This function will read the certifcate and return the appropriate digest
2914 * algorithm to use for signing with this certificate. Some certificates (i.e.
2915 * DSA might not be able to sign without the preferred algorithm).
2917 * Deprecated: Please use gnutls_pubkey_get_preferred_hash_algorithm().
2919 * Returns: the 0 if the hash algorithm is found. A negative error code is
2920 * returned on error.
2922 * Since: 2.12.0
2925 gnutls_x509_crt_get_preferred_hash_algorithm (gnutls_x509_crt_t crt,
2926 gnutls_digest_algorithm_t *
2927 hash, unsigned int *mand)
2929 gnutls_pk_params_st issuer_params;
2930 int ret;
2932 if (crt == NULL)
2934 gnutls_assert ();
2935 return GNUTLS_E_INVALID_REQUEST;
2938 ret = _gnutls_x509_crt_get_mpis (crt, &issuer_params);
2939 if (ret < 0)
2941 gnutls_assert ();
2942 return ret;
2945 ret =
2946 _gnutls_pk_get_hash_algorithm (gnutls_x509_crt_get_pk_algorithm
2947 (crt, NULL), &issuer_params,
2948 hash, mand);
2950 /* release allocated mpis */
2951 gnutls_pk_params_release(&issuer_params);
2953 return ret;
2957 * gnutls_x509_crt_verify_data:
2958 * @crt: Holds the certificate
2959 * @flags: should be 0 for now
2960 * @data: holds the data to be signed
2961 * @signature: contains the signature
2963 * This function will verify the given signed data, using the
2964 * parameters from the certificate.
2966 * Deprecated. Please use gnutls_pubkey_verify_data().
2968 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
2969 * is returned, and zero or positive code on success.
2972 gnutls_x509_crt_verify_data (gnutls_x509_crt_t crt, unsigned int flags,
2973 const gnutls_datum_t * data,
2974 const gnutls_datum_t * signature)
2976 int result;
2978 if (crt == NULL)
2980 gnutls_assert ();
2981 return GNUTLS_E_INVALID_REQUEST;
2984 result = _gnutls_x509_verify_data (GNUTLS_DIG_UNKNOWN, data, signature, crt);
2985 if (result < 0)
2987 gnutls_assert ();
2988 return result;
2991 return result;
2995 * gnutls_x509_crt_verify_hash:
2996 * @crt: Holds the certificate
2997 * @flags: should be 0 for now
2998 * @hash: holds the hash digest to be verified
2999 * @signature: contains the signature
3001 * This function will verify the given signed digest, using the
3002 * parameters from the certificate.
3004 * Deprecated. Please use gnutls_pubkey_verify_data2() or gnutls_pubkey_verify_hash2().
3006 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
3007 * is returned, and zero or positive code on success.
3010 gnutls_x509_crt_verify_hash (gnutls_x509_crt_t crt, unsigned int flags,
3011 const gnutls_datum_t * hash,
3012 const gnutls_datum_t * signature)
3014 gnutls_pk_params_st params;
3015 gnutls_digest_algorithm_t algo;
3016 int ret;
3018 if (crt == NULL)
3020 gnutls_assert ();
3021 return GNUTLS_E_INVALID_REQUEST;
3024 ret = gnutls_x509_crt_get_verify_algorithm (crt, signature, &algo);
3025 if (ret < 0)
3026 return gnutls_assert_val(ret);
3028 /* Read the MPI parameters from the issuer's certificate.
3030 ret =
3031 _gnutls_x509_crt_get_mpis (crt, &params);
3032 if (ret < 0)
3034 gnutls_assert ();
3035 return ret;
3038 ret =
3039 pubkey_verify_hashed_data (gnutls_x509_crt_get_pk_algorithm (crt, NULL), algo,
3040 hash, signature, &params);
3041 if (ret < 0)
3043 gnutls_assert ();
3046 /* release all allocated MPIs
3048 gnutls_pk_params_release(&params);
3050 return ret;
3054 * gnutls_x509_crt_get_crl_dist_points:
3055 * @cert: should contain a #gnutls_x509_crt_t structure
3056 * @seq: specifies the sequence number of the distribution point (0 for the first one, 1 for the second etc.)
3057 * @ret: is the place where the distribution point will be copied to
3058 * @ret_size: holds the size of ret.
3059 * @reason_flags: Revocation reasons. An ORed sequence of flags from %gnutls_x509_crl_reason_flags_t.
3060 * @critical: will be non-zero if the extension is marked as critical (may be null)
3062 * This function retrieves the CRL distribution points (2.5.29.31),
3063 * contained in the given certificate in the X509v3 Certificate
3064 * Extensions.
3066 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER and updates @ret_size if
3067 * @ret_size is not enough to hold the distribution point, or the
3068 * type of the distribution point if everything was ok. The type is
3069 * one of the enumerated %gnutls_x509_subject_alt_name_t. If the
3070 * certificate does not have an Alternative name with the specified
3071 * sequence number then %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is
3072 * returned.
3075 gnutls_x509_crt_get_crl_dist_points (gnutls_x509_crt_t cert,
3076 unsigned int seq, void *ret,
3077 size_t * ret_size,
3078 unsigned int *reason_flags,
3079 unsigned int *critical)
3081 int result;
3082 gnutls_datum_t dist_points = { NULL, 0 };
3083 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
3084 char name[ASN1_MAX_NAME_SIZE];
3085 int len;
3086 gnutls_x509_subject_alt_name_t type;
3087 uint8_t reasons[2];
3089 if (cert == NULL)
3091 gnutls_assert ();
3092 return GNUTLS_E_INVALID_REQUEST;
3095 if (*ret_size > 0 && ret)
3096 memset (ret, 0, *ret_size);
3097 else
3098 *ret_size = 0;
3100 if (reason_flags)
3101 *reason_flags = 0;
3103 result =
3104 _gnutls_x509_crt_get_extension (cert, "2.5.29.31", 0, &dist_points,
3105 critical);
3106 if (result < 0)
3108 return result;
3111 if (dist_points.size == 0 || dist_points.data == NULL)
3113 gnutls_assert ();
3114 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3117 result = asn1_create_element
3118 (_gnutls_get_pkix (), "PKIX1.CRLDistributionPoints", &c2);
3119 if (result != ASN1_SUCCESS)
3121 gnutls_assert ();
3122 _gnutls_free_datum (&dist_points);
3123 return _gnutls_asn2err (result);
3126 result = asn1_der_decoding (&c2, dist_points.data, dist_points.size, NULL);
3127 _gnutls_free_datum (&dist_points);
3129 if (result != ASN1_SUCCESS)
3131 gnutls_assert ();
3132 asn1_delete_structure (&c2);
3133 return _gnutls_asn2err (result);
3136 /* Return the different names from the first CRLDistr. point.
3137 * The whole thing is a mess.
3139 _gnutls_str_cpy (name, sizeof (name), "?1.distributionPoint.fullName");
3141 result = _gnutls_parse_general_name (c2, name, seq, ret, ret_size, NULL, 0);
3142 if (result < 0)
3144 asn1_delete_structure (&c2);
3145 return result;
3148 type = result;
3151 /* Read the CRL reasons.
3153 if (reason_flags)
3155 _gnutls_str_cpy (name, sizeof (name), "?1.reasons");
3157 reasons[0] = reasons[1] = 0;
3159 len = sizeof (reasons);
3160 result = asn1_read_value (c2, name, reasons, &len);
3162 if (result != ASN1_VALUE_NOT_FOUND && result != ASN1_SUCCESS)
3164 gnutls_assert ();
3165 asn1_delete_structure (&c2);
3166 return _gnutls_asn2err (result);
3169 *reason_flags = reasons[0] | (reasons[1] << 8);
3172 asn1_delete_structure (&c2);
3174 return type;
3178 * gnutls_x509_crt_get_key_purpose_oid:
3179 * @cert: should contain a #gnutls_x509_crt_t structure
3180 * @indx: This specifies which OID to return. Use (0) to get the first one.
3181 * @oid: a pointer to a buffer to hold the OID (may be null)
3182 * @oid_size: initially holds the size of @oid
3183 * @critical: output flag to indicate criticality of extension
3185 * This function will extract the key purpose OIDs of the Certificate
3186 * specified by the given index. These are stored in the Extended Key
3187 * Usage extension (2.5.29.37) See the GNUTLS_KP_* definitions for
3188 * human readable names.
3190 * If @oid is null then only the size will be filled. The @oid
3191 * returned will be null terminated, although @oid_size will not
3192 * account for the trailing null.
3194 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
3195 * not long enough, and in that case the *oid_size will be updated
3196 * with the required size. On success 0 is returned.
3199 gnutls_x509_crt_get_key_purpose_oid (gnutls_x509_crt_t cert,
3200 int indx, void *oid, size_t * oid_size,
3201 unsigned int *critical)
3203 char tmpstr[ASN1_MAX_NAME_SIZE];
3204 int result, len;
3205 gnutls_datum_t id;
3206 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
3208 if (cert == NULL)
3210 gnutls_assert ();
3211 return GNUTLS_E_INVALID_REQUEST;
3214 if (oid)
3215 memset (oid, 0, *oid_size);
3216 else
3217 *oid_size = 0;
3219 if ((result =
3220 _gnutls_x509_crt_get_extension (cert, "2.5.29.37", 0, &id,
3221 critical)) < 0)
3223 return result;
3226 if (id.size == 0 || id.data == NULL)
3228 gnutls_assert ();
3229 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3232 result = asn1_create_element
3233 (_gnutls_get_pkix (), "PKIX1.ExtKeyUsageSyntax", &c2);
3234 if (result != ASN1_SUCCESS)
3236 gnutls_assert ();
3237 _gnutls_free_datum (&id);
3238 return _gnutls_asn2err (result);
3241 result = asn1_der_decoding (&c2, id.data, id.size, NULL);
3242 _gnutls_free_datum (&id);
3244 if (result != ASN1_SUCCESS)
3246 gnutls_assert ();
3247 asn1_delete_structure (&c2);
3248 return _gnutls_asn2err (result);
3251 indx++;
3252 /* create a string like "?1"
3254 snprintf (tmpstr, sizeof (tmpstr), "?%u", indx);
3256 len = *oid_size;
3257 result = asn1_read_value (c2, tmpstr, oid, &len);
3259 *oid_size = len;
3260 asn1_delete_structure (&c2);
3262 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
3264 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3267 if (result != ASN1_SUCCESS)
3269 gnutls_assert ();
3270 return _gnutls_asn2err (result);
3273 return 0;
3278 * gnutls_x509_crt_get_pk_rsa_raw:
3279 * @crt: Holds the certificate
3280 * @m: will hold the modulus
3281 * @e: will hold the public exponent
3283 * This function will export the RSA public key's parameters found in
3284 * the given structure. The new parameters will be allocated using
3285 * gnutls_malloc() and will be stored in the appropriate datum.
3287 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3290 gnutls_x509_crt_get_pk_rsa_raw (gnutls_x509_crt_t crt,
3291 gnutls_datum_t * m, gnutls_datum_t * e)
3293 int ret;
3294 gnutls_pk_params_st params;
3296 if (crt == NULL)
3298 gnutls_assert ();
3299 return GNUTLS_E_INVALID_REQUEST;
3302 ret = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
3303 if (ret != GNUTLS_PK_RSA)
3305 gnutls_assert ();
3306 return GNUTLS_E_INVALID_REQUEST;
3309 ret = _gnutls_x509_crt_get_mpis (crt, &params);
3310 if (ret < 0)
3312 gnutls_assert ();
3313 return ret;
3316 ret = _gnutls_mpi_dprint_lz (params.params[0], m);
3317 if (ret < 0)
3319 gnutls_assert ();
3320 goto cleanup;
3323 ret = _gnutls_mpi_dprint_lz (params.params[1], e);
3324 if (ret < 0)
3326 gnutls_assert ();
3327 _gnutls_free_datum (m);
3328 goto cleanup;
3331 ret = 0;
3333 cleanup:
3334 gnutls_pk_params_release(&params);
3335 return ret;
3339 * gnutls_x509_crt_get_pk_dsa_raw:
3340 * @crt: Holds the certificate
3341 * @p: will hold the p
3342 * @q: will hold the q
3343 * @g: will hold the g
3344 * @y: will hold the y
3346 * This function will export the DSA public key's parameters found in
3347 * the given certificate. The new parameters will be allocated using
3348 * gnutls_malloc() and will be stored in the appropriate datum.
3350 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3353 gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt,
3354 gnutls_datum_t * p, gnutls_datum_t * q,
3355 gnutls_datum_t * g, gnutls_datum_t * y)
3357 int ret;
3358 gnutls_pk_params_st params;
3360 if (crt == NULL)
3362 gnutls_assert ();
3363 return GNUTLS_E_INVALID_REQUEST;
3366 ret = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
3367 if (ret != GNUTLS_PK_DSA)
3369 gnutls_assert ();
3370 return GNUTLS_E_INVALID_REQUEST;
3373 ret = _gnutls_x509_crt_get_mpis (crt, &params);
3374 if (ret < 0)
3376 gnutls_assert ();
3377 return ret;
3381 /* P */
3382 ret = _gnutls_mpi_dprint_lz (params.params[0], p);
3383 if (ret < 0)
3385 gnutls_assert ();
3386 goto cleanup;
3389 /* Q */
3390 ret = _gnutls_mpi_dprint_lz (params.params[1], q);
3391 if (ret < 0)
3393 gnutls_assert ();
3394 _gnutls_free_datum (p);
3395 goto cleanup;
3399 /* G */
3400 ret = _gnutls_mpi_dprint_lz (params.params[2], g);
3401 if (ret < 0)
3403 gnutls_assert ();
3404 _gnutls_free_datum (p);
3405 _gnutls_free_datum (q);
3406 goto cleanup;
3410 /* Y */
3411 ret = _gnutls_mpi_dprint_lz (params.params[3], y);
3412 if (ret < 0)
3414 gnutls_assert ();
3415 _gnutls_free_datum (p);
3416 _gnutls_free_datum (g);
3417 _gnutls_free_datum (q);
3418 goto cleanup;
3421 ret = 0;
3423 cleanup:
3424 gnutls_pk_params_release(&params);
3425 return ret;
3430 * gnutls_x509_crt_list_import2:
3431 * @certs: The structures to store the parsed certificate. Must not be initialized.
3432 * @size: It will contain the size of the list.
3433 * @data: The PEM encoded certificate.
3434 * @format: One of DER or PEM.
3435 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
3437 * This function will convert the given PEM encoded certificate list
3438 * to the native gnutls_x509_crt_t format. The output will be stored
3439 * in @certs which will be initialized.
3441 * If the Certificate is PEM encoded it should have a header of "X509
3442 * CERTIFICATE", or "CERTIFICATE".
3444 * Returns: the number of certificates read or a negative error value.
3446 * Since: 3.0
3449 gnutls_x509_crt_list_import2 (gnutls_x509_crt_t ** certs,
3450 unsigned int * size,
3451 const gnutls_datum_t * data,
3452 gnutls_x509_crt_fmt_t format, unsigned int flags)
3454 unsigned int init = 1024;
3455 int ret;
3457 *certs = gnutls_malloc(sizeof(gnutls_x509_crt_t)*init);
3458 if (*certs == NULL)
3460 gnutls_assert();
3461 return GNUTLS_E_MEMORY_ERROR;
3464 ret = gnutls_x509_crt_list_import(*certs, &init, data, format, GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
3465 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
3467 *certs = gnutls_realloc_fast(*certs, sizeof(gnutls_x509_crt_t)*init);
3468 if (*certs == NULL)
3470 gnutls_assert();
3471 return GNUTLS_E_MEMORY_ERROR;
3474 ret = gnutls_x509_crt_list_import(*certs, &init, data, format, flags);
3477 if (ret < 0)
3479 gnutls_free(*certs);
3480 *certs = NULL;
3481 return ret;
3484 *size = init;
3485 return 0;
3488 static int check_if_sorted(gnutls_x509_crt_t * crt, int nr)
3490 char prev_dn[MAX_DN];
3491 char dn[MAX_DN];
3492 size_t prev_dn_size, dn_size;
3493 int i, ret;
3495 /* check if the X.509 list is ordered */
3496 if (nr > 1)
3499 for (i=0;i<nr;i++)
3501 if (i>0)
3503 dn_size = sizeof(dn);
3504 ret = gnutls_x509_crt_get_dn(crt[i], dn, &dn_size);
3505 if (ret < 0)
3507 ret = gnutls_assert_val(ret);
3508 goto cleanup;
3511 if (dn_size != prev_dn_size || memcmp(dn, prev_dn, dn_size) != 0)
3513 ret = gnutls_assert_val(GNUTLS_E_CERTIFICATE_LIST_UNSORTED);
3514 goto cleanup;
3518 prev_dn_size = sizeof(prev_dn);
3519 ret = gnutls_x509_crt_get_issuer_dn(crt[i], prev_dn, &prev_dn_size);
3520 if (ret < 0)
3522 ret = gnutls_assert_val(ret);
3523 goto cleanup;
3528 ret = 0;
3530 cleanup:
3531 return ret;
3536 * gnutls_x509_crt_list_import:
3537 * @certs: The structures to store the parsed certificate. Must not be initialized.
3538 * @cert_max: Initially must hold the maximum number of certs. It will be updated with the number of certs available.
3539 * @data: The PEM encoded certificate.
3540 * @format: One of DER or PEM.
3541 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
3543 * This function will convert the given PEM encoded certificate list
3544 * to the native gnutls_x509_crt_t format. The output will be stored
3545 * in @certs. They will be automatically initialized.
3547 * The flag %GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED will cause
3548 * import to fail if the certificates in the provided buffer are more
3549 * than the available structures. The %GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED
3550 * flag will cause the function to fail if the provided list is not
3551 * sorted from subject to issuer.
3553 * If the Certificate is PEM encoded it should have a header of "X509
3554 * CERTIFICATE", or "CERTIFICATE".
3556 * Returns: the number of certificates read or a negative error value.
3559 gnutls_x509_crt_list_import (gnutls_x509_crt_t * certs,
3560 unsigned int *cert_max,
3561 const gnutls_datum_t * data,
3562 gnutls_x509_crt_fmt_t format, unsigned int flags)
3564 int size;
3565 const char *ptr;
3566 gnutls_datum_t tmp;
3567 int ret, nocopy = 0;
3568 unsigned int count = 0, j;
3570 if (format == GNUTLS_X509_FMT_DER)
3572 if (*cert_max < 1)
3574 *cert_max = 1;
3575 return GNUTLS_E_SHORT_MEMORY_BUFFER;
3578 count = 1; /* import only the first one */
3580 ret = gnutls_x509_crt_init (&certs[0]);
3581 if (ret < 0)
3583 gnutls_assert ();
3584 goto error;
3587 ret = gnutls_x509_crt_import (certs[0], data, format);
3588 if (ret < 0)
3590 gnutls_assert ();
3591 goto error;
3594 *cert_max = 1;
3595 return 1;
3598 /* move to the certificate
3600 ptr = memmem (data->data, data->size,
3601 PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
3602 if (ptr == NULL)
3603 ptr = memmem (data->data, data->size,
3604 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
3606 if (ptr == NULL)
3607 return gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_FOUND);
3609 count = 0;
3613 if (count >= *cert_max)
3615 if (!(flags & GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED))
3616 break;
3617 else
3618 nocopy = 1;
3621 if (!nocopy)
3623 ret = gnutls_x509_crt_init (&certs[count]);
3624 if (ret < 0)
3626 gnutls_assert ();
3627 goto error;
3630 tmp.data = (void *) ptr;
3631 tmp.size = data->size - (ptr - (char *) data->data);
3633 ret =
3634 gnutls_x509_crt_import (certs[count], &tmp, GNUTLS_X509_FMT_PEM);
3635 if (ret < 0)
3637 gnutls_assert ();
3638 goto error;
3642 /* now we move ptr after the pem header
3644 ptr++;
3645 /* find the next certificate (if any)
3647 size = data->size - (ptr - (char *) data->data);
3649 if (size > 0)
3651 char *ptr2;
3653 ptr2 = memmem (ptr, size, PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
3654 if (ptr2 == NULL)
3655 ptr2 = memmem (ptr, size, PEM_CERT_SEP2,
3656 sizeof (PEM_CERT_SEP2) - 1);
3658 ptr = ptr2;
3660 else
3661 ptr = NULL;
3663 count++;
3665 while (ptr != NULL);
3667 *cert_max = count;
3669 if (flags & GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED)
3671 ret = check_if_sorted(certs, *cert_max);
3672 if (ret < 0)
3674 gnutls_assert();
3675 goto error;
3679 if (nocopy == 0)
3680 return count;
3681 else
3682 return GNUTLS_E_SHORT_MEMORY_BUFFER;
3684 error:
3685 for (j = 0; j < count; j++)
3686 gnutls_x509_crt_deinit (certs[j]);
3687 return ret;
3691 * gnutls_x509_crt_get_subject_unique_id:
3692 * @crt: Holds the certificate
3693 * @buf: user allocated memory buffer, will hold the unique id
3694 * @buf_size: size of user allocated memory buffer (on input), will hold
3695 * actual size of the unique ID on return.
3697 * This function will extract the subjectUniqueID value (if present) for
3698 * the given certificate.
3700 * If the user allocated memory buffer is not large enough to hold the
3701 * full subjectUniqueID, then a GNUTLS_E_SHORT_MEMORY_BUFFER error will be
3702 * returned, and buf_size will be set to the actual length.
3704 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3707 gnutls_x509_crt_get_subject_unique_id (gnutls_x509_crt_t crt, char *buf,
3708 size_t * buf_size)
3710 int result;
3711 gnutls_datum_t datum = { NULL, 0 };
3713 result =
3714 _gnutls_x509_read_string (crt->cert, "tbsCertificate.subjectUniqueID",
3715 &datum, RV_BIT_STRING);
3717 if (datum.size > *buf_size)
3718 { /* then we're not going to fit */
3719 *buf_size = datum.size;
3720 buf[0] = '\0';
3721 result = GNUTLS_E_SHORT_MEMORY_BUFFER;
3723 else
3725 *buf_size = datum.size;
3726 memcpy (buf, datum.data, datum.size);
3729 _gnutls_free_datum (&datum);
3731 return result;
3735 * gnutls_x509_crt_get_issuer_unique_id:
3736 * @crt: Holds the certificate
3737 * @buf: user allocated memory buffer, will hold the unique id
3738 * @buf_size: size of user allocated memory buffer (on input), will hold
3739 * actual size of the unique ID on return.
3741 * This function will extract the issuerUniqueID value (if present) for
3742 * the given certificate.
3744 * If the user allocated memory buffer is not large enough to hold the
3745 * full subjectUniqueID, then a GNUTLS_E_SHORT_MEMORY_BUFFER error will be
3746 * returned, and buf_size will be set to the actual length.
3748 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3750 * Since: 2.12.0
3753 gnutls_x509_crt_get_issuer_unique_id (gnutls_x509_crt_t crt, char *buf,
3754 size_t * buf_size)
3756 int result;
3757 gnutls_datum_t datum = { NULL, 0 };
3759 result =
3760 _gnutls_x509_read_string (crt->cert, "tbsCertificate.issuerUniqueID",
3761 &datum, RV_BIT_STRING);
3763 if (datum.size > *buf_size)
3764 { /* then we're not going to fit */
3765 *buf_size = datum.size;
3766 buf[0] = '\0';
3767 result = GNUTLS_E_SHORT_MEMORY_BUFFER;
3769 else
3771 *buf_size = datum.size;
3772 memcpy (buf, datum.data, datum.size);
3775 _gnutls_free_datum (&datum);
3777 return result;
3780 static int
3781 _gnutls_parse_aia (ASN1_TYPE src,
3782 unsigned int seq,
3783 int what,
3784 gnutls_datum_t * data)
3786 int len;
3787 char nptr[ASN1_MAX_NAME_SIZE];
3788 int result;
3789 gnutls_datum_t d;
3790 const char *oid = NULL;
3792 seq++; /* 0->1, 1->2 etc */
3793 switch (what)
3795 case GNUTLS_IA_ACCESSMETHOD_OID:
3796 snprintf (nptr, sizeof (nptr), "?%u.accessMethod", seq);
3797 break;
3799 case GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE:
3800 snprintf (nptr, sizeof (nptr), "?%u.accessLocation", seq);
3801 break;
3803 case GNUTLS_IA_CAISSUERS_URI:
3804 oid = GNUTLS_OID_AD_CAISSUERS;
3805 /* fall through */
3807 case GNUTLS_IA_OCSP_URI:
3808 if (oid == NULL)
3809 oid = GNUTLS_OID_AD_OCSP;
3811 char tmpoid[20];
3812 snprintf (nptr, sizeof (nptr), "?%u.accessMethod", seq);
3813 len = sizeof (tmpoid);
3814 result = asn1_read_value (src, nptr, tmpoid, &len);
3816 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
3817 return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
3819 if (result != ASN1_SUCCESS)
3821 gnutls_assert ();
3822 return _gnutls_asn2err (result);
3824 if ((unsigned)len != strlen (oid) + 1 || memcmp (tmpoid, oid, len) != 0)
3825 return gnutls_assert_val(GNUTLS_E_UNKNOWN_ALGORITHM);
3827 /* fall through */
3829 case GNUTLS_IA_URI:
3830 snprintf (nptr, sizeof (nptr),
3831 "?%u.accessLocation.uniformResourceIdentifier", seq);
3832 break;
3834 default:
3835 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
3838 len = 0;
3839 result = asn1_read_value (src, nptr, NULL, &len);
3840 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
3841 return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
3843 if (result != ASN1_MEM_ERROR)
3845 gnutls_assert ();
3846 return _gnutls_asn2err (result);
3849 d.size = len;
3851 d.data = gnutls_malloc (d.size);
3852 if (d.data == NULL)
3853 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
3855 result = asn1_read_value (src, nptr, d.data, &len);
3856 if (result != ASN1_SUCCESS)
3858 gnutls_assert ();
3859 gnutls_free (d.data);
3860 return _gnutls_asn2err (result);
3863 if (data)
3865 data->data = d.data;
3866 data->size = d.size;
3868 else
3869 gnutls_free (d.data);
3871 return 0;
3875 * gnutls_x509_crt_get_authority_info_access:
3876 * @crt: Holds the certificate
3877 * @seq: specifies the sequence number of the access descriptor (0 for the first one, 1 for the second etc.)
3878 * @what: what data to get, a #gnutls_info_access_what_t type.
3879 * @data: output data to be freed with gnutls_free().
3880 * @critical: pointer to output integer that is set to non-0 if the extension is marked as critical (may be %NULL)
3882 * This function extracts the Authority Information Access (AIA)
3883 * extension, see RFC 5280 section 4.2.2.1 for more information. The
3884 * AIA extension holds a sequence of AccessDescription (AD) data:
3886 * <informalexample><programlisting>
3887 * AuthorityInfoAccessSyntax ::=
3888 * SEQUENCE SIZE (1..MAX) OF AccessDescription
3890 * AccessDescription ::= SEQUENCE {
3891 * accessMethod OBJECT IDENTIFIER,
3892 * accessLocation GeneralName }
3893 * </programlisting></informalexample>
3895 * The @seq input parameter is used to indicate which member of the
3896 * sequence the caller is interested in. The first member is 0, the
3897 * second member 1 and so on. When the @seq value is out of bounds,
3898 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
3900 * The type of data returned in @data is specified via @what which
3901 * should be #gnutls_info_access_what_t values.
3903 * If @what is %GNUTLS_IA_ACCESSMETHOD_OID then @data will hold the
3904 * accessMethod OID (e.g., "1.3.6.1.5.5.7.48.1").
3906 * If @what is %GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE, @data will
3907 * hold the accessLocation GeneralName type (e.g.,
3908 * "uniformResourceIdentifier").
3910 * If @what is %GNUTLS_IA_URI, @data will hold the accessLocation URI
3911 * data. Requesting this @what value leads to an error if the
3912 * accessLocation is not of the "uniformResourceIdentifier" type.
3914 * If @what is %GNUTLS_IA_OCSP_URI, @data will hold the OCSP URI.
3915 * Requesting this @what value leads to an error if the accessMethod
3916 * is not 1.3.6.1.5.5.7.48.1 aka OSCP, or if accessLocation is not of
3917 * the "uniformResourceIdentifier" type.
3919 * If @what is %GNUTLS_IA_CAISSUERS_URI, @data will hold the caIssuers
3920 * URI. Requesting this @what value leads to an error if the
3921 * accessMethod is not 1.3.6.1.5.5.7.48.2 aka caIssuers, or if
3922 * accessLocation is not of the "uniformResourceIdentifier" type.
3924 * More @what values may be allocated in the future as needed.
3926 * If @data is NULL, the function does the same without storing the
3927 * output data, that is, it will set @critical and do error checking
3928 * as usual.
3930 * The value of the critical flag is returned in *@critical. Supply a
3931 * NULL @critical if you want the function to make sure the extension
3932 * is non-critical, as required by RFC 5280.
3934 * Returns: %GNUTLS_E_SUCCESS on success, %GNUTLS_E_INVALID_REQUEST on
3935 * invalid @crt, %GNUTLS_E_CONSTRAINT_ERROR if the extension is
3936 * incorrectly marked as critical (use a non-NULL @critical to
3937 * override), %GNUTLS_E_UNKNOWN_ALGORITHM if the requested OID does
3938 * not match (e.g., when using %GNUTLS_IA_OCSP_URI), otherwise a
3939 * negative error code.
3941 * Since: 3.0
3944 gnutls_x509_crt_get_authority_info_access (gnutls_x509_crt_t crt,
3945 unsigned int seq,
3946 int what,
3947 gnutls_datum_t * data,
3948 unsigned int *critical)
3950 int ret;
3951 gnutls_datum_t aia;
3952 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
3954 if (crt == NULL)
3956 gnutls_assert ();
3957 return GNUTLS_E_INVALID_REQUEST;
3960 if ((ret = _gnutls_x509_crt_get_extension (crt, GNUTLS_OID_AIA, 0, &aia,
3961 critical)) < 0)
3962 return ret;
3964 if (aia.size == 0 || aia.data == NULL)
3966 gnutls_assert ();
3967 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3970 if (critical && *critical)
3971 return GNUTLS_E_CONSTRAINT_ERROR;
3973 ret = asn1_create_element (_gnutls_get_pkix (),
3974 "PKIX1.AuthorityInfoAccessSyntax", &c2);
3975 if (ret != ASN1_SUCCESS)
3977 gnutls_assert ();
3978 _gnutls_free_datum (&aia);
3979 return _gnutls_asn2err (ret);
3982 ret = asn1_der_decoding (&c2, aia.data, aia.size, NULL);
3983 /* asn1_print_structure (stdout, c2, "", ASN1_PRINT_ALL); */
3984 _gnutls_free_datum (&aia);
3985 if (ret != ASN1_SUCCESS)
3987 gnutls_assert ();
3988 asn1_delete_structure (&c2);
3989 return _gnutls_asn2err (ret);
3992 ret = _gnutls_parse_aia (c2, seq, what, data);
3994 asn1_delete_structure (&c2);
3995 if (ret < 0)
3996 gnutls_assert ();
3998 return ret;
4002 * gnutls_x509_crt_set_pin_function:
4003 * @crt: The certificate structure
4004 * @fn: the callback
4005 * @userdata: data associated with the callback
4007 * This function will set a callback function to be used when
4008 * it is required to access a protected object. This function overrides
4009 * the global function set using gnutls_pkcs11_set_pin_function().
4011 * Note that this callback is currently used only during the import
4012 * of a PKCS #11 certificate with gnutls_x509_crt_import_pkcs11_url().
4014 * Since: 3.1.0
4017 void gnutls_x509_crt_set_pin_function (gnutls_x509_crt_t crt,
4018 gnutls_pin_callback_t fn, void *userdata)
4020 crt->pin.cb = fn;
4021 crt->pin.data = userdata;