Correctly restore gnutls_record_recv() in DTLS mode if interrupted during the retrasm...
[gnutls.git] / lib / x509 / crl.c
blobcfd4b9305c78775df251cc28857b543f656071f5
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 uint8_t *out;
123 result = _gnutls_fbase64_decode (PEM_CRL, data->data, data->size, &out);
125 if (result <= 0)
127 if (result == 0)
128 result = GNUTLS_E_INTERNAL_ERROR;
129 gnutls_assert ();
130 return result;
133 _data.data = out;
134 _data.size = result;
136 need_free = 1;
140 result = asn1_der_decoding (&crl->crl, _data.data, _data.size, NULL);
141 if (result != ASN1_SUCCESS)
143 result = _gnutls_asn2err (result);
144 gnutls_assert ();
145 goto cleanup;
148 if (need_free)
149 _gnutls_free_datum (&_data);
151 return 0;
153 cleanup:
154 if (need_free)
155 _gnutls_free_datum (&_data);
156 return result;
161 * gnutls_x509_crl_get_issuer_dn:
162 * @crl: should contain a gnutls_x509_crl_t structure
163 * @buf: a pointer to a structure to hold the peer's name (may be null)
164 * @sizeof_buf: initially holds the size of @buf
166 * This function will copy the name of the CRL issuer in the provided
167 * buffer. The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
168 * described in RFC4514. The output string will be ASCII or UTF-8
169 * encoded, depending on the certificate data.
171 * If buf is %NULL then only the size will be filled.
173 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
174 * not long enough, and in that case the sizeof_buf will be updated
175 * with the required size, and 0 on success.
179 gnutls_x509_crl_get_issuer_dn (const gnutls_x509_crl_t crl, char *buf,
180 size_t * sizeof_buf)
182 if (crl == NULL)
184 gnutls_assert ();
185 return GNUTLS_E_INVALID_REQUEST;
188 return _gnutls_x509_parse_dn (crl->crl,
189 "tbsCertList.issuer.rdnSequence",
190 buf, sizeof_buf);
194 * gnutls_x509_crl_get_issuer_dn_by_oid:
195 * @crl: should contain a gnutls_x509_crl_t structure
196 * @oid: holds an Object Identified in null terminated string
197 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use (0) to get the first one.
198 * @raw_flag: If non (0) returns the raw DER data of the DN part.
199 * @buf: a pointer to a structure to hold the peer's name (may be null)
200 * @sizeof_buf: initially holds the size of @buf
202 * This function will extract the part of the name of the CRL issuer
203 * specified by the given OID. The output will be encoded as described
204 * in RFC4514. The output string will be ASCII or UTF-8 encoded,
205 * depending on the certificate data.
207 * Some helper macros with popular OIDs can be found in gnutls/x509.h
208 * If raw flag is (0), this function will only return known OIDs as
209 * text. Other OIDs will be DER encoded, as described in RFC4514 -- in
210 * hex format with a '#' prefix. You can check about known OIDs
211 * using gnutls_x509_dn_oid_known().
213 * If buf is null then only the size will be filled.
215 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
216 * not long enough, and in that case the sizeof_buf will be updated
217 * with the required size, and 0 on success.
220 gnutls_x509_crl_get_issuer_dn_by_oid (gnutls_x509_crl_t crl,
221 const char *oid, int indx,
222 unsigned int raw_flag, void *buf,
223 size_t * sizeof_buf)
225 if (crl == NULL)
227 gnutls_assert ();
228 return GNUTLS_E_INVALID_REQUEST;
231 return _gnutls_x509_parse_dn_oid (crl->crl,
232 "tbsCertList.issuer.rdnSequence",
233 oid, indx, raw_flag, buf, sizeof_buf);
237 * gnutls_x509_crl_get_dn_oid:
238 * @crl: should contain a gnutls_x509_crl_t structure
239 * @indx: Specifies which DN OID to send. Use (0) to get the first one.
240 * @oid: a pointer to a structure to hold the name (may be null)
241 * @sizeof_oid: initially holds the size of 'oid'
243 * This function will extract the requested OID of the name of the CRL
244 * issuer, specified by the given index.
246 * If oid is null then only the size will be filled.
248 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
249 * not long enough, and in that case the sizeof_oid will be updated
250 * with the required size. On success 0 is returned.
253 gnutls_x509_crl_get_dn_oid (gnutls_x509_crl_t crl,
254 int indx, void *oid, size_t * sizeof_oid)
256 if (crl == NULL)
258 gnutls_assert ();
259 return GNUTLS_E_INVALID_REQUEST;
262 return _gnutls_x509_get_dn_oid (crl->crl,
263 "tbsCertList.issuer.rdnSequence", indx,
264 oid, sizeof_oid);
269 * gnutls_x509_crl_get_signature_algorithm:
270 * @crl: should contain a #gnutls_x509_crl_t structure
272 * This function will return a value of the #gnutls_sign_algorithm_t
273 * enumeration that is the signature algorithm.
275 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
276 * negative error value.
279 gnutls_x509_crl_get_signature_algorithm (gnutls_x509_crl_t crl)
281 int result;
282 gnutls_datum_t sa;
284 if (crl == NULL)
286 gnutls_assert ();
287 return GNUTLS_E_INVALID_REQUEST;
290 /* Read the signature algorithm. Note that parameters are not
291 * read. They will be read from the issuer's certificate if needed.
294 result =
295 _gnutls_x509_read_value (crl->crl, "signatureAlgorithm.algorithm",
296 &sa, 0);
298 if (result < 0)
300 gnutls_assert ();
301 return result;
304 result = _gnutls_x509_oid2sign_algorithm ((const char *) sa.data);
306 _gnutls_free_datum (&sa);
308 return result;
312 * gnutls_x509_crl_get_signature:
313 * @crl: should contain a gnutls_x509_crl_t structure
314 * @sig: a pointer where the signature part will be copied (may be null).
315 * @sizeof_sig: initially holds the size of @sig
317 * This function will extract the signature field of a CRL.
319 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
320 * negative error value. and a negative error code on error.
323 gnutls_x509_crl_get_signature (gnutls_x509_crl_t crl,
324 char *sig, size_t * sizeof_sig)
326 int result;
327 unsigned int bits;
328 int len;
330 if (crl == NULL)
332 gnutls_assert ();
333 return GNUTLS_E_INVALID_REQUEST;
336 len = 0;
337 result = asn1_read_value (crl->crl, "signature", NULL, &len);
339 if (result != ASN1_MEM_ERROR)
341 gnutls_assert ();
342 return _gnutls_asn2err (result);
345 bits = len;
346 if (bits % 8 != 0)
348 gnutls_assert ();
349 return GNUTLS_E_CERTIFICATE_ERROR;
352 len = bits / 8;
354 if (*sizeof_sig < (unsigned)len)
356 *sizeof_sig = bits / 8;
357 return GNUTLS_E_SHORT_MEMORY_BUFFER;
360 result = asn1_read_value (crl->crl, "signature", sig, &len);
361 if (result != ASN1_SUCCESS)
363 gnutls_assert ();
364 return _gnutls_asn2err (result);
367 return 0;
371 * gnutls_x509_crl_get_version:
372 * @crl: should contain a #gnutls_x509_crl_t structure
374 * This function will return the version of the specified CRL.
376 * Returns: The version number, or a negative error code on error.
379 gnutls_x509_crl_get_version (gnutls_x509_crl_t crl)
381 uint8_t version[8];
382 int len, result;
384 if (crl == NULL)
386 gnutls_assert ();
387 return GNUTLS_E_INVALID_REQUEST;
390 len = sizeof (version);
391 if ((result =
392 asn1_read_value (crl->crl, "tbsCertList.version", version,
393 &len)) != ASN1_SUCCESS)
395 gnutls_assert ();
396 return _gnutls_asn2err (result);
399 return (int) version[0] + 1;
403 * gnutls_x509_crl_get_this_update:
404 * @crl: should contain a #gnutls_x509_crl_t structure
406 * This function will return the time this CRL was issued.
408 * Returns: when the CRL was issued, or (time_t)-1 on error.
410 time_t
411 gnutls_x509_crl_get_this_update (gnutls_x509_crl_t crl)
413 if (crl == NULL)
415 gnutls_assert ();
416 return (time_t) - 1;
419 return _gnutls_x509_get_time (crl->crl, "tbsCertList.thisUpdate", 0);
423 * gnutls_x509_crl_get_next_update:
424 * @crl: should contain a #gnutls_x509_crl_t structure
426 * This function will return the time the next CRL will be issued.
427 * This field is optional in a CRL so it might be normal to get an
428 * error instead.
430 * Returns: when the next CRL will be issued, or (time_t)-1 on error.
432 time_t
433 gnutls_x509_crl_get_next_update (gnutls_x509_crl_t crl)
435 if (crl == NULL)
437 gnutls_assert ();
438 return (time_t) - 1;
441 return _gnutls_x509_get_time (crl->crl, "tbsCertList.nextUpdate", 0);
445 * gnutls_x509_crl_get_crt_count:
446 * @crl: should contain a #gnutls_x509_crl_t structure
448 * This function will return the number of revoked certificates in the
449 * given CRL.
451 * Returns: number of certificates, a negative error code on failure.
454 gnutls_x509_crl_get_crt_count (gnutls_x509_crl_t crl)
457 int count, result;
459 if (crl == NULL)
461 gnutls_assert ();
462 return GNUTLS_E_INVALID_REQUEST;
465 result =
466 asn1_number_of_elements (crl->crl,
467 "tbsCertList.revokedCertificates", &count);
469 if (result != ASN1_SUCCESS)
471 gnutls_assert ();
472 return 0; /* no certificates */
475 return count;
479 * gnutls_x509_crl_get_crt_serial:
480 * @crl: should contain a #gnutls_x509_crl_t structure
481 * @indx: the index of the certificate to extract (starting from 0)
482 * @serial: where the serial number will be copied
483 * @serial_size: initially holds the size of serial
484 * @t: if non null, will hold the time this certificate was revoked
486 * This function will retrieve the serial number of the specified, by
487 * the index, revoked certificate.
489 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
490 * negative error value. and a negative error code on error.
493 gnutls_x509_crl_get_crt_serial (gnutls_x509_crl_t crl, int indx,
494 unsigned char *serial,
495 size_t * serial_size, time_t * t)
498 int result, _serial_size;
499 char serial_name[ASN1_MAX_NAME_SIZE];
500 char date_name[ASN1_MAX_NAME_SIZE];
502 if (crl == NULL)
504 gnutls_assert ();
505 return GNUTLS_E_INVALID_REQUEST;
508 snprintf (serial_name, sizeof (serial_name),
509 "tbsCertList.revokedCertificates.?%u.userCertificate", indx + 1);
510 snprintf (date_name, sizeof (date_name),
511 "tbsCertList.revokedCertificates.?%u.revocationDate", indx + 1);
513 _serial_size = *serial_size;
514 result = asn1_read_value (crl->crl, serial_name, serial, &_serial_size);
516 *serial_size = _serial_size;
517 if (result != ASN1_SUCCESS)
519 gnutls_assert ();
520 if (result == ASN1_ELEMENT_NOT_FOUND)
521 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
522 return _gnutls_asn2err (result);
525 if (t)
527 *t = _gnutls_x509_get_time (crl->crl, date_name, 0);
530 return 0;
534 * gnutls_x509_crl_get_raw_issuer_dn:
535 * @crl: should contain a gnutls_x509_crl_t structure
536 * @dn: will hold the starting point of the DN
538 * This function will return a pointer to the DER encoded DN structure
539 * and the length.
541 * Returns: a negative error code on error, and (0) on success.
543 * Since: 2.12.0
546 gnutls_x509_crl_get_raw_issuer_dn (gnutls_x509_crl_t crl,
547 gnutls_datum_t * dn)
549 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
550 int result, len1;
551 int start1, end1;
552 gnutls_datum_t crl_signed_data;
554 if (crl == NULL)
556 gnutls_assert ();
557 return GNUTLS_E_INVALID_REQUEST;
560 /* get the issuer of 'crl'
562 if ((result =
563 asn1_create_element (_gnutls_get_pkix (), "PKIX1.TBSCertList",
564 &c2)) != ASN1_SUCCESS)
566 gnutls_assert ();
567 return _gnutls_asn2err (result);
570 result =
571 _gnutls_x509_get_signed_data (crl->crl, "tbsCertList", &crl_signed_data);
572 if (result < 0)
574 gnutls_assert ();
575 goto cleanup;
578 result =
579 asn1_der_decoding (&c2, crl_signed_data.data, crl_signed_data.size, NULL);
580 if (result != ASN1_SUCCESS)
582 /* couldn't decode DER */
583 gnutls_assert ();
584 asn1_delete_structure (&c2);
585 result = _gnutls_asn2err (result);
586 goto cleanup;
589 result =
590 asn1_der_decoding_startEnd (c2, crl_signed_data.data,
591 crl_signed_data.size, "issuer",
592 &start1, &end1);
594 if (result != ASN1_SUCCESS)
596 gnutls_assert ();
597 result = _gnutls_asn2err (result);
598 goto cleanup;
601 len1 = end1 - start1 + 1;
603 _gnutls_set_datum (dn, &crl_signed_data.data[start1], len1);
605 result = 0;
607 cleanup:
608 asn1_delete_structure (&c2);
609 _gnutls_free_datum (&crl_signed_data);
610 return result;
614 * gnutls_x509_crl_export:
615 * @crl: Holds the revocation list
616 * @format: the format of output params. One of PEM or DER.
617 * @output_data: will contain a private key PEM or DER encoded
618 * @output_data_size: holds the size of output_data (and will
619 * be replaced by the actual size of parameters)
621 * This function will export the revocation list to DER or PEM format.
623 * If the buffer provided is not long enough to hold the output, then
624 * %GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
626 * If the structure is PEM encoded, it will have a header
627 * of "BEGIN X509 CRL".
629 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
630 * negative error value. and a negative error code on failure.
633 gnutls_x509_crl_export (gnutls_x509_crl_t crl,
634 gnutls_x509_crt_fmt_t format, void *output_data,
635 size_t * output_data_size)
637 if (crl == NULL)
639 gnutls_assert ();
640 return GNUTLS_E_INVALID_REQUEST;
643 return _gnutls_x509_export_int (crl->crl, format, PEM_CRL,
644 output_data, output_data_size);
648 * _gnutls_x509_crl_cpy - This function copies a gnutls_x509_crl_t structure
649 * @dest: The structure where to copy
650 * @src: The structure to be copied
652 * This function will copy an X.509 certificate structure.
654 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
655 * negative error value.
658 _gnutls_x509_crl_cpy (gnutls_x509_crl_t dest, gnutls_x509_crl_t src)
660 int ret;
661 size_t der_size;
662 uint8_t *der;
663 gnutls_datum_t tmp;
665 ret = gnutls_x509_crl_export (src, GNUTLS_X509_FMT_DER, NULL, &der_size);
666 if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
668 gnutls_assert ();
669 return ret;
672 der = gnutls_malloc (der_size);
673 if (der == NULL)
675 gnutls_assert ();
676 return GNUTLS_E_MEMORY_ERROR;
679 ret = gnutls_x509_crl_export (src, GNUTLS_X509_FMT_DER, der, &der_size);
680 if (ret < 0)
682 gnutls_assert ();
683 gnutls_free (der);
684 return ret;
687 tmp.data = der;
688 tmp.size = der_size;
689 ret = gnutls_x509_crl_import (dest, &tmp, GNUTLS_X509_FMT_DER);
691 gnutls_free (der);
693 if (ret < 0)
695 gnutls_assert ();
696 return ret;
699 return 0;
703 static int
704 _get_authority_key_id (gnutls_x509_crl_t cert, ASN1_TYPE *c2,
705 unsigned int *critical)
707 int ret;
708 gnutls_datum_t id;
710 *c2 = ASN1_TYPE_EMPTY;
712 if (cert == NULL)
714 gnutls_assert ();
715 return GNUTLS_E_INVALID_REQUEST;
718 if ((ret =
719 _gnutls_x509_crl_get_extension (cert, "2.5.29.35", 0, &id,
720 critical)) < 0)
722 return gnutls_assert_val(ret);
725 if (id.size == 0 || id.data == NULL)
727 gnutls_assert ();
728 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
731 ret = asn1_create_element
732 (_gnutls_get_pkix (), "PKIX1.AuthorityKeyIdentifier", c2);
733 if (ret != ASN1_SUCCESS)
735 gnutls_assert ();
736 _gnutls_free_datum (&id);
737 return _gnutls_asn2err (ret);
740 ret = asn1_der_decoding (c2, id.data, id.size, NULL);
741 _gnutls_free_datum (&id);
743 if (ret != ASN1_SUCCESS)
745 gnutls_assert ();
746 asn1_delete_structure (c2);
747 return _gnutls_asn2err (ret);
750 return 0;
754 * gnutls_x509_crl_get_authority_key_gn_serial:
755 * @crl: should contain a #gnutls_x509_crl_t structure
756 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
757 * @alt: is the place where the alternative name will be copied to
758 * @alt_size: holds the size of alt.
759 * @alt_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
760 * @serial: buffer to store the serial number (may be null)
761 * @serial_size: Holds the size of the serial field (may be null)
762 * @critical: will be non (0) if the extension is marked as critical (may be null)
764 * This function will return the X.509 authority key
765 * identifier when stored as a general name (authorityCertIssuer)
766 * and serial number.
768 * Because more than one general names might be stored
769 * @seq can be used as a counter to request them all until
770 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
772 * Returns: Returns 0 on success, or an error code.
774 * Since: 3.0
777 gnutls_x509_crl_get_authority_key_gn_serial (gnutls_x509_crl_t crl,
778 unsigned int seq,
779 void *alt,
780 size_t * alt_size,
781 unsigned int *alt_type,
782 void* serial,
783 size_t *serial_size,
784 unsigned int *critical)
786 int ret, result, len;
787 ASN1_TYPE c2;
789 ret = _get_authority_key_id(crl, &c2, critical);
790 if (ret < 0)
791 return gnutls_assert_val(ret);
793 ret =
794 _gnutls_parse_general_name (c2, "authorityCertIssuer", seq, alt, alt_size, alt_type,
796 if (ret < 0)
798 ret = gnutls_assert_val(ret);
799 goto fail;
802 if (serial)
804 len = *serial_size;
805 result = asn1_read_value (c2, "authorityCertSerialNumber", serial, &len);
807 *serial_size = len;
809 if (result < 0)
811 ret = _gnutls_asn2err(result);
812 goto fail;
817 ret = 0;
819 fail:
820 asn1_delete_structure (&c2);
822 return ret;
827 * gnutls_x509_crl_get_authority_key_id:
828 * @crl: should contain a #gnutls_x509_crl_t structure
829 * @id: The place where the identifier will be copied
830 * @id_size: Holds the size of the result field.
831 * @critical: will be non (0) if the extension is marked as critical
832 * (may be null)
834 * This function will return the CRL authority's key identifier. This
835 * is obtained by the X.509 Authority Key identifier extension field
836 * (2.5.29.35). Note that this function
837 * only returns the keyIdentifier field of the extension and
838 * %GNUTLS_E_X509_UNSUPPORTED_EXTENSION, if the extension contains
839 * the name and serial number of the certificate. In that case
840 * gnutls_x509_crl_get_authority_key_gn_serial() may be used.
842 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
843 * negative error code in case of an error.
845 * Since: 2.8.0
848 gnutls_x509_crl_get_authority_key_id (gnutls_x509_crl_t crl, void *id,
849 size_t * id_size,
850 unsigned int *critical)
852 int result, len, ret;
853 ASN1_TYPE c2;
855 ret = _get_authority_key_id(crl, &c2, critical);
856 if (ret < 0)
857 return gnutls_assert_val(ret);
859 len = *id_size;
860 result = asn1_read_value (c2, "keyIdentifier", id, &len);
862 *id_size = len;
863 asn1_delete_structure (&c2);
865 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
866 return gnutls_assert_val(GNUTLS_E_X509_UNSUPPORTED_EXTENSION);
868 if (result != ASN1_SUCCESS)
870 gnutls_assert ();
871 return _gnutls_asn2err (result);
874 return 0;
878 * gnutls_x509_crl_get_number:
879 * @crl: should contain a #gnutls_x509_crl_t structure
880 * @ret: The place where the number will be copied
881 * @ret_size: Holds the size of the result field.
882 * @critical: will be non (0) if the extension is marked as critical
883 * (may be null)
885 * This function will return the CRL number extension. This is
886 * obtained by the CRL Number extension field (2.5.29.20).
888 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
889 * negative error code in case of an error.
891 * Since: 2.8.0
894 gnutls_x509_crl_get_number (gnutls_x509_crl_t crl, void *ret,
895 size_t * ret_size, unsigned int *critical)
897 int result;
898 gnutls_datum_t id;
900 if (crl == NULL)
902 gnutls_assert ();
903 return GNUTLS_E_INVALID_REQUEST;
907 if (ret)
908 memset (ret, 0, *ret_size);
909 else
910 *ret_size = 0;
912 if ((result =
913 _gnutls_x509_crl_get_extension (crl, "2.5.29.20", 0, &id,
914 critical)) < 0)
916 return result;
919 if (id.size == 0 || id.data == NULL)
921 gnutls_assert ();
922 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
925 result = _gnutls_x509_ext_extract_number (ret, ret_size, id.data, id.size);
927 _gnutls_free_datum (&id);
929 if (result < 0)
931 gnutls_assert ();
932 return result;
935 return 0;
939 * gnutls_x509_crl_get_extension_oid:
940 * @crl: should contain a #gnutls_x509_crl_t structure
941 * @indx: Specifies which extension OID to send, use (0) to get the first one.
942 * @oid: a pointer to a structure to hold the OID (may be null)
943 * @sizeof_oid: initially holds the size of @oid
945 * This function will return the requested extension OID in the CRL.
946 * The extension OID will be stored as a string in the provided
947 * buffer.
949 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
950 * negative error code in case of an error. If your have reached the
951 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
952 * will be returned.
954 * Since: 2.8.0
957 gnutls_x509_crl_get_extension_oid (gnutls_x509_crl_t crl, int indx,
958 void *oid, size_t * sizeof_oid)
960 int result;
962 if (crl == NULL)
964 gnutls_assert ();
965 return GNUTLS_E_INVALID_REQUEST;
968 result = _gnutls_x509_crl_get_extension_oid (crl, indx, oid, sizeof_oid);
969 if (result < 0)
971 return result;
974 return 0;
979 * gnutls_x509_crl_get_extension_info:
980 * @crl: should contain a #gnutls_x509_crl_t structure
981 * @indx: Specifies which extension OID to send, use (0) to get the first one.
982 * @oid: a pointer to a structure to hold the OID
983 * @sizeof_oid: initially holds the maximum size of @oid, on return
984 * holds actual size of @oid.
985 * @critical: output variable with critical flag, may be NULL.
987 * This function will return the requested extension OID in the CRL,
988 * and the critical flag for it. The extension OID will be stored as
989 * a string in the provided buffer. Use
990 * gnutls_x509_crl_get_extension_data() to extract the data.
992 * If the buffer provided is not long enough to hold the output, then
993 * *@sizeof_oid is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
994 * returned.
996 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
997 * negative error code in case of an error. If your have reached the
998 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
999 * will be returned.
1001 * Since: 2.8.0
1004 gnutls_x509_crl_get_extension_info (gnutls_x509_crl_t crl, int indx,
1005 void *oid, size_t * sizeof_oid,
1006 unsigned int *critical)
1008 int result;
1009 char str_critical[10];
1010 char name[ASN1_MAX_NAME_SIZE];
1011 int len;
1013 if (!crl)
1015 gnutls_assert ();
1016 return GNUTLS_E_INVALID_REQUEST;
1019 snprintf (name, sizeof (name), "tbsCertList.crlExtensions.?%u.extnID",
1020 indx + 1);
1022 len = *sizeof_oid;
1023 result = asn1_read_value (crl->crl, name, oid, &len);
1024 *sizeof_oid = len;
1026 if (result == ASN1_ELEMENT_NOT_FOUND)
1027 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1028 else if (result != ASN1_SUCCESS)
1030 gnutls_assert ();
1031 return _gnutls_asn2err (result);
1034 snprintf (name, sizeof (name), "tbsCertList.crlExtensions.?%u.critical",
1035 indx + 1);
1036 len = sizeof (str_critical);
1037 result = asn1_read_value (crl->crl, name, str_critical, &len);
1038 if (result != ASN1_SUCCESS)
1040 gnutls_assert ();
1041 return _gnutls_asn2err (result);
1044 if (critical)
1046 if (str_critical[0] == 'T')
1047 *critical = 1;
1048 else
1049 *critical = 0;
1052 return 0;
1057 * gnutls_x509_crl_get_extension_data:
1058 * @crl: should contain a #gnutls_x509_crl_t structure
1059 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
1060 * @data: a pointer to a structure to hold the data (may be null)
1061 * @sizeof_data: initially holds the size of @oid
1063 * This function will return the requested extension data in the CRL.
1064 * The extension data will be stored as a string in the provided
1065 * buffer.
1067 * Use gnutls_x509_crl_get_extension_info() to extract the OID and
1068 * critical flag. Use gnutls_x509_crl_get_extension_info() instead,
1069 * if you want to get data indexed by the extension OID rather than
1070 * sequence.
1072 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1073 * negative error code in case of an error. If your have reached the
1074 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1075 * will be returned.
1077 * Since: 2.8.0
1080 gnutls_x509_crl_get_extension_data (gnutls_x509_crl_t crl, int indx,
1081 void *data, size_t * sizeof_data)
1083 int result, len;
1084 char name[ASN1_MAX_NAME_SIZE];
1086 if (!crl)
1088 gnutls_assert ();
1089 return GNUTLS_E_INVALID_REQUEST;
1092 snprintf (name, sizeof (name), "tbsCertList.crlExtensions.?%u.extnValue",
1093 indx + 1);
1095 len = *sizeof_data;
1096 result = asn1_read_value (crl->crl, name, data, &len);
1097 *sizeof_data = len;
1099 if (result == ASN1_ELEMENT_NOT_FOUND)
1100 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1101 else if (result < 0)
1103 gnutls_assert ();
1104 return _gnutls_asn2err (result);
1107 return 0;
1111 * gnutls_x509_crl_list_import2:
1112 * @crls: The structures to store the parsed crl list. Must not be initialized.
1113 * @size: It will contain the size of the list.
1114 * @data: The PEM encoded CRL.
1115 * @format: One of DER or PEM.
1116 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
1118 * This function will convert the given PEM encoded CRL list
1119 * to the native gnutls_x509_crl_t format. The output will be stored
1120 * in @crls. They will be automatically initialized.
1122 * If the Certificate is PEM encoded it should have a header of "X509
1123 * CRL".
1125 * Returns: the number of certificates read or a negative error value.
1127 * Since: 3.0
1130 gnutls_x509_crl_list_import2 (gnutls_x509_crl_t ** crls,
1131 unsigned int * size,
1132 const gnutls_datum_t * data,
1133 gnutls_x509_crt_fmt_t format, unsigned int flags)
1135 unsigned int init = 1024;
1136 int ret;
1138 *crls = gnutls_malloc(sizeof(gnutls_x509_crl_t)*init);
1139 if (*crls == NULL)
1141 gnutls_assert();
1142 return GNUTLS_E_MEMORY_ERROR;
1145 ret = gnutls_x509_crl_list_import(*crls, &init, data, format, GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
1146 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
1148 *crls = gnutls_realloc_fast(*crls, 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, flags);
1158 if (ret < 0)
1160 gnutls_free(*crls);
1161 *crls = NULL;
1162 return ret;
1165 *size = init;
1166 return 0;
1170 * gnutls_x509_crl_list_import:
1171 * @crls: The structures to store the parsed CRLs. Must not be initialized.
1172 * @crl_max: Initially must hold the maximum number of crls. It will be updated with the number of crls available.
1173 * @data: The PEM encoded CRLs
1174 * @format: One of DER or PEM.
1175 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
1177 * This function will convert the given PEM encoded CRL list
1178 * to the native gnutls_x509_crl_t format. The output will be stored
1179 * in @crls. They will be automatically initialized.
1181 * If the Certificate is PEM encoded it should have a header of "X509 CRL".
1183 * Returns: the number of certificates read or a negative error value.
1185 * Since: 3.0
1188 gnutls_x509_crl_list_import (gnutls_x509_crl_t * crls,
1189 unsigned int *crl_max,
1190 const gnutls_datum_t * data,
1191 gnutls_x509_crt_fmt_t format, unsigned int flags)
1193 int size;
1194 const char *ptr;
1195 gnutls_datum_t tmp;
1196 int ret, nocopy = 0;
1197 unsigned int count = 0, j;
1199 if (format == GNUTLS_X509_FMT_DER)
1201 if (*crl_max < 1)
1203 *crl_max = 1;
1204 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1207 count = 1; /* import only the first one */
1209 ret = gnutls_x509_crl_init (&crls[0]);
1210 if (ret < 0)
1212 gnutls_assert ();
1213 goto error;
1216 ret = gnutls_x509_crl_import (crls[0], data, format);
1217 if (ret < 0)
1219 gnutls_assert ();
1220 goto error;
1223 *crl_max = 1;
1224 return 1;
1227 /* move to the certificate
1229 ptr = memmem (data->data, data->size,
1230 PEM_CRL_SEP, sizeof (PEM_CRL_SEP) - 1);
1231 if (ptr == NULL)
1233 gnutls_assert ();
1234 return GNUTLS_E_BASE64_DECODING_ERROR;
1237 count = 0;
1241 if (count >= *crl_max)
1243 if (!(flags & GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED))
1244 break;
1245 else
1246 nocopy = 1;
1249 if (!nocopy)
1251 ret = gnutls_x509_crl_init (&crls[count]);
1252 if (ret < 0)
1254 gnutls_assert ();
1255 goto error;
1258 tmp.data = (void *) ptr;
1259 tmp.size = data->size - (ptr - (char *) data->data);
1261 ret =
1262 gnutls_x509_crl_import (crls[count], &tmp, GNUTLS_X509_FMT_PEM);
1263 if (ret < 0)
1265 gnutls_assert ();
1266 goto error;
1270 /* now we move ptr after the pem header
1272 ptr++;
1273 /* find the next certificate (if any)
1275 size = data->size - (ptr - (char *) data->data);
1277 if (size > 0)
1279 ptr = memmem (ptr, size, PEM_CRL_SEP, sizeof (PEM_CRL_SEP) - 1);
1281 else
1282 ptr = NULL;
1284 count++;
1286 while (ptr != NULL);
1288 *crl_max = count;
1290 if (nocopy == 0)
1291 return count;
1292 else
1293 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1295 error:
1296 for (j = 0; j < count; j++)
1297 gnutls_x509_crl_deinit (crls[j]);
1298 return ret;