Corrected bugs in record parsing.
[gnutls.git] / lib / x509 / crl.c
blobbdde7e99b1410f80bd61339989d73adb4da8e9fc
1 /*
2 * Copyright (C) 2003-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 #include <gnutls_int.h>
24 #include <libtasn1.h>
26 #include <gnutls_datum.h>
27 #include <gnutls_global.h>
28 #include <gnutls_errors.h>
29 #include <common.h>
30 #include <x509_b64.h>
31 #include <x509_int.h>
32 #include <gnutls_x509.h>
34 /**
35 * gnutls_x509_crl_init:
36 * @crl: The structure to be initialized
38 * This function will initialize a CRL structure. CRL stands for
39 * Certificate Revocation List. A revocation list usually contains
40 * lists of certificate serial numbers that have been revoked by an
41 * Authority. The revocation lists are always signed with the
42 * authority's private key.
44 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
45 * negative error value.
46 **/
47 int
48 gnutls_x509_crl_init (gnutls_x509_crl_t * crl)
50 *crl = gnutls_calloc (1, sizeof (gnutls_x509_crl_int));
52 if (*crl)
54 int result = asn1_create_element (_gnutls_get_pkix (),
55 "PKIX1.CertificateList",
56 &(*crl)->crl);
57 if (result != ASN1_SUCCESS)
59 gnutls_assert ();
60 gnutls_free (*crl);
61 return _gnutls_asn2err (result);
63 return 0; /* success */
65 return GNUTLS_E_MEMORY_ERROR;
68 /**
69 * gnutls_x509_crl_deinit:
70 * @crl: The structure to be initialized
72 * This function will deinitialize a CRL structure.
73 **/
74 void
75 gnutls_x509_crl_deinit (gnutls_x509_crl_t crl)
77 if (!crl)
78 return;
80 if (crl->crl)
81 asn1_delete_structure (&crl->crl);
83 gnutls_free (crl);
86 /**
87 * gnutls_x509_crl_import:
88 * @crl: The structure to store the parsed CRL.
89 * @data: The DER or PEM encoded CRL.
90 * @format: One of DER or PEM
92 * This function will convert the given DER or PEM encoded CRL
93 * to the native #gnutls_x509_crl_t format. The output will be stored in 'crl'.
95 * If the CRL is PEM encoded it should have a header of "X509 CRL".
97 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
98 * negative error value.
99 **/
101 gnutls_x509_crl_import (gnutls_x509_crl_t crl,
102 const gnutls_datum_t * data,
103 gnutls_x509_crt_fmt_t format)
105 int result = 0, need_free = 0;
106 gnutls_datum_t _data;
108 _data.data = data->data;
109 _data.size = data->size;
111 if (crl == NULL)
113 gnutls_assert ();
114 return GNUTLS_E_INVALID_REQUEST;
117 /* If the CRL is in PEM format then decode it
119 if (format == GNUTLS_X509_FMT_PEM)
121 result = _gnutls_fbase64_decode (PEM_CRL, data->data, data->size, &_data);
123 if (result < 0)
125 gnutls_assert ();
126 return result;
129 need_free = 1;
133 result = asn1_der_decoding (&crl->crl, _data.data, _data.size, NULL);
134 if (result != ASN1_SUCCESS)
136 result = _gnutls_asn2err (result);
137 gnutls_assert ();
138 goto cleanup;
141 if (need_free)
142 _gnutls_free_datum (&_data);
144 return 0;
146 cleanup:
147 if (need_free)
148 _gnutls_free_datum (&_data);
149 return result;
154 * gnutls_x509_crl_get_issuer_dn:
155 * @crl: should contain a gnutls_x509_crl_t structure
156 * @buf: a pointer to a structure to hold the peer's name (may be null)
157 * @sizeof_buf: initially holds the size of @buf
159 * This function will copy the name of the CRL issuer in the provided
160 * buffer. The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
161 * described in RFC4514. The output string will be ASCII or UTF-8
162 * encoded, depending on the certificate data.
164 * If buf is %NULL then only the size will be filled.
166 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
167 * not long enough, and in that case the sizeof_buf will be updated
168 * with the required size, and 0 on success.
172 gnutls_x509_crl_get_issuer_dn (const gnutls_x509_crl_t crl, char *buf,
173 size_t * sizeof_buf)
175 if (crl == NULL)
177 gnutls_assert ();
178 return GNUTLS_E_INVALID_REQUEST;
181 return _gnutls_x509_parse_dn (crl->crl,
182 "tbsCertList.issuer.rdnSequence",
183 buf, sizeof_buf);
187 * gnutls_x509_crl_get_issuer_dn_by_oid:
188 * @crl: should contain a gnutls_x509_crl_t structure
189 * @oid: holds an Object Identified in null terminated string
190 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use (0) to get the first one.
191 * @raw_flag: If non-zero returns the raw DER data of the DN part.
192 * @buf: a pointer to a structure to hold the peer's name (may be null)
193 * @sizeof_buf: initially holds the size of @buf
195 * This function will extract the part of the name of the CRL issuer
196 * specified by the given OID. The output will be encoded as described
197 * in RFC4514. The output string will be ASCII or UTF-8 encoded,
198 * depending on the certificate data.
200 * Some helper macros with popular OIDs can be found in gnutls/x509.h
201 * If raw flag is (0), this function will only return known OIDs as
202 * text. Other OIDs will be DER encoded, as described in RFC4514 -- in
203 * hex format with a '#' prefix. You can check about known OIDs
204 * using gnutls_x509_dn_oid_known().
206 * If buf is null then only the size will be filled.
208 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
209 * not long enough, and in that case the sizeof_buf will be updated
210 * with the required size, and 0 on success.
213 gnutls_x509_crl_get_issuer_dn_by_oid (gnutls_x509_crl_t crl,
214 const char *oid, int indx,
215 unsigned int raw_flag, void *buf,
216 size_t * sizeof_buf)
218 gnutls_datum_t td;
219 int ret;
221 if (crl == NULL)
223 gnutls_assert ();
224 return GNUTLS_E_INVALID_REQUEST;
227 ret = _gnutls_x509_parse_dn_oid (crl->crl,
228 "tbsCertList.issuer.rdnSequence",
229 oid, indx, raw_flag, &td);
230 if (ret < 0)
231 return gnutls_assert_val(ret);
233 return _gnutls_strdatum_to_buf (&td, buf, sizeof_buf);
238 * gnutls_x509_crl_get_dn_oid:
239 * @crl: should contain a gnutls_x509_crl_t structure
240 * @indx: Specifies which DN OID to send. Use (0) to get the first one.
241 * @oid: a pointer to a structure to hold the name (may be null)
242 * @sizeof_oid: initially holds the size of 'oid'
244 * This function will extract the requested OID of the name of the CRL
245 * issuer, specified by the given index.
247 * If oid is null then only the size will be filled.
249 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
250 * not long enough, and in that case the sizeof_oid will be updated
251 * with the required size. On success 0 is returned.
254 gnutls_x509_crl_get_dn_oid (gnutls_x509_crl_t crl,
255 int indx, void *oid, size_t * sizeof_oid)
257 if (crl == NULL)
259 gnutls_assert ();
260 return GNUTLS_E_INVALID_REQUEST;
263 return _gnutls_x509_get_dn_oid (crl->crl,
264 "tbsCertList.issuer.rdnSequence", indx,
265 oid, sizeof_oid);
270 * gnutls_x509_crl_get_signature_algorithm:
271 * @crl: should contain a #gnutls_x509_crl_t structure
273 * This function will return a value of the #gnutls_sign_algorithm_t
274 * enumeration that is the signature algorithm.
276 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
277 * negative error value.
280 gnutls_x509_crl_get_signature_algorithm (gnutls_x509_crl_t crl)
282 int result;
283 gnutls_datum_t sa;
285 if (crl == NULL)
287 gnutls_assert ();
288 return GNUTLS_E_INVALID_REQUEST;
291 /* Read the signature algorithm. Note that parameters are not
292 * read. They will be read from the issuer's certificate if needed.
295 result =
296 _gnutls_x509_read_value (crl->crl, "signatureAlgorithm.algorithm",
297 &sa);
299 if (result < 0)
301 gnutls_assert ();
302 return result;
305 result = _gnutls_x509_oid2sign_algorithm ((const char *) sa.data);
307 _gnutls_free_datum (&sa);
309 return result;
313 * gnutls_x509_crl_get_signature:
314 * @crl: should contain a gnutls_x509_crl_t structure
315 * @sig: a pointer where the signature part will be copied (may be null).
316 * @sizeof_sig: initially holds the size of @sig
318 * This function will extract the signature field of a CRL.
320 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
321 * negative error value. and a negative error code on error.
324 gnutls_x509_crl_get_signature (gnutls_x509_crl_t crl,
325 char *sig, size_t * sizeof_sig)
327 int result;
328 unsigned int bits;
329 int len;
331 if (crl == NULL)
333 gnutls_assert ();
334 return GNUTLS_E_INVALID_REQUEST;
337 len = 0;
338 result = asn1_read_value (crl->crl, "signature", NULL, &len);
340 if (result != ASN1_MEM_ERROR)
342 gnutls_assert ();
343 return _gnutls_asn2err (result);
346 bits = len;
347 if (bits % 8 != 0)
349 gnutls_assert ();
350 return GNUTLS_E_CERTIFICATE_ERROR;
353 len = bits / 8;
355 if (*sizeof_sig < (unsigned)len)
357 *sizeof_sig = bits / 8;
358 return GNUTLS_E_SHORT_MEMORY_BUFFER;
361 result = asn1_read_value (crl->crl, "signature", sig, &len);
362 if (result != ASN1_SUCCESS)
364 gnutls_assert ();
365 return _gnutls_asn2err (result);
368 return 0;
372 * gnutls_x509_crl_get_version:
373 * @crl: should contain a #gnutls_x509_crl_t structure
375 * This function will return the version of the specified CRL.
377 * Returns: The version number, or a negative error code on error.
380 gnutls_x509_crl_get_version (gnutls_x509_crl_t crl)
382 uint8_t version[8];
383 int len, result;
385 if (crl == NULL)
387 gnutls_assert ();
388 return GNUTLS_E_INVALID_REQUEST;
391 len = sizeof (version);
392 if ((result =
393 asn1_read_value (crl->crl, "tbsCertList.version", version,
394 &len)) != ASN1_SUCCESS)
396 gnutls_assert ();
397 return _gnutls_asn2err (result);
400 return (int) version[0] + 1;
404 * gnutls_x509_crl_get_this_update:
405 * @crl: should contain a #gnutls_x509_crl_t structure
407 * This function will return the time this CRL was issued.
409 * Returns: when the CRL was issued, or (time_t)-1 on error.
411 time_t
412 gnutls_x509_crl_get_this_update (gnutls_x509_crl_t crl)
414 if (crl == NULL)
416 gnutls_assert ();
417 return (time_t) - 1;
420 return _gnutls_x509_get_time (crl->crl, "tbsCertList.thisUpdate", 0);
424 * gnutls_x509_crl_get_next_update:
425 * @crl: should contain a #gnutls_x509_crl_t structure
427 * This function will return the time the next CRL will be issued.
428 * This field is optional in a CRL so it might be normal to get an
429 * error instead.
431 * Returns: when the next CRL will be issued, or (time_t)-1 on error.
433 time_t
434 gnutls_x509_crl_get_next_update (gnutls_x509_crl_t crl)
436 if (crl == NULL)
438 gnutls_assert ();
439 return (time_t) - 1;
442 return _gnutls_x509_get_time (crl->crl, "tbsCertList.nextUpdate", 0);
446 * gnutls_x509_crl_get_crt_count:
447 * @crl: should contain a #gnutls_x509_crl_t structure
449 * This function will return the number of revoked certificates in the
450 * given CRL.
452 * Returns: number of certificates, a negative error code on failure.
455 gnutls_x509_crl_get_crt_count (gnutls_x509_crl_t crl)
458 int count, result;
460 if (crl == NULL)
462 gnutls_assert ();
463 return GNUTLS_E_INVALID_REQUEST;
466 result =
467 asn1_number_of_elements (crl->crl,
468 "tbsCertList.revokedCertificates", &count);
470 if (result != ASN1_SUCCESS)
472 gnutls_assert ();
473 return 0; /* no certificates */
476 return count;
480 * gnutls_x509_crl_get_crt_serial:
481 * @crl: should contain a #gnutls_x509_crl_t structure
482 * @indx: the index of the certificate to extract (starting from 0)
483 * @serial: where the serial number will be copied
484 * @serial_size: initially holds the size of serial
485 * @t: if non null, will hold the time this certificate was revoked
487 * This function will retrieve the serial number of the specified, by
488 * the index, revoked certificate.
490 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
491 * negative error value. and a negative error code on error.
494 gnutls_x509_crl_get_crt_serial (gnutls_x509_crl_t crl, int indx,
495 unsigned char *serial,
496 size_t * serial_size, time_t * t)
499 int result, _serial_size;
500 char serial_name[ASN1_MAX_NAME_SIZE];
501 char date_name[ASN1_MAX_NAME_SIZE];
503 if (crl == NULL)
505 gnutls_assert ();
506 return GNUTLS_E_INVALID_REQUEST;
509 snprintf (serial_name, sizeof (serial_name),
510 "tbsCertList.revokedCertificates.?%u.userCertificate", indx + 1);
511 snprintf (date_name, sizeof (date_name),
512 "tbsCertList.revokedCertificates.?%u.revocationDate", indx + 1);
514 _serial_size = *serial_size;
515 result = asn1_read_value (crl->crl, serial_name, serial, &_serial_size);
517 *serial_size = _serial_size;
518 if (result != ASN1_SUCCESS)
520 gnutls_assert ();
521 if (result == ASN1_ELEMENT_NOT_FOUND)
522 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
523 return _gnutls_asn2err (result);
526 if (t)
528 *t = _gnutls_x509_get_time (crl->crl, date_name, 0);
531 return 0;
535 * gnutls_x509_crl_get_raw_issuer_dn:
536 * @crl: should contain a gnutls_x509_crl_t structure
537 * @dn: will hold the starting point of the DN
539 * This function will return a pointer to the DER encoded DN structure
540 * and the length.
542 * Returns: a negative error code on error, and (0) on success.
544 * Since: 2.12.0
547 gnutls_x509_crl_get_raw_issuer_dn (gnutls_x509_crl_t crl,
548 gnutls_datum_t * dn)
550 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
551 int result, len1;
552 int start1, end1;
553 gnutls_datum_t crl_signed_data;
555 if (crl == NULL)
557 gnutls_assert ();
558 return GNUTLS_E_INVALID_REQUEST;
561 /* get the issuer of 'crl'
563 if ((result =
564 asn1_create_element (_gnutls_get_pkix (), "PKIX1.TBSCertList",
565 &c2)) != ASN1_SUCCESS)
567 gnutls_assert ();
568 return _gnutls_asn2err (result);
571 result =
572 _gnutls_x509_get_signed_data (crl->crl, "tbsCertList", &crl_signed_data);
573 if (result < 0)
575 gnutls_assert ();
576 goto cleanup;
579 result =
580 asn1_der_decoding (&c2, crl_signed_data.data, crl_signed_data.size, NULL);
581 if (result != ASN1_SUCCESS)
583 /* couldn't decode DER */
584 gnutls_assert ();
585 asn1_delete_structure (&c2);
586 result = _gnutls_asn2err (result);
587 goto cleanup;
590 result =
591 asn1_der_decoding_startEnd (c2, crl_signed_data.data,
592 crl_signed_data.size, "issuer",
593 &start1, &end1);
595 if (result != ASN1_SUCCESS)
597 gnutls_assert ();
598 result = _gnutls_asn2err (result);
599 goto cleanup;
602 len1 = end1 - start1 + 1;
604 _gnutls_set_datum (dn, &crl_signed_data.data[start1], len1);
606 result = 0;
608 cleanup:
609 asn1_delete_structure (&c2);
610 _gnutls_free_datum (&crl_signed_data);
611 return result;
615 * gnutls_x509_crl_export:
616 * @crl: Holds the revocation list
617 * @format: the format of output params. One of PEM or DER.
618 * @output_data: will contain a private key PEM or DER encoded
619 * @output_data_size: holds the size of output_data (and will
620 * be replaced by the actual size of parameters)
622 * This function will export the revocation list to DER or PEM format.
624 * If the buffer provided is not long enough to hold the output, then
625 * %GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
627 * If the structure is PEM encoded, it will have a header
628 * of "BEGIN X509 CRL".
630 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
631 * negative error value. and a negative error code on failure.
634 gnutls_x509_crl_export (gnutls_x509_crl_t crl,
635 gnutls_x509_crt_fmt_t format, void *output_data,
636 size_t * output_data_size)
638 if (crl == NULL)
640 gnutls_assert ();
641 return GNUTLS_E_INVALID_REQUEST;
644 return _gnutls_x509_export_int (crl->crl, format, PEM_CRL,
645 output_data, output_data_size);
649 * gnutls_x509_crl_export2:
650 * @crl: Holds the revocation list
651 * @format: the format of output params. One of PEM or DER.
652 * @out: will contain a private key PEM or DER encoded
654 * This function will export the revocation list to DER or PEM format.
656 * The output buffer is allocated using gnutls_malloc().
658 * If the structure is PEM encoded, it will have a header
659 * of "BEGIN X509 CRL".
661 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
662 * negative error value. and a negative error code on failure.
664 * Since 3.1.3
667 gnutls_x509_crl_export2 (gnutls_x509_crl_t crl,
668 gnutls_x509_crt_fmt_t format, gnutls_datum_t *out)
670 if (crl == NULL)
672 gnutls_assert ();
673 return GNUTLS_E_INVALID_REQUEST;
676 return _gnutls_x509_export_int2 (crl->crl, format, PEM_CRL, out);
680 * _gnutls_x509_crl_cpy - This function copies a gnutls_x509_crl_t structure
681 * @dest: The structure where to copy
682 * @src: The structure to be copied
684 * This function will copy an X.509 certificate structure.
686 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
687 * negative error value.
690 _gnutls_x509_crl_cpy (gnutls_x509_crl_t dest, gnutls_x509_crl_t src)
692 int ret;
693 gnutls_datum_t tmp;
695 ret = gnutls_x509_crl_export2 (src, GNUTLS_X509_FMT_DER, &tmp);
696 if (ret < 0)
697 return gnutls_assert_val(ret);
699 ret = gnutls_x509_crl_import (dest, &tmp, GNUTLS_X509_FMT_DER);
701 gnutls_free (tmp.data);
703 if (ret < 0)
705 gnutls_assert ();
706 return ret;
709 return 0;
713 static int
714 _get_authority_key_id (gnutls_x509_crl_t cert, ASN1_TYPE *c2,
715 unsigned int *critical)
717 int ret;
718 gnutls_datum_t id;
720 *c2 = ASN1_TYPE_EMPTY;
722 if (cert == NULL)
724 gnutls_assert ();
725 return GNUTLS_E_INVALID_REQUEST;
728 if ((ret =
729 _gnutls_x509_crl_get_extension (cert, "2.5.29.35", 0, &id,
730 critical)) < 0)
732 return gnutls_assert_val(ret);
735 if (id.size == 0 || id.data == NULL)
737 gnutls_assert ();
738 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
741 ret = asn1_create_element
742 (_gnutls_get_pkix (), "PKIX1.AuthorityKeyIdentifier", c2);
743 if (ret != ASN1_SUCCESS)
745 gnutls_assert ();
746 _gnutls_free_datum (&id);
747 return _gnutls_asn2err (ret);
750 ret = asn1_der_decoding (c2, id.data, id.size, NULL);
751 _gnutls_free_datum (&id);
753 if (ret != ASN1_SUCCESS)
755 gnutls_assert ();
756 asn1_delete_structure (c2);
757 return _gnutls_asn2err (ret);
760 return 0;
764 * gnutls_x509_crl_get_authority_key_gn_serial:
765 * @crl: should contain a #gnutls_x509_crl_t structure
766 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
767 * @alt: is the place where the alternative name will be copied to
768 * @alt_size: holds the size of alt.
769 * @alt_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
770 * @serial: buffer to store the serial number (may be null)
771 * @serial_size: Holds the size of the serial field (may be null)
772 * @critical: will be non-zero if the extension is marked as critical (may be null)
774 * This function will return the X.509 authority key
775 * identifier when stored as a general name (authorityCertIssuer)
776 * and serial number.
778 * Because more than one general names might be stored
779 * @seq can be used as a counter to request them all until
780 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
782 * Returns: Returns 0 on success, or an error code.
784 * Since: 3.0
787 gnutls_x509_crl_get_authority_key_gn_serial (gnutls_x509_crl_t crl,
788 unsigned int seq,
789 void *alt,
790 size_t * alt_size,
791 unsigned int *alt_type,
792 void* serial,
793 size_t *serial_size,
794 unsigned int *critical)
796 int ret, result, len;
797 ASN1_TYPE c2;
799 ret = _get_authority_key_id(crl, &c2, critical);
800 if (ret < 0)
801 return gnutls_assert_val(ret);
803 ret =
804 _gnutls_parse_general_name (c2, "authorityCertIssuer", seq, alt, alt_size, alt_type,
806 if (ret < 0)
808 ret = gnutls_assert_val(ret);
809 goto fail;
812 if (serial)
814 len = *serial_size;
815 result = asn1_read_value (c2, "authorityCertSerialNumber", serial, &len);
817 *serial_size = len;
819 if (result < 0)
821 ret = _gnutls_asn2err(result);
822 goto fail;
827 ret = 0;
829 fail:
830 asn1_delete_structure (&c2);
832 return ret;
837 * gnutls_x509_crl_get_authority_key_id:
838 * @crl: should contain a #gnutls_x509_crl_t structure
839 * @id: The place where the identifier will be copied
840 * @id_size: Holds the size of the result field.
841 * @critical: will be non-zero if the extension is marked as critical
842 * (may be null)
844 * This function will return the CRL authority's key identifier. This
845 * is obtained by the X.509 Authority Key identifier extension field
846 * (2.5.29.35). Note that this function
847 * only returns the keyIdentifier field of the extension and
848 * %GNUTLS_E_X509_UNSUPPORTED_EXTENSION, if the extension contains
849 * the name and serial number of the certificate. In that case
850 * gnutls_x509_crl_get_authority_key_gn_serial() may be used.
852 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
853 * negative error code in case of an error.
855 * Since: 2.8.0
858 gnutls_x509_crl_get_authority_key_id (gnutls_x509_crl_t crl, void *id,
859 size_t * id_size,
860 unsigned int *critical)
862 int result, len, ret;
863 ASN1_TYPE c2;
865 ret = _get_authority_key_id(crl, &c2, critical);
866 if (ret < 0)
867 return gnutls_assert_val(ret);
869 len = *id_size;
870 result = asn1_read_value (c2, "keyIdentifier", id, &len);
872 *id_size = len;
873 asn1_delete_structure (&c2);
875 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
876 return gnutls_assert_val(GNUTLS_E_X509_UNSUPPORTED_EXTENSION);
878 if (result != ASN1_SUCCESS)
880 gnutls_assert ();
881 return _gnutls_asn2err (result);
884 return 0;
888 * gnutls_x509_crl_get_number:
889 * @crl: should contain a #gnutls_x509_crl_t structure
890 * @ret: The place where the number will be copied
891 * @ret_size: Holds the size of the result field.
892 * @critical: will be non-zero if the extension is marked as critical
893 * (may be null)
895 * This function will return the CRL number extension. This is
896 * obtained by the CRL Number extension field (2.5.29.20).
898 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
899 * negative error code in case of an error.
901 * Since: 2.8.0
904 gnutls_x509_crl_get_number (gnutls_x509_crl_t crl, void *ret,
905 size_t * ret_size, unsigned int *critical)
907 int result;
908 gnutls_datum_t id;
910 if (crl == NULL)
912 gnutls_assert ();
913 return GNUTLS_E_INVALID_REQUEST;
917 if (ret)
918 memset (ret, 0, *ret_size);
919 else
920 *ret_size = 0;
922 if ((result =
923 _gnutls_x509_crl_get_extension (crl, "2.5.29.20", 0, &id,
924 critical)) < 0)
926 return result;
929 if (id.size == 0 || id.data == NULL)
931 gnutls_assert ();
932 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
935 result = _gnutls_x509_ext_extract_number (ret, ret_size, id.data, id.size);
937 _gnutls_free_datum (&id);
939 if (result < 0)
941 gnutls_assert ();
942 return result;
945 return 0;
949 * gnutls_x509_crl_get_extension_oid:
950 * @crl: should contain a #gnutls_x509_crl_t structure
951 * @indx: Specifies which extension OID to send, use (0) to get the first one.
952 * @oid: a pointer to a structure to hold the OID (may be null)
953 * @sizeof_oid: initially holds the size of @oid
955 * This function will return the requested extension OID in the CRL.
956 * The extension OID will be stored as a string in the provided
957 * buffer.
959 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
960 * negative error code in case of an error. If your have reached the
961 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
962 * will be returned.
964 * Since: 2.8.0
967 gnutls_x509_crl_get_extension_oid (gnutls_x509_crl_t crl, int indx,
968 void *oid, size_t * sizeof_oid)
970 int result;
972 if (crl == NULL)
974 gnutls_assert ();
975 return GNUTLS_E_INVALID_REQUEST;
978 result = _gnutls_x509_crl_get_extension_oid (crl, indx, oid, sizeof_oid);
979 if (result < 0)
981 return result;
984 return 0;
989 * gnutls_x509_crl_get_extension_info:
990 * @crl: should contain a #gnutls_x509_crl_t structure
991 * @indx: Specifies which extension OID to send, use (0) to get the first one.
992 * @oid: a pointer to a structure to hold the OID
993 * @sizeof_oid: initially holds the maximum size of @oid, on return
994 * holds actual size of @oid.
995 * @critical: output variable with critical flag, may be NULL.
997 * This function will return the requested extension OID in the CRL,
998 * and the critical flag for it. The extension OID will be stored as
999 * a string in the provided buffer. Use
1000 * gnutls_x509_crl_get_extension_data() to extract the data.
1002 * If the buffer provided is not long enough to hold the output, then
1003 * *@sizeof_oid is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
1004 * returned.
1006 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1007 * negative error code in case of an error. If your have reached the
1008 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1009 * will be returned.
1011 * Since: 2.8.0
1014 gnutls_x509_crl_get_extension_info (gnutls_x509_crl_t crl, int indx,
1015 void *oid, size_t * sizeof_oid,
1016 unsigned int *critical)
1018 int result;
1019 char str_critical[10];
1020 char name[ASN1_MAX_NAME_SIZE];
1021 int len;
1023 if (!crl)
1025 gnutls_assert ();
1026 return GNUTLS_E_INVALID_REQUEST;
1029 snprintf (name, sizeof (name), "tbsCertList.crlExtensions.?%u.extnID",
1030 indx + 1);
1032 len = *sizeof_oid;
1033 result = asn1_read_value (crl->crl, name, oid, &len);
1034 *sizeof_oid = len;
1036 if (result == ASN1_ELEMENT_NOT_FOUND)
1037 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1038 else if (result != ASN1_SUCCESS)
1040 gnutls_assert ();
1041 return _gnutls_asn2err (result);
1044 snprintf (name, sizeof (name), "tbsCertList.crlExtensions.?%u.critical",
1045 indx + 1);
1046 len = sizeof (str_critical);
1047 result = asn1_read_value (crl->crl, name, str_critical, &len);
1048 if (result != ASN1_SUCCESS)
1050 gnutls_assert ();
1051 return _gnutls_asn2err (result);
1054 if (critical)
1056 if (str_critical[0] == 'T')
1057 *critical = 1;
1058 else
1059 *critical = 0;
1062 return 0;
1067 * gnutls_x509_crl_get_extension_data:
1068 * @crl: should contain a #gnutls_x509_crl_t structure
1069 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
1070 * @data: a pointer to a structure to hold the data (may be null)
1071 * @sizeof_data: initially holds the size of @oid
1073 * This function will return the requested extension data in the CRL.
1074 * The extension data will be stored as a string in the provided
1075 * buffer.
1077 * Use gnutls_x509_crl_get_extension_info() to extract the OID and
1078 * critical flag. Use gnutls_x509_crl_get_extension_info() instead,
1079 * if you want to get data indexed by the extension OID rather than
1080 * sequence.
1082 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1083 * negative error code in case of an error. If your have reached the
1084 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1085 * will be returned.
1087 * Since: 2.8.0
1090 gnutls_x509_crl_get_extension_data (gnutls_x509_crl_t crl, int indx,
1091 void *data, size_t * sizeof_data)
1093 int result, len;
1094 char name[ASN1_MAX_NAME_SIZE];
1096 if (!crl)
1098 gnutls_assert ();
1099 return GNUTLS_E_INVALID_REQUEST;
1102 snprintf (name, sizeof (name), "tbsCertList.crlExtensions.?%u.extnValue",
1103 indx + 1);
1105 len = *sizeof_data;
1106 result = asn1_read_value (crl->crl, name, data, &len);
1107 *sizeof_data = len;
1109 if (result == ASN1_ELEMENT_NOT_FOUND)
1110 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1111 else if (result < 0)
1113 gnutls_assert ();
1114 return _gnutls_asn2err (result);
1117 return 0;
1121 * gnutls_x509_crl_list_import2:
1122 * @crls: The structures to store the parsed crl list. Must not be initialized.
1123 * @size: It will contain the size of the list.
1124 * @data: The PEM encoded CRL.
1125 * @format: One of DER or PEM.
1126 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
1128 * This function will convert the given PEM encoded CRL list
1129 * to the native gnutls_x509_crl_t format. The output will be stored
1130 * in @crls. They will be automatically initialized.
1132 * If the Certificate is PEM encoded it should have a header of "X509
1133 * CRL".
1135 * Returns: the number of certificates read or a negative error value.
1137 * Since: 3.0
1140 gnutls_x509_crl_list_import2 (gnutls_x509_crl_t ** crls,
1141 unsigned int * size,
1142 const gnutls_datum_t * data,
1143 gnutls_x509_crt_fmt_t format, unsigned int flags)
1145 unsigned int init = 1024;
1146 int ret;
1148 *crls = gnutls_malloc(sizeof(gnutls_x509_crl_t)*init);
1149 if (*crls == NULL)
1151 gnutls_assert();
1152 return GNUTLS_E_MEMORY_ERROR;
1155 ret = gnutls_x509_crl_list_import(*crls, &init, data, format, GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
1156 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
1158 *crls = gnutls_realloc_fast(*crls, sizeof(gnutls_x509_crl_t)*init);
1159 if (*crls == NULL)
1161 gnutls_assert();
1162 return GNUTLS_E_MEMORY_ERROR;
1165 ret = gnutls_x509_crl_list_import(*crls, &init, data, format, flags);
1168 if (ret < 0)
1170 gnutls_free(*crls);
1171 *crls = NULL;
1172 return ret;
1175 *size = init;
1176 return 0;
1180 * gnutls_x509_crl_list_import:
1181 * @crls: The structures to store the parsed CRLs. Must not be initialized.
1182 * @crl_max: Initially must hold the maximum number of crls. It will be updated with the number of crls available.
1183 * @data: The PEM encoded CRLs
1184 * @format: One of DER or PEM.
1185 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
1187 * This function will convert the given PEM encoded CRL list
1188 * to the native gnutls_x509_crl_t format. The output will be stored
1189 * in @crls. They will be automatically initialized.
1191 * If the Certificate is PEM encoded it should have a header of "X509 CRL".
1193 * Returns: the number of certificates read or a negative error value.
1195 * Since: 3.0
1198 gnutls_x509_crl_list_import (gnutls_x509_crl_t * crls,
1199 unsigned int *crl_max,
1200 const gnutls_datum_t * data,
1201 gnutls_x509_crt_fmt_t format, unsigned int flags)
1203 int size;
1204 const char *ptr;
1205 gnutls_datum_t tmp;
1206 int ret, nocopy = 0;
1207 unsigned int count = 0, j;
1209 if (format == GNUTLS_X509_FMT_DER)
1211 if (*crl_max < 1)
1213 *crl_max = 1;
1214 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1217 count = 1; /* import only the first one */
1219 ret = gnutls_x509_crl_init (&crls[0]);
1220 if (ret < 0)
1222 gnutls_assert ();
1223 goto error;
1226 ret = gnutls_x509_crl_import (crls[0], data, format);
1227 if (ret < 0)
1229 gnutls_assert ();
1230 goto error;
1233 *crl_max = 1;
1234 return 1;
1237 /* move to the certificate
1239 ptr = memmem (data->data, data->size,
1240 PEM_CRL_SEP, sizeof (PEM_CRL_SEP) - 1);
1241 if (ptr == NULL)
1243 gnutls_assert ();
1244 return GNUTLS_E_BASE64_DECODING_ERROR;
1247 count = 0;
1251 if (count >= *crl_max)
1253 if (!(flags & GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED))
1254 break;
1255 else
1256 nocopy = 1;
1259 if (!nocopy)
1261 ret = gnutls_x509_crl_init (&crls[count]);
1262 if (ret < 0)
1264 gnutls_assert ();
1265 goto error;
1268 tmp.data = (void *) ptr;
1269 tmp.size = data->size - (ptr - (char *) data->data);
1271 ret =
1272 gnutls_x509_crl_import (crls[count], &tmp, GNUTLS_X509_FMT_PEM);
1273 if (ret < 0)
1275 gnutls_assert ();
1276 goto error;
1280 /* now we move ptr after the pem header
1282 ptr++;
1283 /* find the next certificate (if any)
1285 size = data->size - (ptr - (char *) data->data);
1287 if (size > 0)
1289 ptr = memmem (ptr, size, PEM_CRL_SEP, sizeof (PEM_CRL_SEP) - 1);
1291 else
1292 ptr = NULL;
1294 count++;
1296 while (ptr != NULL);
1298 *crl_max = count;
1300 if (nocopy == 0)
1301 return count;
1302 else
1303 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1305 error:
1306 for (j = 0; j < count; j++)
1307 gnutls_x509_crl_deinit (crls[j]);
1308 return ret;