handle visiblestring.
[gnutls.git] / lib / x509 / x509.c
blob75c612abb60ab85a7a64f85c9062f0766c63900c
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 (0) returns the raw DER data of the DN part.
282 * @buf: a pointer to a structure to hold the name (may be null)
283 * @buf_size: initially holds the size of @buf
285 * This function will extract the part of the name of the Certificate
286 * issuer specified by the given OID. The output, if the raw flag is not
287 * used, will be encoded as described in RFC4514. Thus a string that is
288 * ASCII or UTF-8 encoded, depending on the certificate data.
290 * Some helper macros with popular OIDs can be found in gnutls/x509.h
291 * If raw flag is (0), this function will only return known OIDs as
292 * text. Other OIDs will be DER encoded, as described in RFC4514 --
293 * in hex format with a '#' prefix. You can check about known OIDs
294 * using gnutls_x509_dn_oid_known().
296 * If @buf is null then only the size will be filled. If the @raw_flag
297 * is not specified the output is always null terminated, although the
298 * @buf_size will not include the null character.
300 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
301 * long enough, and in that case the @buf_size will be updated with
302 * the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there
303 * are no data in the current index. On success 0 is returned.
306 gnutls_x509_crt_get_issuer_dn_by_oid (gnutls_x509_crt_t cert,
307 const char *oid, int indx,
308 unsigned int raw_flag, void *buf,
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 (0) returns the raw DER data of the DN part.
394 * @buf: a pointer where the DN part will be copied (may be null).
395 * @buf_size: initially holds the size of @buf
397 * This function will extract the part of the name of the Certificate
398 * subject specified by the given OID. The output, if the raw flag is
399 * not used, will be encoded as described in RFC4514. Thus a string
400 * that is ASCII or UTF-8 encoded, depending on the certificate data.
402 * Some helper macros with popular OIDs can be found in gnutls/x509.h
403 * If raw flag is (0), this function will only return known OIDs as
404 * text. Other OIDs will be DER encoded, as described in RFC4514 --
405 * in hex format with a '#' prefix. You can check about known OIDs
406 * using gnutls_x509_dn_oid_known().
408 * If @buf is null then only the size will be filled. If the @raw_flag
409 * is not specified the output is always null terminated, although the
410 * @buf_size will not include the null character.
412 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
413 * long enough, and in that case the @buf_size will be updated with
414 * the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there
415 * are no data in the current index. On success 0 is returned.
418 gnutls_x509_crt_get_dn_by_oid (gnutls_x509_crt_t cert, const char *oid,
419 int indx, unsigned int raw_flag,
420 void *buf, size_t * buf_size)
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 (0) if the extension is marked as critical (may be null)
740 * This function will return the X.509v3 certificate's subject key
741 * identifier. This is obtained by the X.509 Subject Key identifier
742 * extension field (2.5.29.14).
744 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
745 * if the extension is not present, otherwise a negative error value.
748 gnutls_x509_crt_get_subject_key_id (gnutls_x509_crt_t cert, void *ret,
749 size_t * ret_size, unsigned int *critical)
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 (0) if the extension is marked as critical (may be null)
881 * This function will return the X.509 authority key
882 * identifier when stored as a general name (authorityCertIssuer)
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 (0) if the extension is marked as critical (may be null)
946 * This function will return the X.509v3 certificate authority's key
947 * identifier. This is obtained by the X.509 Authority Key
948 * identifier extension field (2.5.29.35). Note that this function
949 * only returns the keyIdentifier field of the extension and
950 * %GNUTLS_E_X509_UNSUPPORTED_EXTENSION, if the extension contains
951 * the name and serial number of the certificate. In that case
952 * gnutls_x509_crt_get_authority_key_gn_serial() may be used.
954 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
955 * if the extension is not present, otherwise a negative error value.
958 gnutls_x509_crt_get_authority_key_id (gnutls_x509_crt_t cert, void *id,
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 (0) if the extension is marked as critical (may be null)
1320 * This function retrieves the Alternative Name (2.5.29.17), contained
1321 * in the given certificate in the X509v3 Certificate Extensions.
1323 * When the SAN type is otherName, it will extract the data in the
1324 * otherName's value field, and %GNUTLS_SAN_OTHERNAME is returned.
1325 * You may use gnutls_x509_crt_get_subject_alt_othername_oid() to get
1326 * the corresponding OID and the "virtual" SAN types (e.g.,
1327 * %GNUTLS_SAN_OTHERNAME_XMPP).
1329 * If an otherName OID is known, the data will be decoded. Otherwise
1330 * the returned data will be DER encoded, and you will have to decode
1331 * it yourself. Currently, only the RFC 3920 id-on-xmppAddr SAN is
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 (0) if the extension is marked as critical (may be null)
1360 * This function retrieves the Issuer Alternative Name (2.5.29.18),
1361 * contained in the given certificate in the X509v3 Certificate
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 (0) if the extension is marked as critical (may be null)
1404 * This function will return the alternative names, contained in the
1405 * given certificate. It is the same as
1406 * gnutls_x509_crt_get_subject_alt_name() except for the fact that it
1407 * will return the type of the alternative name in @san_type even if
1408 * the function fails for some reason (i.e. the buffer provided is
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 (0) if the extension is marked as critical (may be null)
1439 * This function will return the alternative names, contained in the
1440 * given certificate. It is the same as
1441 * gnutls_x509_crt_get_issuer_alt_name() except for the fact that it
1442 * will return the type of the alternative name in @ian_type even if
1443 * the function fails for some reason (i.e. the buffer provided is
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 (0) if the extension is marked as critical
1550 * @ca: pointer to output integer indicating CA status, may be NULL,
1551 * value is 1 if the certificate CA flag is set, 0 otherwise.
1552 * @pathlen: pointer to output integer indicating path length (may be
1553 * NULL), non-negative error codes indicate a present pathLenConstraint
1554 * field and the actual value, -1 indicate that the field is absent.
1556 * This function will read the certificate's basic constraints, and
1557 * return the certificates CA status. It reads the basicConstraints
1558 * X.509 extension (2.5.29.19).
1560 * Returns: If the certificate is a CA a positive value will be
1561 * returned, or (0) if the certificate does not have CA flag set. A
1562 * negative error code may be returned in case of errors. If the
1563 * certificate does not contain the basicConstraints extension
1564 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1567 gnutls_x509_crt_get_basic_constraints (gnutls_x509_crt_t cert,
1568 unsigned int *critical,
1569 unsigned int *ca, int *pathlen)
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 (0) if the extension is marked as critical
1617 * This function will return certificates CA status, by reading the
1618 * basicConstraints X.509 extension (2.5.29.19). If the certificate is
1619 * a CA a positive value will be returned, or (0) if the certificate
1620 * does not have CA flag set.
1622 * Use gnutls_x509_crt_get_basic_constraints() if you want to read the
1623 * pathLenConstraint field too.
1625 * Returns: A negative error code may be returned in case of parsing error.
1626 * If the certificate does not contain the basicConstraints extension
1627 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1630 gnutls_x509_crt_get_ca_status (gnutls_x509_crt_t cert, unsigned int *critical)
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 (0) if the extension is marked as critical
1644 * This function will return certificate's key usage, by reading the
1645 * keyUsage X.509 extension (2.5.29.15). The key usage value will ORed
1646 * values of the: %GNUTLS_KEY_DIGITAL_SIGNATURE,
1647 * %GNUTLS_KEY_NON_REPUDIATION, %GNUTLS_KEY_KEY_ENCIPHERMENT,
1648 * %GNUTLS_KEY_DATA_ENCIPHERMENT, %GNUTLS_KEY_KEY_AGREEMENT,
1649 * %GNUTLS_KEY_KEY_CERT_SIGN, %GNUTLS_KEY_CRL_SIGN,
1650 * %GNUTLS_KEY_ENCIPHER_ONLY, %GNUTLS_KEY_DECIPHER_ONLY.
1652 * Returns: the certificate key usage, or a negative error code in case of
1653 * parsing error. If the certificate does not contain the keyUsage
1654 * extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
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 (0) if the extension is marked as critical
1704 * @pathlen: pointer to output integer indicating path length (may be
1705 * NULL), non-negative error codes indicate a present pCPathLenConstraint
1706 * field and the actual value, -1 indicate that the field is absent.
1707 * @policyLanguage: output variable with OID of policy language
1708 * @policy: output variable with policy data
1709 * @sizeof_policy: output variable size of policy data
1711 * This function will get information from a proxy certificate. It
1712 * reads the ProxyCertInfo X.509 extension (1.3.6.1.5.5.7.1.14).
1714 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1715 * otherwise a negative error code is returned.
1718 gnutls_x509_crt_get_proxy (gnutls_x509_crt_t cert,
1719 unsigned int *critical,
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_certificate_policy_release:
1764 * @policy: a certificate policy
1766 * This function will deinitialize all memory associated with the provided
1767 * @policy. The policy is allocated using gnutls_x509_crt_get_policy().
1770 void gnutls_certificate_policy_release(struct gnutls_certificate_policy_st* policy)
1772 unsigned i;
1774 gnutls_free(policy->policy_oid);
1775 for (i=0;i<policy->qualifiers;i++)
1776 gnutls_free(policy->qualifier_data[i]);
1779 static int decode_user_notice(const void* data, size_t size, char** txt)
1781 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1782 int ret, len;
1783 char choice_type[64];
1784 char name[128];
1785 gnutls_datum_t td, td2;
1787 ret = asn1_create_element
1788 (_gnutls_get_pkix (), "PKIX1.UserNotice", &c2);
1789 if (ret != ASN1_SUCCESS)
1791 gnutls_assert ();
1792 ret = _gnutls_asn2err (ret);
1793 goto cleanup;
1796 ret = asn1_der_decoding (&c2, data, size, NULL);
1797 if (ret != ASN1_SUCCESS)
1799 gnutls_assert ();
1800 ret = _gnutls_asn2err (ret);
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_asn2err (ret);
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 != ASN1_SUCCESS)
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, &td2);
1833 _gnutls_free_datum(&td);
1834 if (ret < 0)
1836 gnutls_assert();
1837 goto cleanup;
1840 td.data = td2.data;
1841 td.size = td2.size;
1843 else
1845 /* _gnutls_x509_read_value allows that */
1846 td.data[td.size] = 0;
1849 *txt = (void*)td.data;
1850 ret = 0;
1852 cleanup:
1853 asn1_delete_structure (&c2);
1854 return ret;
1859 * gnutls_x509_crt_get_policy:
1860 * @cert: should contain a #gnutls_x509_crt_t structure
1861 * @indx: This specifies which policy to return. Use (0) to get the first one.
1862 * @policy: A pointer to a policy structure.
1863 * @critical: will be non (0) if the extension is marked as critical
1865 * This function will extract the certificate policy specified by the
1866 * given index.
1868 * The policy returned by this function must be deinitialized by using
1869 * gnutls_certificate_policy_release().
1871 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1872 * if the extension is not present, otherwise a negative error value.
1875 gnutls_x509_crt_get_policy (gnutls_x509_crt_t crt, int indx, struct gnutls_certificate_policy_st* policy, unsigned int *critical)
1877 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1878 char tmpstr[128];
1879 char tmpoid[MAX_OID_SIZE];
1880 gnutls_datum_t tmpd = {NULL, 0};
1881 int ret, len;
1882 unsigned i;
1884 if (crt == NULL)
1886 gnutls_assert ();
1887 return GNUTLS_E_INVALID_REQUEST;
1890 memset(policy, 0, sizeof(*policy));
1892 if ((ret =
1893 _gnutls_x509_crt_get_extension (crt, "2.5.29.32", 0, &tmpd,
1894 critical)) < 0)
1896 return ret;
1899 if (tmpd.size == 0 || tmpd .data == NULL)
1901 gnutls_assert ();
1902 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1905 ret = asn1_create_element
1906 (_gnutls_get_pkix (), "PKIX1.certificatePolicies", &c2);
1907 if (ret != ASN1_SUCCESS)
1909 gnutls_assert ();
1910 ret = _gnutls_asn2err (ret);
1911 goto cleanup;
1914 ret = asn1_der_decoding (&c2, tmpd.data, tmpd.size, NULL);
1915 if (ret != ASN1_SUCCESS)
1917 gnutls_assert ();
1918 ret = _gnutls_asn2err (ret);
1919 goto cleanup;
1921 _gnutls_free_datum (&tmpd);
1923 indx++;
1924 /* create a string like "?1"
1926 snprintf (tmpstr, sizeof (tmpstr), "?%u.policyIdentifier", indx);
1928 ret = _gnutls_x509_read_value(c2, tmpstr, &tmpd);
1930 if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1931 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1933 if (ret < 0)
1935 gnutls_assert();
1936 goto cleanup;
1938 policy->policy_oid = (void*)tmpd.data;
1939 tmpd.data = NULL;
1941 for (i=0;i<GNUTLS_MAX_QUALIFIERS;i++)
1943 gnutls_datum_t td;
1945 snprintf (tmpstr, sizeof (tmpstr), "?%u.policyQualifiers.?%u.policyQualifierId", indx, i+1);
1947 len = sizeof(tmpoid);
1948 ret = asn1_read_value(c2, tmpstr, tmpoid, &len);
1950 if (ret == ASN1_ELEMENT_NOT_FOUND && i > 0)
1951 break; /* finished */
1953 if (ret != ASN1_SUCCESS)
1955 gnutls_assert();
1956 ret = _gnutls_asn2err (ret);
1957 goto cleanup;
1960 if (strcmp(tmpoid, "1.3.6.1.5.5.7.2.1") == 0)
1962 snprintf (tmpstr, sizeof (tmpstr), "?%u.policyQualifiers.?%u.qualifier", indx, i+1);
1964 ret = _gnutls_x509_read_string(c2, tmpstr, &td, RV_IA5STRING);
1965 if (ret < 0)
1967 gnutls_assert();
1968 goto full_cleanup;
1971 policy->qualifier_data[i] = (void*)td.data;
1972 td.data = NULL;
1973 policy->qualifier_type[i] = GNUTLS_X509_QUALIFIER_URI;
1975 else if (strcmp(tmpoid, "1.3.6.1.5.5.7.2.2") == 0)
1977 snprintf (tmpstr, sizeof (tmpstr), "?%u.policyQualifiers.?%u.qualifier", indx, i+1);
1979 ret = _gnutls_x509_read_string(c2, tmpstr, &td, RV_RAW);
1980 if (ret < 0)
1982 gnutls_assert();
1983 goto full_cleanup;
1986 ret = decode_user_notice(td.data, td.size, &policy->qualifier_data[i]);
1987 gnutls_free(td.data);
1988 td.data = NULL;
1990 if (ret < 0)
1992 gnutls_assert();
1993 goto full_cleanup;
1996 policy->qualifier_type[i] = GNUTLS_X509_QUALIFIER_NOTICE;
1998 else
1999 policy->qualifier_type[i] = GNUTLS_X509_QUALIFIER_UNKNOWN;
2001 policy->qualifiers++;
2006 ret = 0;
2007 goto cleanup;
2009 full_cleanup:
2010 gnutls_certificate_policy_release(policy);
2012 cleanup:
2013 _gnutls_free_datum (&tmpd);
2014 asn1_delete_structure (&c2);
2015 return ret;
2020 * gnutls_x509_crt_get_extension_by_oid:
2021 * @cert: should contain a #gnutls_x509_crt_t structure
2022 * @oid: holds an Object Identified in null terminated string
2023 * @indx: In case multiple same OIDs exist in the extensions, this specifies which to send. Use (0) to get the first one.
2024 * @buf: a pointer to a structure to hold the name (may be null)
2025 * @buf_size: initially holds the size of @buf
2026 * @critical: will be non (0) if the extension is marked as critical
2028 * This function will return the extension specified by the OID in the
2029 * certificate. The extensions will be returned as binary data DER
2030 * encoded, in the provided buffer.
2032 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2033 * otherwise a negative error code is returned. If the certificate does not
2034 * contain the specified extension
2035 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
2038 gnutls_x509_crt_get_extension_by_oid (gnutls_x509_crt_t cert,
2039 const char *oid, int indx,
2040 void *buf, size_t * buf_size,
2041 unsigned int *critical)
2043 int result;
2044 gnutls_datum_t output;
2046 if (cert == NULL)
2048 gnutls_assert ();
2049 return GNUTLS_E_INVALID_REQUEST;
2052 if ((result =
2053 _gnutls_x509_crt_get_extension (cert, oid, indx, &output,
2054 critical)) < 0)
2056 gnutls_assert ();
2057 return result;
2060 if (output.size == 0 || output.data == NULL)
2062 gnutls_assert ();
2063 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2066 if (output.size > (unsigned int) *buf_size)
2068 *buf_size = output.size;
2069 _gnutls_free_datum (&output);
2070 return GNUTLS_E_SHORT_MEMORY_BUFFER;
2073 *buf_size = output.size;
2075 if (buf)
2076 memcpy (buf, output.data, output.size);
2078 _gnutls_free_datum (&output);
2080 return 0;
2085 * gnutls_x509_crt_get_extension_oid:
2086 * @cert: should contain a #gnutls_x509_crt_t structure
2087 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
2088 * @oid: a pointer to a structure to hold the OID (may be null)
2089 * @oid_size: initially holds the size of @oid
2091 * This function will return the requested extension OID in the certificate.
2092 * The extension OID will be stored as a string in the provided buffer.
2094 * The @oid returned will be null terminated, although @oid_size will not
2095 * account for the trailing null.
2097 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2098 * otherwise a negative error code is returned. If you have reached the
2099 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2100 * will be returned.
2103 gnutls_x509_crt_get_extension_oid (gnutls_x509_crt_t cert, int indx,
2104 void *oid, size_t * oid_size)
2106 int result;
2108 if (cert == NULL)
2110 gnutls_assert ();
2111 return GNUTLS_E_INVALID_REQUEST;
2114 result = _gnutls_x509_crt_get_extension_oid (cert, indx, oid, oid_size);
2115 if (result < 0)
2117 return result;
2120 return 0;
2125 * gnutls_x509_crt_get_extension_info:
2126 * @cert: should contain a #gnutls_x509_crt_t structure
2127 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
2128 * @oid: a pointer to a structure to hold the OID
2129 * @oid_size: initially holds the maximum size of @oid, on return
2130 * holds actual size of @oid.
2131 * @critical: output variable with critical flag, may be NULL.
2133 * This function will return the requested extension OID in the
2134 * certificate, and the critical flag for it. The extension OID will
2135 * be stored as a string in the provided buffer. Use
2136 * gnutls_x509_crt_get_extension_data() to extract the data.
2138 * If the buffer provided is not long enough to hold the output, then
2139 * @oid_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
2140 * returned. The @oid returned will be null terminated, although
2141 * @oid_size will not account for the trailing null.
2143 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2144 * otherwise a negative error code is returned. If you have reached the
2145 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2146 * will be returned.
2149 gnutls_x509_crt_get_extension_info (gnutls_x509_crt_t cert, int indx,
2150 void *oid, size_t * oid_size,
2151 unsigned int *critical)
2153 int result;
2154 char str_critical[10];
2155 char name[ASN1_MAX_NAME_SIZE];
2156 int len;
2158 if (!cert)
2160 gnutls_assert ();
2161 return GNUTLS_E_INVALID_REQUEST;
2164 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u.extnID",
2165 indx + 1);
2167 len = *oid_size;
2168 result = asn1_read_value (cert->cert, name, oid, &len);
2169 *oid_size = len;
2171 if (result == ASN1_ELEMENT_NOT_FOUND)
2172 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2173 else if (result != ASN1_SUCCESS)
2175 gnutls_assert ();
2176 return _gnutls_asn2err (result);
2179 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u.critical",
2180 indx + 1);
2181 len = sizeof (str_critical);
2182 result = asn1_read_value (cert->cert, name, str_critical, &len);
2183 if (result != ASN1_SUCCESS)
2185 gnutls_assert ();
2186 return _gnutls_asn2err (result);
2189 if (critical)
2191 if (str_critical[0] == 'T')
2192 *critical = 1;
2193 else
2194 *critical = 0;
2197 return 0;
2202 * gnutls_x509_crt_get_extension_data:
2203 * @cert: should contain a #gnutls_x509_crt_t structure
2204 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
2205 * @data: a pointer to a structure to hold the data (may be null)
2206 * @sizeof_data: initially holds the size of @oid
2208 * This function will return the requested extension data in the
2209 * certificate. The extension data will be stored as a string in the
2210 * provided buffer.
2212 * Use gnutls_x509_crt_get_extension_info() to extract the OID and
2213 * critical flag. Use gnutls_x509_crt_get_extension_by_oid() instead,
2214 * if you want to get data indexed by the extension OID rather than
2215 * sequence.
2217 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2218 * otherwise a negative error code is returned. If you have reached the
2219 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2220 * will be returned.
2223 gnutls_x509_crt_get_extension_data (gnutls_x509_crt_t cert, int indx,
2224 void *data, size_t * sizeof_data)
2226 int result, len;
2227 char name[ASN1_MAX_NAME_SIZE];
2229 if (!cert)
2231 gnutls_assert ();
2232 return GNUTLS_E_INVALID_REQUEST;
2235 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u.extnValue",
2236 indx + 1);
2238 len = *sizeof_data;
2239 result = asn1_read_value (cert->cert, name, data, &len);
2240 *sizeof_data = len;
2242 if (result == ASN1_ELEMENT_NOT_FOUND)
2243 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2244 else if (result < 0)
2246 gnutls_assert ();
2247 return _gnutls_asn2err (result);
2250 return 0;
2253 static int
2254 _gnutls_x509_crt_get_raw_dn2 (gnutls_x509_crt_t cert,
2255 const char *whom, gnutls_datum_t * start)
2257 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2258 int result, len1;
2259 int start1, end1;
2260 gnutls_datum_t signed_data = { NULL, 0 };
2262 /* get the issuer of 'cert'
2264 if ((result =
2265 asn1_create_element (_gnutls_get_pkix (), "PKIX1.TBSCertificate",
2266 &c2)) != ASN1_SUCCESS)
2268 gnutls_assert ();
2269 return _gnutls_asn2err (result);
2272 result =
2273 _gnutls_x509_get_signed_data (cert->cert, "tbsCertificate", &signed_data);
2274 if (result < 0)
2276 gnutls_assert ();
2277 goto cleanup;
2280 result = asn1_der_decoding (&c2, signed_data.data, signed_data.size, NULL);
2281 if (result != ASN1_SUCCESS)
2283 gnutls_assert ();
2284 asn1_delete_structure (&c2);
2285 result = _gnutls_asn2err (result);
2286 goto cleanup;
2289 result =
2290 asn1_der_decoding_startEnd (c2, signed_data.data, signed_data.size,
2291 whom, &start1, &end1);
2293 if (result != ASN1_SUCCESS)
2295 gnutls_assert ();
2296 result = _gnutls_asn2err (result);
2297 goto cleanup;
2300 len1 = end1 - start1 + 1;
2302 _gnutls_set_datum (start, &signed_data.data[start1], len1);
2304 result = 0;
2306 cleanup:
2307 asn1_delete_structure (&c2);
2308 _gnutls_free_datum (&signed_data);
2309 return result;
2313 * gnutls_x509_crt_get_raw_issuer_dn:
2314 * @cert: should contain a #gnutls_x509_crt_t structure
2315 * @start: will hold the starting point of the DN
2317 * This function will return a pointer to the DER encoded DN structure
2318 * and the length. This points to allocated data that must be free'd using gnutls_free().
2320 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2321 * negative error value.or a negative error code on error.
2325 gnutls_x509_crt_get_raw_issuer_dn (gnutls_x509_crt_t cert,
2326 gnutls_datum_t * start)
2328 return _gnutls_x509_crt_get_raw_dn2 (cert, "issuer", start);
2332 * gnutls_x509_crt_get_raw_dn:
2333 * @cert: should contain a #gnutls_x509_crt_t structure
2334 * @start: will hold the starting point of the DN
2336 * This function will return a pointer to the DER encoded DN structure and
2337 * the length. This points to allocated data that must be free'd using gnutls_free().
2339 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2340 * negative error value. or a negative error code on error.
2344 gnutls_x509_crt_get_raw_dn (gnutls_x509_crt_t cert, gnutls_datum_t * start)
2346 return _gnutls_x509_crt_get_raw_dn2 (cert, "subject", start);
2349 static int
2350 get_dn (gnutls_x509_crt_t cert, const char *whom, gnutls_x509_dn_t * dn)
2352 *dn = asn1_find_node (cert->cert, whom);
2353 if (!*dn)
2354 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2355 return 0;
2359 * gnutls_x509_crt_get_subject:
2360 * @cert: should contain a #gnutls_x509_crt_t structure
2361 * @dn: output variable with pointer to uint8_t DN.
2363 * Return the Certificate's Subject DN as an uint8_t data type. You
2364 * may use gnutls_x509_dn_get_rdn_ava() to decode the DN.
2366 * Note that @dn should be treated as constant. Because points
2367 * into the @cert object, you may not deallocate @cert
2368 * and continue to access @dn.
2370 * Returns: Returns 0 on success, or an error code.
2373 gnutls_x509_crt_get_subject (gnutls_x509_crt_t cert, gnutls_x509_dn_t * dn)
2375 return get_dn (cert, "tbsCertificate.subject.rdnSequence", dn);
2379 * gnutls_x509_crt_get_issuer:
2380 * @cert: should contain a #gnutls_x509_crt_t structure
2381 * @dn: output variable with pointer to uint8_t DN
2383 * Return the Certificate's Issuer DN as an uint8_t data type. You may
2384 * use gnutls_x509_dn_get_rdn_ava() to decode the DN.
2386 * Note that @dn should be treated as constant. Because points
2387 * into the @cert object, you may not deallocate @cert
2388 * and continue to access @dn.
2390 * Returns: Returns 0 on success, or an error code.
2393 gnutls_x509_crt_get_issuer (gnutls_x509_crt_t cert, gnutls_x509_dn_t * dn)
2395 return get_dn (cert, "tbsCertificate.issuer.rdnSequence", dn);
2399 * gnutls_x509_dn_get_rdn_ava:
2400 * @dn: input variable with uint8_t DN pointer
2401 * @irdn: index of RDN
2402 * @iava: index of AVA.
2403 * @ava: Pointer to structure which will hold output information.
2405 * Get pointers to data within the DN.
2407 * Note that @ava will contain pointers into the @dn structure, so you
2408 * should not modify any data or deallocate it. Note also that the DN
2409 * in turn points into the original certificate structure, and thus
2410 * you may not deallocate the certificate and continue to access @dn.
2412 * Returns: Returns 0 on success, or an error code.
2415 gnutls_x509_dn_get_rdn_ava (gnutls_x509_dn_t dn,
2416 int irdn, int iava, gnutls_x509_ava_st * ava)
2418 ASN1_TYPE rdn, elem;
2419 ASN1_DATA_NODE vnode;
2420 long len;
2421 int lenlen, remlen, ret;
2422 char rbuf[ASN1_MAX_NAME_SIZE];
2423 unsigned char cls;
2424 const unsigned char *ptr;
2426 iava++;
2427 irdn++; /* 0->1, 1->2 etc */
2429 snprintf (rbuf, sizeof (rbuf), "rdnSequence.?%d.?%d", irdn, iava);
2430 rdn = asn1_find_node (dn, rbuf);
2431 if (!rdn)
2433 gnutls_assert ();
2434 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2437 snprintf (rbuf, sizeof (rbuf), "?%d.type", iava);
2438 elem = asn1_find_node (rdn, rbuf);
2439 if (!elem)
2441 gnutls_assert ();
2442 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2445 ret = asn1_read_node_value(elem, &vnode);
2446 if (ret != ASN1_SUCCESS)
2448 gnutls_assert ();
2449 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2452 ava->oid.data = (void*)vnode.value;
2453 ava->oid.size = vnode.value_len;
2455 snprintf (rbuf, sizeof (rbuf), "?%d.value", iava);
2456 elem = asn1_find_node (rdn, rbuf);
2457 if (!elem)
2459 gnutls_assert ();
2460 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2463 ret = asn1_read_node_value(elem, &vnode);
2464 if (ret != ASN1_SUCCESS)
2466 gnutls_assert ();
2467 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2469 /* The value still has the previous tag's length bytes, plus the
2470 * current value's tag and length bytes. Decode them.
2473 ptr = vnode.value;
2474 remlen = vnode.value_len;
2475 len = asn1_get_length_der (ptr, remlen, &lenlen);
2476 if (len < 0)
2478 gnutls_assert ();
2479 return GNUTLS_E_ASN1_DER_ERROR;
2482 ptr += lenlen;
2483 remlen -= lenlen;
2484 ret = asn1_get_tag_der (ptr, remlen, &cls, &lenlen, &ava->value_tag);
2485 if (ret)
2487 gnutls_assert ();
2488 return _gnutls_asn2err (ret);
2491 ptr += lenlen;
2492 remlen -= lenlen;
2495 signed long tmp;
2497 tmp = asn1_get_length_der (ptr, remlen, &lenlen);
2498 if (tmp < 0)
2500 gnutls_assert ();
2501 return GNUTLS_E_ASN1_DER_ERROR;
2503 ava->value.size = tmp;
2505 ava->value.data = (void*)(ptr + lenlen);
2507 return 0;
2511 * gnutls_x509_crt_get_fingerprint:
2512 * @cert: should contain a #gnutls_x509_crt_t structure
2513 * @algo: is a digest algorithm
2514 * @buf: a pointer to a structure to hold the fingerprint (may be null)
2515 * @buf_size: initially holds the size of @buf
2517 * This function will calculate and copy the certificate's fingerprint
2518 * in the provided buffer.
2520 * If the buffer is null then only the size will be filled.
2522 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
2523 * not long enough, and in that case the *buf_size will be updated
2524 * with the required size. On success 0 is returned.
2527 gnutls_x509_crt_get_fingerprint (gnutls_x509_crt_t cert,
2528 gnutls_digest_algorithm_t algo,
2529 void *buf, size_t * buf_size)
2531 uint8_t *cert_buf;
2532 int cert_buf_size;
2533 int result;
2534 gnutls_datum_t tmp;
2536 if (buf_size == 0 || cert == NULL)
2538 return GNUTLS_E_INVALID_REQUEST;
2541 cert_buf_size = 0;
2542 asn1_der_coding (cert->cert, "", NULL, &cert_buf_size, NULL);
2544 cert_buf = gnutls_malloc (cert_buf_size);
2545 if (cert_buf == NULL)
2547 gnutls_assert ();
2548 return GNUTLS_E_MEMORY_ERROR;
2551 result = asn1_der_coding (cert->cert, "", cert_buf, &cert_buf_size, NULL);
2553 if (result != ASN1_SUCCESS)
2555 gnutls_assert ();
2556 gnutls_free (cert_buf);
2557 return _gnutls_asn2err (result);
2560 tmp.data = cert_buf;
2561 tmp.size = cert_buf_size;
2563 result = gnutls_fingerprint (algo, &tmp, buf, buf_size);
2564 gnutls_free (cert_buf);
2566 return result;
2570 * gnutls_x509_crt_export:
2571 * @cert: Holds the certificate
2572 * @format: the format of output params. One of PEM or DER.
2573 * @output_data: will contain a certificate PEM or DER encoded
2574 * @output_data_size: holds the size of output_data (and will be
2575 * replaced by the actual size of parameters)
2577 * This function will export the certificate to DER or PEM format.
2579 * If the buffer provided is not long enough to hold the output, then
2580 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2581 * be returned.
2583 * If the structure is PEM encoded, it will have a header
2584 * of "BEGIN CERTIFICATE".
2586 * Returns: In case of failure a negative error code will be
2587 * returned, and 0 on success.
2590 gnutls_x509_crt_export (gnutls_x509_crt_t cert,
2591 gnutls_x509_crt_fmt_t format, void *output_data,
2592 size_t * output_data_size)
2594 if (cert == NULL)
2596 gnutls_assert ();
2597 return GNUTLS_E_INVALID_REQUEST;
2600 return _gnutls_x509_export_int (cert->cert, format, "CERTIFICATE",
2601 output_data, output_data_size);
2605 * gnutls_x509_crt_export2:
2606 * @cert: Holds the certificate
2607 * @format: the format of output params. One of PEM or DER.
2608 * @out: will contain a certificate PEM or DER encoded
2610 * This function will export the certificate to DER or PEM format.
2611 * The output buffer is allocated using gnutls_malloc().
2613 * If the structure is PEM encoded, it will have a header
2614 * of "BEGIN CERTIFICATE".
2616 * Returns: In case of failure a negative error code will be
2617 * returned, and 0 on success.
2619 * Since: 3.1
2622 gnutls_x509_crt_export2 (gnutls_x509_crt_t cert,
2623 gnutls_x509_crt_fmt_t format, gnutls_datum_t * out)
2625 if (cert == NULL)
2627 gnutls_assert ();
2628 return GNUTLS_E_INVALID_REQUEST;
2631 return _gnutls_x509_export_int2 (cert->cert, format, "CERTIFICATE", out);
2635 _gnutls_get_key_id (gnutls_pk_algorithm_t pk, gnutls_pk_params_st * params,
2636 unsigned char *output_data,
2637 size_t * output_data_size)
2639 int ret = 0;
2640 gnutls_datum_t der = { NULL, 0 };
2641 const gnutls_digest_algorithm_t hash = GNUTLS_DIG_SHA1;
2642 unsigned int digest_len = _gnutls_hash_get_algo_len(hash);
2644 if (output_data == NULL || *output_data_size < digest_len)
2646 gnutls_assert ();
2647 *output_data_size = digest_len;
2648 return GNUTLS_E_SHORT_MEMORY_BUFFER;
2651 ret = _gnutls_x509_encode_PKI_params(&der, pk, params);
2652 if (ret < 0)
2653 return gnutls_assert_val(ret);
2655 ret = _gnutls_hash_fast(hash, der.data, der.size, output_data);
2656 if (ret < 0)
2658 gnutls_assert ();
2659 goto cleanup;
2661 *output_data_size = digest_len;
2663 ret = 0;
2665 cleanup:
2667 _gnutls_free_datum (&der);
2668 return ret;
2672 * gnutls_x509_crt_get_key_id:
2673 * @crt: Holds the certificate
2674 * @flags: should be 0 for now
2675 * @output_data: will contain the key ID
2676 * @output_data_size: holds the size of output_data (and will be
2677 * replaced by the actual size of parameters)
2679 * This function will return a unique ID that depends on the public
2680 * key parameters. This ID can be used in checking whether a
2681 * certificate corresponds to the given private key.
2683 * If the buffer provided is not long enough to hold the output, then
2684 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2685 * be returned. The output will normally be a SHA-1 hash output,
2686 * which is 20 bytes.
2688 * Returns: In case of failure a negative error code will be
2689 * returned, and 0 on success.
2692 gnutls_x509_crt_get_key_id (gnutls_x509_crt_t crt, unsigned int flags,
2693 unsigned char *output_data,
2694 size_t * output_data_size)
2696 int pk, ret = 0;
2697 gnutls_pk_params_st params;
2699 if (crt == NULL)
2701 gnutls_assert ();
2702 return GNUTLS_E_INVALID_REQUEST;
2705 pk = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
2706 if (pk < 0)
2708 gnutls_assert ();
2709 return pk;
2712 ret = _gnutls_x509_crt_get_mpis (crt, &params);
2713 if (ret < 0)
2715 gnutls_assert ();
2716 return ret;
2719 ret = _gnutls_get_key_id(pk, &params, output_data, output_data_size);
2721 gnutls_pk_params_release(&params);
2723 return ret;
2727 /* This is exactly as gnutls_x509_crt_check_revocation() except that
2728 * it calls func.
2731 _gnutls_x509_crt_check_revocation (gnutls_x509_crt_t cert,
2732 const gnutls_x509_crl_t * crl_list,
2733 int crl_list_length,
2734 gnutls_verify_output_function func)
2736 uint8_t serial[128];
2737 uint8_t cert_serial[128];
2738 size_t serial_size, cert_serial_size;
2739 int ncerts, ret, i, j;
2740 gnutls_datum_t dn1, dn2;
2742 if (cert == NULL)
2744 gnutls_assert ();
2745 return GNUTLS_E_INVALID_REQUEST;
2748 for (j = 0; j < crl_list_length; j++)
2749 { /* do for all the crls */
2751 /* Step 1. check if issuer's DN match
2753 ret = gnutls_x509_crl_get_raw_issuer_dn (crl_list[j], &dn1);
2754 if (ret < 0)
2756 gnutls_assert ();
2757 return ret;
2760 ret = gnutls_x509_crt_get_raw_issuer_dn (cert, &dn2);
2761 if (ret < 0)
2763 gnutls_assert ();
2764 return ret;
2767 ret = _gnutls_x509_compare_raw_dn (&dn1, &dn2);
2768 _gnutls_free_datum (&dn1);
2769 _gnutls_free_datum (&dn2);
2770 if (ret == 0)
2772 /* issuers do not match so don't even
2773 * bother checking.
2775 continue;
2778 /* Step 2. Read the certificate's serial number
2780 cert_serial_size = sizeof (cert_serial);
2781 ret = gnutls_x509_crt_get_serial (cert, cert_serial, &cert_serial_size);
2782 if (ret < 0)
2784 gnutls_assert ();
2785 return ret;
2788 /* Step 3. cycle through the CRL serials and compare with
2789 * certificate serial we have.
2792 ncerts = gnutls_x509_crl_get_crt_count (crl_list[j]);
2793 if (ncerts < 0)
2795 gnutls_assert ();
2796 return ncerts;
2799 for (i = 0; i < ncerts; i++)
2801 serial_size = sizeof (serial);
2802 ret =
2803 gnutls_x509_crl_get_crt_serial (crl_list[j], i, serial,
2804 &serial_size, NULL);
2806 if (ret < 0)
2808 gnutls_assert ();
2809 return ret;
2812 if (serial_size == cert_serial_size)
2814 if (memcmp (serial, cert_serial, serial_size) == 0)
2816 /* serials match */
2817 if (func) func(cert, NULL, crl_list[j], GNUTLS_CERT_REVOKED|GNUTLS_CERT_INVALID);
2818 return 1; /* revoked! */
2822 if (func) func(cert, NULL, crl_list[j], 0);
2825 return 0; /* not revoked. */
2830 * gnutls_x509_crt_check_revocation:
2831 * @cert: should contain a #gnutls_x509_crt_t structure
2832 * @crl_list: should contain a list of gnutls_x509_crl_t structures
2833 * @crl_list_length: the length of the crl_list
2835 * This function will return check if the given certificate is
2836 * revoked. It is assumed that the CRLs have been verified before.
2838 * Returns: 0 if the certificate is NOT revoked, and 1 if it is. A
2839 * negative error code is returned on error.
2842 gnutls_x509_crt_check_revocation (gnutls_x509_crt_t cert,
2843 const gnutls_x509_crl_t * crl_list,
2844 int crl_list_length)
2846 return _gnutls_x509_crt_check_revocation(cert, crl_list, crl_list_length, NULL);
2850 * gnutls_x509_crt_get_verify_algorithm:
2851 * @crt: Holds the certificate
2852 * @signature: contains the signature
2853 * @hash: The result of the call with the hash algorithm used for signature
2855 * This function will read the certifcate and the signed data to
2856 * determine the hash algorithm used to generate the signature.
2858 * Deprecated: Use gnutls_pubkey_get_verify_algorithm() instead.
2860 * Returns: the 0 if the hash algorithm is found. A negative error code is
2861 * returned on error.
2863 * Since: 2.8.0
2866 gnutls_x509_crt_get_verify_algorithm (gnutls_x509_crt_t crt,
2867 const gnutls_datum_t * signature,
2868 gnutls_digest_algorithm_t * hash)
2870 gnutls_pk_params_st issuer_params;
2871 int ret;
2873 if (crt == NULL)
2875 gnutls_assert ();
2876 return GNUTLS_E_INVALID_REQUEST;
2879 ret = _gnutls_x509_crt_get_mpis (crt, &issuer_params);
2880 if (ret < 0)
2882 gnutls_assert ();
2883 return ret;
2886 ret = _gnutls_x509_verify_algorithm (hash,
2887 signature,
2888 gnutls_x509_crt_get_pk_algorithm (crt,
2889 NULL),
2890 &issuer_params);
2892 /* release allocated mpis */
2893 gnutls_pk_params_release(&issuer_params);
2895 return ret;
2901 * gnutls_x509_crt_get_preferred_hash_algorithm:
2902 * @crt: Holds the certificate
2903 * @hash: The result of the call with the hash algorithm used for signature
2904 * @mand: If non (0) it means that the algorithm MUST use this hash. May be NULL.
2906 * This function will read the certifcate and return the appropriate digest
2907 * algorithm to use for signing with this certificate. Some certificates (i.e.
2908 * DSA might not be able to sign without the preferred algorithm).
2910 * Deprecated: Please use gnutls_pubkey_get_preferred_hash_algorithm().
2912 * Returns: the 0 if the hash algorithm is found. A negative error code is
2913 * returned on error.
2915 * Since: 2.12.0
2918 gnutls_x509_crt_get_preferred_hash_algorithm (gnutls_x509_crt_t crt,
2919 gnutls_digest_algorithm_t *
2920 hash, unsigned int *mand)
2922 gnutls_pk_params_st issuer_params;
2923 int ret;
2925 if (crt == NULL)
2927 gnutls_assert ();
2928 return GNUTLS_E_INVALID_REQUEST;
2931 ret = _gnutls_x509_crt_get_mpis (crt, &issuer_params);
2932 if (ret < 0)
2934 gnutls_assert ();
2935 return ret;
2938 ret =
2939 _gnutls_pk_get_hash_algorithm (gnutls_x509_crt_get_pk_algorithm
2940 (crt, NULL), &issuer_params,
2941 hash, mand);
2943 /* release allocated mpis */
2944 gnutls_pk_params_release(&issuer_params);
2946 return ret;
2950 * gnutls_x509_crt_verify_data:
2951 * @crt: Holds the certificate
2952 * @flags: should be 0 for now
2953 * @data: holds the data to be signed
2954 * @signature: contains the signature
2956 * This function will verify the given signed data, using the
2957 * parameters from the certificate.
2959 * Deprecated. Please use gnutls_pubkey_verify_data().
2961 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
2962 * is returned, and zero or positive code on success.
2965 gnutls_x509_crt_verify_data (gnutls_x509_crt_t crt, unsigned int flags,
2966 const gnutls_datum_t * data,
2967 const gnutls_datum_t * signature)
2969 int result;
2971 if (crt == NULL)
2973 gnutls_assert ();
2974 return GNUTLS_E_INVALID_REQUEST;
2977 result = _gnutls_x509_verify_data (GNUTLS_DIG_UNKNOWN, data, signature, crt);
2978 if (result < 0)
2980 gnutls_assert ();
2981 return result;
2984 return result;
2988 * gnutls_x509_crt_verify_hash:
2989 * @crt: Holds the certificate
2990 * @flags: should be 0 for now
2991 * @hash: holds the hash digest to be verified
2992 * @signature: contains the signature
2994 * This function will verify the given signed digest, using the
2995 * parameters from the certificate.
2997 * Deprecated. Please use gnutls_pubkey_verify_data2() or gnutls_pubkey_verify_hash2().
2999 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
3000 * is returned, and zero or positive code on success.
3003 gnutls_x509_crt_verify_hash (gnutls_x509_crt_t crt, unsigned int flags,
3004 const gnutls_datum_t * hash,
3005 const gnutls_datum_t * signature)
3007 gnutls_pk_params_st params;
3008 gnutls_digest_algorithm_t algo;
3009 int ret;
3011 if (crt == NULL)
3013 gnutls_assert ();
3014 return GNUTLS_E_INVALID_REQUEST;
3017 ret = gnutls_x509_crt_get_verify_algorithm (crt, signature, &algo);
3018 if (ret < 0)
3019 return gnutls_assert_val(ret);
3021 /* Read the MPI parameters from the issuer's certificate.
3023 ret =
3024 _gnutls_x509_crt_get_mpis (crt, &params);
3025 if (ret < 0)
3027 gnutls_assert ();
3028 return ret;
3031 ret =
3032 pubkey_verify_hashed_data (gnutls_x509_crt_get_pk_algorithm (crt, NULL), algo,
3033 hash, signature, &params);
3034 if (ret < 0)
3036 gnutls_assert ();
3039 /* release all allocated MPIs
3041 gnutls_pk_params_release(&params);
3043 return ret;
3047 * gnutls_x509_crt_get_crl_dist_points:
3048 * @cert: should contain a #gnutls_x509_crt_t structure
3049 * @seq: specifies the sequence number of the distribution point (0 for the first one, 1 for the second etc.)
3050 * @ret: is the place where the distribution point will be copied to
3051 * @ret_size: holds the size of ret.
3052 * @reason_flags: Revocation reasons. An ORed sequence of flags from %gnutls_x509_crl_reason_flags_t.
3053 * @critical: will be non (0) if the extension is marked as critical (may be null)
3055 * This function retrieves the CRL distribution points (2.5.29.31),
3056 * contained in the given certificate in the X509v3 Certificate
3057 * Extensions.
3059 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER and updates @ret_size if
3060 * @ret_size is not enough to hold the distribution point, or the
3061 * type of the distribution point if everything was ok. The type is
3062 * one of the enumerated %gnutls_x509_subject_alt_name_t. If the
3063 * certificate does not have an Alternative name with the specified
3064 * sequence number then %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is
3065 * returned.
3068 gnutls_x509_crt_get_crl_dist_points (gnutls_x509_crt_t cert,
3069 unsigned int seq, void *ret,
3070 size_t * ret_size,
3071 unsigned int *reason_flags,
3072 unsigned int *critical)
3074 int result;
3075 gnutls_datum_t dist_points = { NULL, 0 };
3076 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
3077 char name[ASN1_MAX_NAME_SIZE];
3078 int len;
3079 gnutls_x509_subject_alt_name_t type;
3080 uint8_t reasons[2];
3082 if (cert == NULL)
3084 gnutls_assert ();
3085 return GNUTLS_E_INVALID_REQUEST;
3088 if (*ret_size > 0 && ret)
3089 memset (ret, 0, *ret_size);
3090 else
3091 *ret_size = 0;
3093 if (reason_flags)
3094 *reason_flags = 0;
3096 result =
3097 _gnutls_x509_crt_get_extension (cert, "2.5.29.31", 0, &dist_points,
3098 critical);
3099 if (result < 0)
3101 return result;
3104 if (dist_points.size == 0 || dist_points.data == NULL)
3106 gnutls_assert ();
3107 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3110 result = asn1_create_element
3111 (_gnutls_get_pkix (), "PKIX1.CRLDistributionPoints", &c2);
3112 if (result != ASN1_SUCCESS)
3114 gnutls_assert ();
3115 _gnutls_free_datum (&dist_points);
3116 return _gnutls_asn2err (result);
3119 result = asn1_der_decoding (&c2, dist_points.data, dist_points.size, NULL);
3120 _gnutls_free_datum (&dist_points);
3122 if (result != ASN1_SUCCESS)
3124 gnutls_assert ();
3125 asn1_delete_structure (&c2);
3126 return _gnutls_asn2err (result);
3129 /* Return the different names from the first CRLDistr. point.
3130 * The whole thing is a mess.
3132 _gnutls_str_cpy (name, sizeof (name), "?1.distributionPoint.fullName");
3134 result = _gnutls_parse_general_name (c2, name, seq, ret, ret_size, NULL, 0);
3135 if (result < 0)
3137 asn1_delete_structure (&c2);
3138 return result;
3141 type = result;
3144 /* Read the CRL reasons.
3146 if (reason_flags)
3148 _gnutls_str_cpy (name, sizeof (name), "?1.reasons");
3150 reasons[0] = reasons[1] = 0;
3152 len = sizeof (reasons);
3153 result = asn1_read_value (c2, name, reasons, &len);
3155 if (result != ASN1_VALUE_NOT_FOUND && result != ASN1_SUCCESS)
3157 gnutls_assert ();
3158 asn1_delete_structure (&c2);
3159 return _gnutls_asn2err (result);
3162 *reason_flags = reasons[0] | (reasons[1] << 8);
3165 asn1_delete_structure (&c2);
3167 return type;
3171 * gnutls_x509_crt_get_key_purpose_oid:
3172 * @cert: should contain a #gnutls_x509_crt_t structure
3173 * @indx: This specifies which OID to return. Use (0) to get the first one.
3174 * @oid: a pointer to a buffer to hold the OID (may be null)
3175 * @oid_size: initially holds the size of @oid
3176 * @critical: output flag to indicate criticality of extension
3178 * This function will extract the key purpose OIDs of the Certificate
3179 * specified by the given index. These are stored in the Extended Key
3180 * Usage extension (2.5.29.37) See the GNUTLS_KP_* definitions for
3181 * human readable names.
3183 * If @oid is null then only the size will be filled. The @oid
3184 * returned will be null terminated, although @oid_size will not
3185 * account for the trailing null.
3187 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
3188 * not long enough, and in that case the *oid_size will be updated
3189 * with the required size. On success 0 is returned.
3192 gnutls_x509_crt_get_key_purpose_oid (gnutls_x509_crt_t cert,
3193 int indx, void *oid, size_t * oid_size,
3194 unsigned int *critical)
3196 char tmpstr[ASN1_MAX_NAME_SIZE];
3197 int result, len;
3198 gnutls_datum_t id;
3199 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
3201 if (cert == NULL)
3203 gnutls_assert ();
3204 return GNUTLS_E_INVALID_REQUEST;
3207 if (oid)
3208 memset (oid, 0, *oid_size);
3209 else
3210 *oid_size = 0;
3212 if ((result =
3213 _gnutls_x509_crt_get_extension (cert, "2.5.29.37", 0, &id,
3214 critical)) < 0)
3216 return result;
3219 if (id.size == 0 || id.data == NULL)
3221 gnutls_assert ();
3222 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3225 result = asn1_create_element
3226 (_gnutls_get_pkix (), "PKIX1.ExtKeyUsageSyntax", &c2);
3227 if (result != ASN1_SUCCESS)
3229 gnutls_assert ();
3230 _gnutls_free_datum (&id);
3231 return _gnutls_asn2err (result);
3234 result = asn1_der_decoding (&c2, id.data, id.size, NULL);
3235 _gnutls_free_datum (&id);
3237 if (result != ASN1_SUCCESS)
3239 gnutls_assert ();
3240 asn1_delete_structure (&c2);
3241 return _gnutls_asn2err (result);
3244 indx++;
3245 /* create a string like "?1"
3247 snprintf (tmpstr, sizeof (tmpstr), "?%u", indx);
3249 len = *oid_size;
3250 result = asn1_read_value (c2, tmpstr, oid, &len);
3252 *oid_size = len;
3253 asn1_delete_structure (&c2);
3255 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
3257 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3260 if (result != ASN1_SUCCESS)
3262 gnutls_assert ();
3263 return _gnutls_asn2err (result);
3266 return 0;
3271 * gnutls_x509_crt_get_pk_rsa_raw:
3272 * @crt: Holds the certificate
3273 * @m: will hold the modulus
3274 * @e: will hold the public exponent
3276 * This function will export the RSA public key's parameters found in
3277 * the given structure. The new parameters will be allocated using
3278 * gnutls_malloc() and will be stored in the appropriate datum.
3280 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3283 gnutls_x509_crt_get_pk_rsa_raw (gnutls_x509_crt_t crt,
3284 gnutls_datum_t * m, gnutls_datum_t * e)
3286 int ret;
3287 gnutls_pk_params_st params;
3289 if (crt == NULL)
3291 gnutls_assert ();
3292 return GNUTLS_E_INVALID_REQUEST;
3295 ret = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
3296 if (ret != GNUTLS_PK_RSA)
3298 gnutls_assert ();
3299 return GNUTLS_E_INVALID_REQUEST;
3302 ret = _gnutls_x509_crt_get_mpis (crt, &params);
3303 if (ret < 0)
3305 gnutls_assert ();
3306 return ret;
3309 ret = _gnutls_mpi_dprint_lz (params.params[0], m);
3310 if (ret < 0)
3312 gnutls_assert ();
3313 goto cleanup;
3316 ret = _gnutls_mpi_dprint_lz (params.params[1], e);
3317 if (ret < 0)
3319 gnutls_assert ();
3320 _gnutls_free_datum (m);
3321 goto cleanup;
3324 ret = 0;
3326 cleanup:
3327 gnutls_pk_params_release(&params);
3328 return ret;
3332 * gnutls_x509_crt_get_pk_dsa_raw:
3333 * @crt: Holds the certificate
3334 * @p: will hold the p
3335 * @q: will hold the q
3336 * @g: will hold the g
3337 * @y: will hold the y
3339 * This function will export the DSA public key's parameters found in
3340 * the given certificate. The new parameters will be allocated using
3341 * gnutls_malloc() and will be stored in the appropriate datum.
3343 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3346 gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt,
3347 gnutls_datum_t * p, gnutls_datum_t * q,
3348 gnutls_datum_t * g, gnutls_datum_t * y)
3350 int ret;
3351 gnutls_pk_params_st params;
3353 if (crt == NULL)
3355 gnutls_assert ();
3356 return GNUTLS_E_INVALID_REQUEST;
3359 ret = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
3360 if (ret != GNUTLS_PK_DSA)
3362 gnutls_assert ();
3363 return GNUTLS_E_INVALID_REQUEST;
3366 ret = _gnutls_x509_crt_get_mpis (crt, &params);
3367 if (ret < 0)
3369 gnutls_assert ();
3370 return ret;
3374 /* P */
3375 ret = _gnutls_mpi_dprint_lz (params.params[0], p);
3376 if (ret < 0)
3378 gnutls_assert ();
3379 goto cleanup;
3382 /* Q */
3383 ret = _gnutls_mpi_dprint_lz (params.params[1], q);
3384 if (ret < 0)
3386 gnutls_assert ();
3387 _gnutls_free_datum (p);
3388 goto cleanup;
3392 /* G */
3393 ret = _gnutls_mpi_dprint_lz (params.params[2], g);
3394 if (ret < 0)
3396 gnutls_assert ();
3397 _gnutls_free_datum (p);
3398 _gnutls_free_datum (q);
3399 goto cleanup;
3403 /* Y */
3404 ret = _gnutls_mpi_dprint_lz (params.params[3], y);
3405 if (ret < 0)
3407 gnutls_assert ();
3408 _gnutls_free_datum (p);
3409 _gnutls_free_datum (g);
3410 _gnutls_free_datum (q);
3411 goto cleanup;
3414 ret = 0;
3416 cleanup:
3417 gnutls_pk_params_release(&params);
3418 return ret;
3423 * gnutls_x509_crt_list_import2:
3424 * @certs: The structures to store the parsed certificate. Must not be initialized.
3425 * @size: It will contain the size of the list.
3426 * @data: The PEM encoded certificate.
3427 * @format: One of DER or PEM.
3428 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
3430 * This function will convert the given PEM encoded certificate list
3431 * to the native gnutls_x509_crt_t format. The output will be stored
3432 * in @certs which will be initialized.
3434 * If the Certificate is PEM encoded it should have a header of "X509
3435 * CERTIFICATE", or "CERTIFICATE".
3437 * Returns: the number of certificates read or a negative error value.
3439 * Since: 3.0
3442 gnutls_x509_crt_list_import2 (gnutls_x509_crt_t ** certs,
3443 unsigned int * size,
3444 const gnutls_datum_t * data,
3445 gnutls_x509_crt_fmt_t format, unsigned int flags)
3447 unsigned int init = 1024;
3448 int ret;
3450 *certs = gnutls_malloc(sizeof(gnutls_x509_crt_t)*init);
3451 if (*certs == NULL)
3453 gnutls_assert();
3454 return GNUTLS_E_MEMORY_ERROR;
3457 ret = gnutls_x509_crt_list_import(*certs, &init, data, format, GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
3458 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
3460 *certs = gnutls_realloc_fast(*certs, sizeof(gnutls_x509_crt_t)*init);
3461 if (*certs == NULL)
3463 gnutls_assert();
3464 return GNUTLS_E_MEMORY_ERROR;
3467 ret = gnutls_x509_crt_list_import(*certs, &init, data, format, flags);
3470 if (ret < 0)
3472 gnutls_free(*certs);
3473 *certs = NULL;
3474 return ret;
3477 *size = init;
3478 return 0;
3481 static int check_if_sorted(gnutls_x509_crt_t * crt, int nr)
3483 char prev_dn[MAX_DN];
3484 char dn[MAX_DN];
3485 size_t prev_dn_size, dn_size;
3486 int i, ret;
3488 /* check if the X.509 list is ordered */
3489 if (nr > 1)
3492 for (i=0;i<nr;i++)
3494 if (i>0)
3496 dn_size = sizeof(dn);
3497 ret = gnutls_x509_crt_get_dn(crt[i], dn, &dn_size);
3498 if (ret < 0)
3500 ret = gnutls_assert_val(ret);
3501 goto cleanup;
3504 if (dn_size != prev_dn_size || memcmp(dn, prev_dn, dn_size) != 0)
3506 ret = gnutls_assert_val(GNUTLS_E_CERTIFICATE_LIST_UNSORTED);
3507 goto cleanup;
3511 prev_dn_size = sizeof(prev_dn);
3512 ret = gnutls_x509_crt_get_issuer_dn(crt[i], prev_dn, &prev_dn_size);
3513 if (ret < 0)
3515 ret = gnutls_assert_val(ret);
3516 goto cleanup;
3521 ret = 0;
3523 cleanup:
3524 return ret;
3529 * gnutls_x509_crt_list_import:
3530 * @certs: The structures to store the parsed certificate. Must not be initialized.
3531 * @cert_max: Initially must hold the maximum number of certs. It will be updated with the number of certs available.
3532 * @data: The PEM encoded certificate.
3533 * @format: One of DER or PEM.
3534 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
3536 * This function will convert the given PEM encoded certificate list
3537 * to the native gnutls_x509_crt_t format. The output will be stored
3538 * in @certs. They will be automatically initialized.
3540 * The flag %GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED will cause
3541 * import to fail if the certificates in the provided buffer are more
3542 * than the available structures. The %GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED
3543 * flag will cause the function to fail if the provided list is not
3544 * sorted from subject to issuer.
3546 * If the Certificate is PEM encoded it should have a header of "X509
3547 * CERTIFICATE", or "CERTIFICATE".
3549 * Returns: the number of certificates read or a negative error value.
3552 gnutls_x509_crt_list_import (gnutls_x509_crt_t * certs,
3553 unsigned int *cert_max,
3554 const gnutls_datum_t * data,
3555 gnutls_x509_crt_fmt_t format, unsigned int flags)
3557 int size;
3558 const char *ptr;
3559 gnutls_datum_t tmp;
3560 int ret, nocopy = 0;
3561 unsigned int count = 0, j;
3563 if (format == GNUTLS_X509_FMT_DER)
3565 if (*cert_max < 1)
3567 *cert_max = 1;
3568 return GNUTLS_E_SHORT_MEMORY_BUFFER;
3571 count = 1; /* import only the first one */
3573 ret = gnutls_x509_crt_init (&certs[0]);
3574 if (ret < 0)
3576 gnutls_assert ();
3577 goto error;
3580 ret = gnutls_x509_crt_import (certs[0], data, format);
3581 if (ret < 0)
3583 gnutls_assert ();
3584 goto error;
3587 *cert_max = 1;
3588 return 1;
3591 /* move to the certificate
3593 ptr = memmem (data->data, data->size,
3594 PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
3595 if (ptr == NULL)
3596 ptr = memmem (data->data, data->size,
3597 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
3599 if (ptr == NULL)
3600 return gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_FOUND);
3602 count = 0;
3606 if (count >= *cert_max)
3608 if (!(flags & GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED))
3609 break;
3610 else
3611 nocopy = 1;
3614 if (!nocopy)
3616 ret = gnutls_x509_crt_init (&certs[count]);
3617 if (ret < 0)
3619 gnutls_assert ();
3620 goto error;
3623 tmp.data = (void *) ptr;
3624 tmp.size = data->size - (ptr - (char *) data->data);
3626 ret =
3627 gnutls_x509_crt_import (certs[count], &tmp, GNUTLS_X509_FMT_PEM);
3628 if (ret < 0)
3630 gnutls_assert ();
3631 goto error;
3635 /* now we move ptr after the pem header
3637 ptr++;
3638 /* find the next certificate (if any)
3640 size = data->size - (ptr - (char *) data->data);
3642 if (size > 0)
3644 char *ptr2;
3646 ptr2 = memmem (ptr, size, PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
3647 if (ptr2 == NULL)
3648 ptr2 = memmem (ptr, size, PEM_CERT_SEP2,
3649 sizeof (PEM_CERT_SEP2) - 1);
3651 ptr = ptr2;
3653 else
3654 ptr = NULL;
3656 count++;
3658 while (ptr != NULL);
3660 *cert_max = count;
3662 if (flags & GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED)
3664 ret = check_if_sorted(certs, *cert_max);
3665 if (ret < 0)
3667 gnutls_assert();
3668 goto error;
3672 if (nocopy == 0)
3673 return count;
3674 else
3675 return GNUTLS_E_SHORT_MEMORY_BUFFER;
3677 error:
3678 for (j = 0; j < count; j++)
3679 gnutls_x509_crt_deinit (certs[j]);
3680 return ret;
3684 * gnutls_x509_crt_get_subject_unique_id:
3685 * @crt: Holds the certificate
3686 * @buf: user allocated memory buffer, will hold the unique id
3687 * @buf_size: size of user allocated memory buffer (on input), will hold
3688 * actual size of the unique ID on return.
3690 * This function will extract the subjectUniqueID value (if present) for
3691 * the given certificate.
3693 * If the user allocated memory buffer is not large enough to hold the
3694 * full subjectUniqueID, then a GNUTLS_E_SHORT_MEMORY_BUFFER error will be
3695 * returned, and buf_size will be set to the actual length.
3697 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3700 gnutls_x509_crt_get_subject_unique_id (gnutls_x509_crt_t crt, char *buf,
3701 size_t * buf_size)
3703 int result;
3704 gnutls_datum_t datum = { NULL, 0 };
3706 result =
3707 _gnutls_x509_read_string (crt->cert, "tbsCertificate.subjectUniqueID",
3708 &datum, RV_BIT_STRING);
3710 if (datum.size > *buf_size)
3711 { /* then we're not going to fit */
3712 *buf_size = datum.size;
3713 buf[0] = '\0';
3714 result = GNUTLS_E_SHORT_MEMORY_BUFFER;
3716 else
3718 *buf_size = datum.size;
3719 memcpy (buf, datum.data, datum.size);
3722 _gnutls_free_datum (&datum);
3724 return result;
3728 * gnutls_x509_crt_get_issuer_unique_id:
3729 * @crt: Holds the certificate
3730 * @buf: user allocated memory buffer, will hold the unique id
3731 * @buf_size: size of user allocated memory buffer (on input), will hold
3732 * actual size of the unique ID on return.
3734 * This function will extract the issuerUniqueID value (if present) for
3735 * the given certificate.
3737 * If the user allocated memory buffer is not large enough to hold the
3738 * full subjectUniqueID, then a GNUTLS_E_SHORT_MEMORY_BUFFER error will be
3739 * returned, and buf_size will be set to the actual length.
3741 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3743 * Since: 2.12.0
3746 gnutls_x509_crt_get_issuer_unique_id (gnutls_x509_crt_t crt, char *buf,
3747 size_t * buf_size)
3749 int result;
3750 gnutls_datum_t datum = { NULL, 0 };
3752 result =
3753 _gnutls_x509_read_string (crt->cert, "tbsCertificate.issuerUniqueID",
3754 &datum, RV_BIT_STRING);
3756 if (datum.size > *buf_size)
3757 { /* then we're not going to fit */
3758 *buf_size = datum.size;
3759 buf[0] = '\0';
3760 result = GNUTLS_E_SHORT_MEMORY_BUFFER;
3762 else
3764 *buf_size = datum.size;
3765 memcpy (buf, datum.data, datum.size);
3768 _gnutls_free_datum (&datum);
3770 return result;
3773 static int
3774 _gnutls_parse_aia (ASN1_TYPE src,
3775 unsigned int seq,
3776 int what,
3777 gnutls_datum_t * data)
3779 int len;
3780 char nptr[ASN1_MAX_NAME_SIZE];
3781 int result;
3782 gnutls_datum_t d;
3783 const char *oid = NULL;
3785 seq++; /* 0->1, 1->2 etc */
3786 switch (what)
3788 case GNUTLS_IA_ACCESSMETHOD_OID:
3789 snprintf (nptr, sizeof (nptr), "?%u.accessMethod", seq);
3790 break;
3792 case GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE:
3793 snprintf (nptr, sizeof (nptr), "?%u.accessLocation", seq);
3794 break;
3796 case GNUTLS_IA_CAISSUERS_URI:
3797 oid = GNUTLS_OID_AD_CAISSUERS;
3798 /* fall through */
3800 case GNUTLS_IA_OCSP_URI:
3801 if (oid == NULL)
3802 oid = GNUTLS_OID_AD_OCSP;
3804 char tmpoid[20];
3805 snprintf (nptr, sizeof (nptr), "?%u.accessMethod", seq);
3806 len = sizeof (tmpoid);
3807 result = asn1_read_value (src, nptr, tmpoid, &len);
3809 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
3810 return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
3812 if (result != ASN1_SUCCESS)
3814 gnutls_assert ();
3815 return _gnutls_asn2err (result);
3817 if ((unsigned)len != strlen (oid) + 1 || memcmp (tmpoid, oid, len) != 0)
3818 return gnutls_assert_val(GNUTLS_E_UNKNOWN_ALGORITHM);
3820 /* fall through */
3822 case GNUTLS_IA_URI:
3823 snprintf (nptr, sizeof (nptr),
3824 "?%u.accessLocation.uniformResourceIdentifier", seq);
3825 break;
3827 default:
3828 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
3831 len = 0;
3832 result = asn1_read_value (src, nptr, NULL, &len);
3833 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
3834 return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
3836 if (result != ASN1_MEM_ERROR)
3838 gnutls_assert ();
3839 return _gnutls_asn2err (result);
3842 d.size = len;
3844 d.data = gnutls_malloc (d.size);
3845 if (d.data == NULL)
3846 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
3848 result = asn1_read_value (src, nptr, d.data, &len);
3849 if (result != ASN1_SUCCESS)
3851 gnutls_assert ();
3852 gnutls_free (d.data);
3853 return _gnutls_asn2err (result);
3856 if (data)
3858 data->data = d.data;
3859 data->size = d.size;
3861 else
3862 gnutls_free (d.data);
3864 return 0;
3868 * gnutls_x509_crt_get_authority_info_access:
3869 * @crt: Holds the certificate
3870 * @seq: specifies the sequence number of the access descriptor (0 for the first one, 1 for the second etc.)
3871 * @what: what data to get, a #gnutls_info_access_what_t type.
3872 * @data: output data to be freed with gnutls_free().
3873 * @critical: pointer to output integer that is set to non-0 if the extension is marked as critical (may be %NULL)
3875 * This function extracts the Authority Information Access (AIA)
3876 * extension, see RFC 5280 section 4.2.2.1 for more information. The
3877 * AIA extension holds a sequence of AccessDescription (AD) data:
3879 * <informalexample><programlisting>
3880 * AuthorityInfoAccessSyntax ::=
3881 * SEQUENCE SIZE (1..MAX) OF AccessDescription
3883 * AccessDescription ::= SEQUENCE {
3884 * accessMethod OBJECT IDENTIFIER,
3885 * accessLocation GeneralName }
3886 * </programlisting></informalexample>
3888 * The @seq input parameter is used to indicate which member of the
3889 * sequence the caller is interested in. The first member is 0, the
3890 * second member 1 and so on. When the @seq value is out of bounds,
3891 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
3893 * The type of data returned in @data is specified via @what which
3894 * should be #gnutls_info_access_what_t values.
3896 * If @what is %GNUTLS_IA_ACCESSMETHOD_OID then @data will hold the
3897 * accessMethod OID (e.g., "1.3.6.1.5.5.7.48.1").
3899 * If @what is %GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE, @data will
3900 * hold the accessLocation GeneralName type (e.g.,
3901 * "uniformResourceIdentifier").
3903 * If @what is %GNUTLS_IA_URI, @data will hold the accessLocation URI
3904 * data. Requesting this @what value leads to an error if the
3905 * accessLocation is not of the "uniformResourceIdentifier" type.
3907 * If @what is %GNUTLS_IA_OCSP_URI, @data will hold the OCSP URI.
3908 * Requesting this @what value leads to an error if the accessMethod
3909 * is not 1.3.6.1.5.5.7.48.1 aka OSCP, or if accessLocation is not of
3910 * the "uniformResourceIdentifier" type.
3912 * If @what is %GNUTLS_IA_CAISSUERS_URI, @data will hold the caIssuers
3913 * URI. Requesting this @what value leads to an error if the
3914 * accessMethod is not 1.3.6.1.5.5.7.48.2 aka caIssuers, or if
3915 * accessLocation is not of the "uniformResourceIdentifier" type.
3917 * More @what values may be allocated in the future as needed.
3919 * If @data is NULL, the function does the same without storing the
3920 * output data, that is, it will set @critical and do error checking
3921 * as usual.
3923 * The value of the critical flag is returned in *@critical. Supply a
3924 * NULL @critical if you want the function to make sure the extension
3925 * is non-critical, as required by RFC 5280.
3927 * Returns: %GNUTLS_E_SUCCESS on success, %GNUTLS_E_INVALID_REQUEST on
3928 * invalid @crt, %GNUTLS_E_CONSTRAINT_ERROR if the extension is
3929 * incorrectly marked as critical (use a non-NULL @critical to
3930 * override), %GNUTLS_E_UNKNOWN_ALGORITHM if the requested OID does
3931 * not match (e.g., when using %GNUTLS_IA_OCSP_URI), otherwise a
3932 * negative error code.
3934 * Since: 3.0
3937 gnutls_x509_crt_get_authority_info_access (gnutls_x509_crt_t crt,
3938 unsigned int seq,
3939 int what,
3940 gnutls_datum_t * data,
3941 unsigned int *critical)
3943 int ret;
3944 gnutls_datum_t aia;
3945 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
3947 if (crt == NULL)
3949 gnutls_assert ();
3950 return GNUTLS_E_INVALID_REQUEST;
3953 if ((ret = _gnutls_x509_crt_get_extension (crt, GNUTLS_OID_AIA, 0, &aia,
3954 critical)) < 0)
3955 return ret;
3957 if (aia.size == 0 || aia.data == NULL)
3959 gnutls_assert ();
3960 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3963 if (critical && *critical)
3964 return GNUTLS_E_CONSTRAINT_ERROR;
3966 ret = asn1_create_element (_gnutls_get_pkix (),
3967 "PKIX1.AuthorityInfoAccessSyntax", &c2);
3968 if (ret != ASN1_SUCCESS)
3970 gnutls_assert ();
3971 _gnutls_free_datum (&aia);
3972 return _gnutls_asn2err (ret);
3975 ret = asn1_der_decoding (&c2, aia.data, aia.size, NULL);
3976 /* asn1_print_structure (stdout, c2, "", ASN1_PRINT_ALL); */
3977 _gnutls_free_datum (&aia);
3978 if (ret != ASN1_SUCCESS)
3980 gnutls_assert ();
3981 asn1_delete_structure (&c2);
3982 return _gnutls_asn2err (ret);
3985 ret = _gnutls_parse_aia (c2, seq, what, data);
3987 asn1_delete_structure (&c2);
3988 if (ret < 0)
3989 gnutls_assert ();
3991 return ret;
3995 * gnutls_x509_crt_set_pin_function:
3996 * @crt: The certificate structure
3997 * @fn: the callback
3998 * @userdata: data associated with the callback
4000 * This function will set a callback function to be used when
4001 * it is required to access a protected object. This function overrides
4002 * the global function set using gnutls_pkcs11_set_pin_function().
4004 * Note that this callback is currently used only during the import
4005 * of a PKCS #11 certificate with gnutls_x509_crt_import_pkcs11_url().
4007 * Since: 3.1.0
4010 void gnutls_x509_crt_set_pin_function (gnutls_x509_crt_t crt,
4011 gnutls_pin_callback_t fn, void *userdata)
4013 crt->pin.cb = fn;
4014 crt->pin.data = userdata;