1 /*
2  * Copyright (C) 2003-2016 Free Software Foundation, Inc.
3  * Copyright (C) 2015-2016 Red Hat, Inc.
4  *
5  * Author: Nikos Mavrogiannopoulos
6  *
7  * This file is part of GnuTLS.
8  *
9  * The GnuTLS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1 of
12  * the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this program.  If not, see <https://www.gnu.org/licenses/>
21  *
22  */
23 
24 #include "gnutls_int.h"
25 #include <libtasn1.h>
26 
27 #include <datum.h>
28 #include <global.h>
29 #include "errors.h"
30 #include <common.h>
31 #include <x509_b64.h>
32 #include <x509_int.h>
33 #include <x509.h>
34 
crl_reinit(gnutls_x509_crl_t crl)35 static int crl_reinit(gnutls_x509_crl_t crl)
36 {
37 int result;
38 
39 	if (crl->crl)
40 		asn1_delete_structure(&crl->crl);
41 
42 	result = asn1_create_element(_gnutls_get_pkix(),
43 				 "PKIX1.CertificateList",
44 				 &crl->crl);
45 	if (result != ASN1_SUCCESS) {
46 		gnutls_assert();
47 		return _gnutls_asn2err(result);
48 	}
49 	crl->rcache = NULL;
50 	crl->rcache_idx = 0;
51 	crl->raw_issuer_dn.size = 0;
52 
53 	return 0;
54 }
55 
56 /**
57  * gnutls_x509_crl_init:
58  * @crl: A pointer to the type to be initialized
59  *
60  * This function will initialize a CRL structure. CRL stands for
61  * Certificate Revocation List. A revocation list usually contains
62  * lists of certificate serial numbers that have been revoked by an
63  * Authority. The revocation lists are always signed with the
64  * authority's private key.
65  *
66  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
67  *   negative error value.
68  **/
gnutls_x509_crl_init(gnutls_x509_crl_t * crl)69 int gnutls_x509_crl_init(gnutls_x509_crl_t * crl)
70 {
71 	FAIL_IF_LIB_ERROR;
72 
73 	*crl = gnutls_calloc(1, sizeof(gnutls_x509_crl_int));
74 
75 	if (*crl) {
76 		int result = crl_reinit(*crl);
77 		if (result < 0) {
78 			gnutls_assert();
79 			gnutls_free(*crl);
80 			return result;
81 		}
82 		return 0;	/* success */
83 	}
84 	return GNUTLS_E_MEMORY_ERROR;
85 }
86 
87 /**
88  * gnutls_x509_crl_deinit:
89  * @crl: The data to be deinitialized
90  *
91  * This function will deinitialize a CRL structure.
92  **/
gnutls_x509_crl_deinit(gnutls_x509_crl_t crl)93 void gnutls_x509_crl_deinit(gnutls_x509_crl_t crl)
94 {
95 	if (!crl)
96 		return;
97 
98 	if (crl->crl)
99 		asn1_delete_structure(&crl->crl);
100 	gnutls_free(crl->der.data);
101 
102 	gnutls_free(crl);
103 }
104 
105 /**
106  * gnutls_x509_crl_import:
107  * @crl: The data to store the parsed CRL.
108  * @data: The DER or PEM encoded CRL.
109  * @format: One of DER or PEM
110  *
111  * This function will convert the given DER or PEM encoded CRL
112  * to the native #gnutls_x509_crl_t format. The output will be stored in 'crl'.
113  *
114  * If the CRL is PEM encoded it should have a header of "X509 CRL".
115  *
116  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
117  *   negative error value.
118  **/
119 int
gnutls_x509_crl_import(gnutls_x509_crl_t crl,const gnutls_datum_t * data,gnutls_x509_crt_fmt_t format)120 gnutls_x509_crl_import(gnutls_x509_crl_t crl,
121 		       const gnutls_datum_t * data,
122 		       gnutls_x509_crt_fmt_t format)
123 {
124 	int result = 0;
125 
126 	if (crl == NULL) {
127 		gnutls_assert();
128 		return GNUTLS_E_INVALID_REQUEST;
129 	}
130 
131 	_gnutls_free_datum(&crl->der);
132 
133 	/* If the CRL is in PEM format then decode it
134 	 */
135 	if (format == GNUTLS_X509_FMT_PEM) {
136 		result =
137 		    _gnutls_fbase64_decode(PEM_CRL, data->data, data->size,
138 					   &crl->der);
139 
140 		if (result < 0) {
141 			gnutls_assert();
142 			return result;
143 		}
144 	} else {
145 		result = _gnutls_set_datum(&crl->der, data->data, data->size);
146 		if (result < 0) {
147 			gnutls_assert();
148 			return result;
149 		}
150 	}
151 
152 	if (crl->expanded) {
153 		result = crl_reinit(crl);
154 		if (result < 0) {
155 			gnutls_assert();
156 			goto cleanup;
157 		}
158 	}
159 	crl->expanded = 1;
160 
161 	result =
162 	    _asn1_strict_der_decode(&crl->crl, crl->der.data, crl->der.size, NULL);
163 	if (result != ASN1_SUCCESS) {
164 		result = _gnutls_asn2err(result);
165 		gnutls_assert();
166 		goto cleanup;
167 	}
168 
169 	result = _gnutls_x509_get_raw_field2(crl->crl, &crl->der,
170 					  "tbsCertList.issuer.rdnSequence",
171 					  &crl->raw_issuer_dn);
172 	if (result < 0) {
173 		gnutls_assert();
174 		goto cleanup;
175 	}
176 
177 	return 0;
178 
179       cleanup:
180 	_gnutls_free_datum(&crl->der);
181 	return result;
182 }
183 
184 
185 /**
186  * gnutls_x509_crl_get_issuer_dn:
187  * @crl: should contain a gnutls_x509_crl_t type
188  * @buf: a pointer to a structure to hold the peer's name (may be null)
189  * @sizeof_buf: initially holds the size of @buf
190  *
191  * This function will copy the name of the CRL issuer in the provided
192  * buffer. The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
193  * described in RFC4514. The output string will be ASCII or UTF-8
194  * encoded, depending on the certificate data.
195  *
196  * If buf is %NULL then only the size will be filled.
197  *
198  * This function does not output a fully RFC4514 compliant string, if
199  * that is required see gnutls_x509_crl_get_issuer_dn3().
200  *
201  * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
202  * not long enough, and in that case the sizeof_buf will be updated
203  * with the required size, and 0 on success.
204  *
205  **/
206 int
gnutls_x509_crl_get_issuer_dn(gnutls_x509_crl_t crl,char * buf,size_t * sizeof_buf)207 gnutls_x509_crl_get_issuer_dn(gnutls_x509_crl_t crl, char *buf,
208 			      size_t * sizeof_buf)
209 {
210 	if (crl == NULL) {
211 		gnutls_assert();
212 		return GNUTLS_E_INVALID_REQUEST;
213 	}
214 
215 	return _gnutls_x509_parse_dn(crl->crl,
216 				     "tbsCertList.issuer.rdnSequence",
217 				     buf, sizeof_buf, GNUTLS_X509_DN_FLAG_COMPAT);
218 }
219 
220 /**
221  * gnutls_x509_crl_get_issuer_dn_by_oid:
222  * @crl: should contain a gnutls_x509_crl_t type
223  * @oid: holds an Object Identified in null terminated string
224  * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use (0) to get the first one.
225  * @raw_flag: If non-zero returns the raw DER data of the DN part.
226  * @buf: a pointer to a structure to hold the peer's name (may be null)
227  * @sizeof_buf: initially holds the size of @buf
228  *
229  * This function will extract the part of the name of the CRL issuer
230  * specified by the given OID. The output will be encoded as described
231  * in RFC4514. The output string will be ASCII or UTF-8 encoded,
232  * depending on the certificate data.
233  *
234  * Some helper macros with popular OIDs can be found in gnutls/x509.h
235  * If raw flag is (0), this function will only return known OIDs as
236  * text. Other OIDs will be DER encoded, as described in RFC4514 -- in
237  * hex format with a '#' prefix.  You can check about known OIDs
238  * using gnutls_x509_dn_oid_known().
239  *
240  * If buf is null then only the size will be filled.
241  *
242  * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
243  * not long enough, and in that case the sizeof_buf will be updated
244  * with the required size, and 0 on success.
245  **/
246 int
gnutls_x509_crl_get_issuer_dn_by_oid(gnutls_x509_crl_t crl,const char * oid,unsigned indx,unsigned int raw_flag,void * buf,size_t * sizeof_buf)247 gnutls_x509_crl_get_issuer_dn_by_oid(gnutls_x509_crl_t crl,
248 				     const char *oid, unsigned indx,
249 				     unsigned int raw_flag, void *buf,
250 				     size_t * sizeof_buf)
251 {
252 	gnutls_datum_t td;
253 	int ret;
254 
255 	if (crl == NULL) {
256 		gnutls_assert();
257 		return GNUTLS_E_INVALID_REQUEST;
258 	}
259 
260 	ret = _gnutls_x509_parse_dn_oid(crl->crl,
261 					"tbsCertList.issuer.rdnSequence",
262 					oid, indx, raw_flag, &td);
263 	if (ret < 0)
264 		return gnutls_assert_val(ret);
265 
266 	return _gnutls_strdatum_to_buf(&td, buf, sizeof_buf);
267 }
268 
269 
270 /**
271  * gnutls_x509_crl_get_dn_oid:
272  * @crl: should contain a gnutls_x509_crl_t type
273  * @indx: Specifies which DN OID to send. Use (0) to get the first one.
274  * @oid: a pointer to store the OID (may be null)
275  * @sizeof_oid: initially holds the size of 'oid'
276  *
277  * This function will extract the requested OID of the name of the CRL
278  * issuer, specified by the given index.
279  *
280  * If oid is null then only the size will be filled.
281  *
282  * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
283  * not long enough, and in that case the sizeof_oid will be updated
284  * with the required size.  On success 0 is returned.
285  **/
286 int
gnutls_x509_crl_get_dn_oid(gnutls_x509_crl_t crl,unsigned indx,void * oid,size_t * sizeof_oid)287 gnutls_x509_crl_get_dn_oid(gnutls_x509_crl_t crl,
288 			   unsigned indx, void *oid, size_t * sizeof_oid)
289 {
290 	if (crl == NULL) {
291 		gnutls_assert();
292 		return GNUTLS_E_INVALID_REQUEST;
293 	}
294 
295 	return _gnutls_x509_get_dn_oid(crl->crl,
296 				       "tbsCertList.issuer.rdnSequence",
297 				       indx, oid, sizeof_oid);
298 }
299 
300 /**
301  * gnutls_x509_crl_get_issuer_dn2:
302  * @crl: should contain a #gnutls_x509_crl_t type
303  * @dn: a pointer to a structure to hold the name
304  *
305  * This function will allocate buffer and copy the name of the CRL issuer.
306  * The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
307  * described in RFC4514. The output string will be ASCII or UTF-8
308  * encoded, depending on the certificate data.
309  *
310  * This function does not output a fully RFC4514 compliant string, if
311  * that is required see gnutls_x509_crl_get_issuer_dn3().
312  *
313  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
314  *   negative error value.
315  *
316  * Since: 3.1.10
317  **/
318 int
gnutls_x509_crl_get_issuer_dn2(gnutls_x509_crl_t crl,gnutls_datum_t * dn)319 gnutls_x509_crl_get_issuer_dn2(gnutls_x509_crl_t crl, gnutls_datum_t * dn)
320 {
321 	if (crl == NULL) {
322 		gnutls_assert();
323 		return GNUTLS_E_INVALID_REQUEST;
324 	}
325 
326 	return _gnutls_x509_get_dn(crl->crl,
327 				   "tbsCertList.issuer.rdnSequence",
328 				   dn, GNUTLS_X509_DN_FLAG_COMPAT);
329 }
330 
331 /**
332  * gnutls_x509_crl_get_issuer_dn3:
333  * @crl: should contain a #gnutls_x509_crl_t type
334  * @dn: a pointer to a structure to hold the name
335  * @flags: zero or %GNUTLS_X509_DN_FLAG_COMPAT
336  *
337  * This function will allocate buffer and copy the name of the CRL issuer.
338  * The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
339  * described in RFC4514. The output string will be ASCII or UTF-8
340  * encoded, depending on the certificate data.
341  *
342  * When the flag %GNUTLS_X509_DN_FLAG_COMPAT is specified, the output
343  * format will match the format output by previous to 3.5.6 versions of GnuTLS
344  * which was not not fully RFC4514-compliant.
345  *
346  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
347  *   negative error value.
348  *
349  * Since: 3.5.7
350  **/
351 int
gnutls_x509_crl_get_issuer_dn3(gnutls_x509_crl_t crl,gnutls_datum_t * dn,unsigned flags)352 gnutls_x509_crl_get_issuer_dn3(gnutls_x509_crl_t crl, gnutls_datum_t * dn, unsigned flags)
353 {
354 	if (crl == NULL) {
355 		gnutls_assert();
356 		return GNUTLS_E_INVALID_REQUEST;
357 	}
358 
359 	return _gnutls_x509_get_dn(crl->crl,
360 				   "tbsCertList.issuer.rdnSequence",
361 				   dn, flags);
362 }
363 
364 /**
365  * gnutls_x509_crl_get_signature_algorithm:
366  * @crl: should contain a #gnutls_x509_crl_t type
367  *
368  * This function will return a value of the #gnutls_sign_algorithm_t
369  * enumeration that is the signature algorithm.
370  *
371  * Since 3.6.0 this function never returns a negative error code.
372  * Error cases and unknown/unsupported signature algorithms are
373  * mapped to %GNUTLS_SIGN_UNKNOWN.
374  *
375  * Returns: a #gnutls_sign_algorithm_t value
376  **/
gnutls_x509_crl_get_signature_algorithm(gnutls_x509_crl_t crl)377 int gnutls_x509_crl_get_signature_algorithm(gnutls_x509_crl_t crl)
378 {
379 	return map_errs_to_zero(_gnutls_x509_get_signature_algorithm(crl->crl,
380 						    "signatureAlgorithm"));
381 }
382 
383 /**
384  * gnutls_x509_crl_get_signature_oid:
385  * @crl: should contain a #gnutls_x509_crl_t type
386  * @oid: a pointer to a buffer to hold the OID (may be null)
387  * @oid_size: initially holds the size of @oid
388  *
389  * This function will return the OID of the signature algorithm
390  * that has been used to sign this CRL. This is function
391  * is useful in the case gnutls_x509_crl_get_signature_algorithm()
392  * returned %GNUTLS_SIGN_UNKNOWN.
393  *
394  * Returns: zero or a negative error code on error.
395  *
396  * Since: 3.5.0
397  **/
gnutls_x509_crl_get_signature_oid(gnutls_x509_crl_t crl,char * oid,size_t * oid_size)398 int gnutls_x509_crl_get_signature_oid(gnutls_x509_crl_t crl, char *oid, size_t *oid_size)
399 {
400 	char str[MAX_OID_SIZE];
401 	int len, result, ret;
402 	gnutls_datum_t out;
403 
404 	len = sizeof(str);
405 	result = asn1_read_value(crl->crl, "signatureAlgorithm.algorithm", str, &len);
406 	if (result != ASN1_SUCCESS) {
407 		gnutls_assert();
408 		return _gnutls_asn2err(result);
409 	}
410 
411 	out.data = (void*)str;
412 	out.size = len;
413 
414 	ret = _gnutls_copy_string(&out, (void*)oid, oid_size);
415 	if (ret < 0) {
416 		gnutls_assert();
417 		return ret;
418 	}
419 
420 	return 0;
421 }
422 
423 /**
424  * gnutls_x509_crl_get_signature:
425  * @crl: should contain a gnutls_x509_crl_t type
426  * @sig: a pointer where the signature part will be copied (may be null).
427  * @sizeof_sig: initially holds the size of @sig
428  *
429  * This function will extract the signature field of a CRL.
430  *
431  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
432  *   negative error value.
433  **/
434 int
gnutls_x509_crl_get_signature(gnutls_x509_crl_t crl,char * sig,size_t * sizeof_sig)435 gnutls_x509_crl_get_signature(gnutls_x509_crl_t crl,
436 			      char *sig, size_t * sizeof_sig)
437 {
438 	int result;
439 	unsigned int bits;
440 	int len;
441 
442 	if (crl == NULL) {
443 		gnutls_assert();
444 		return GNUTLS_E_INVALID_REQUEST;
445 	}
446 
447 	len = 0;
448 	result = asn1_read_value(crl->crl, "signature", NULL, &len);
449 
450 	if (result != ASN1_MEM_ERROR) {
451 		gnutls_assert();
452 		return _gnutls_asn2err(result);
453 	}
454 
455 	bits = len;
456 	if (bits % 8 != 0) {
457 		gnutls_assert();
458 		return GNUTLS_E_CERTIFICATE_ERROR;
459 	}
460 
461 	len = bits / 8;
462 
463 	if (*sizeof_sig < (unsigned) len) {
464 		*sizeof_sig = bits / 8;
465 		return GNUTLS_E_SHORT_MEMORY_BUFFER;
466 	}
467 
468 	result = asn1_read_value(crl->crl, "signature", sig, &len);
469 	if (result != ASN1_SUCCESS) {
470 		gnutls_assert();
471 		return _gnutls_asn2err(result);
472 	}
473 
474 	return 0;
475 }
476 
477 /**
478  * gnutls_x509_crl_get_version:
479  * @crl: should contain a #gnutls_x509_crl_t type
480  *
481  * This function will return the version of the specified CRL.
482  *
483  * Returns: The version number, or a negative error code on error.
484  **/
gnutls_x509_crl_get_version(gnutls_x509_crl_t crl)485 int gnutls_x509_crl_get_version(gnutls_x509_crl_t crl)
486 {
487 	if (crl == NULL) {
488 		gnutls_assert();
489 		return GNUTLS_E_INVALID_REQUEST;
490 	}
491 
492 	return _gnutls_x509_get_version(crl->crl, "tbsCertList.version");
493 }
494 
495 /**
496  * gnutls_x509_crl_get_this_update:
497  * @crl: should contain a #gnutls_x509_crl_t type
498  *
499  * This function will return the time this CRL was issued.
500  *
501  * Returns: when the CRL was issued, or (time_t)-1 on error.
502  **/
gnutls_x509_crl_get_this_update(gnutls_x509_crl_t crl)503 time_t gnutls_x509_crl_get_this_update(gnutls_x509_crl_t crl)
504 {
505 	if (crl == NULL) {
506 		gnutls_assert();
507 		return (time_t) - 1;
508 	}
509 
510 	return _gnutls_x509_get_time(crl->crl, "tbsCertList.thisUpdate",
511 				     0);
512 }
513 
514 /**
515  * gnutls_x509_crl_get_next_update:
516  * @crl: should contain a #gnutls_x509_crl_t type
517  *
518  * This function will return the time the next CRL will be issued.
519  * This field is optional in a CRL so it might be normal to get an
520  * error instead.
521  *
522  * Returns: when the next CRL will be issued, or (time_t)-1 on error.
523  **/
gnutls_x509_crl_get_next_update(gnutls_x509_crl_t crl)524 time_t gnutls_x509_crl_get_next_update(gnutls_x509_crl_t crl)
525 {
526 	if (crl == NULL) {
527 		gnutls_assert();
528 		return (time_t) - 1;
529 	}
530 
531 	return _gnutls_x509_get_time(crl->crl, "tbsCertList.nextUpdate",
532 				     0);
533 }
534 
535 /**
536  * gnutls_x509_crl_get_crt_count:
537  * @crl: should contain a #gnutls_x509_crl_t type
538  *
539  * This function will return the number of revoked certificates in the
540  * given CRL.
541  *
542  * Returns: number of certificates, a negative error code on failure.
543  **/
gnutls_x509_crl_get_crt_count(gnutls_x509_crl_t crl)544 int gnutls_x509_crl_get_crt_count(gnutls_x509_crl_t crl)
545 {
546 
547 	int count, result;
548 
549 	if (crl == NULL) {
550 		gnutls_assert();
551 		return GNUTLS_E_INVALID_REQUEST;
552 	}
553 
554 	result =
555 	    asn1_number_of_elements(crl->crl,
556 				    "tbsCertList.revokedCertificates",
557 				    &count);
558 
559 	if (result != ASN1_SUCCESS) {
560 		gnutls_assert();
561 		return 0;	/* no certificates */
562 	}
563 
564 	return count;
565 }
566 
567 /**
568  * gnutls_x509_crl_get_crt_serial:
569  * @crl: should contain a #gnutls_x509_crl_t type
570  * @indx: the index of the certificate to extract (starting from 0)
571  * @serial: where the serial number will be copied
572  * @serial_size: initially holds the size of serial
573  * @t: if non null, will hold the time this certificate was revoked
574  *
575  * This function will retrieve the serial number of the specified, by
576  * the index, revoked certificate.
577  *
578  * Note that this function will have performance issues in large sequences
579  * of revoked certificates. In that case use gnutls_x509_crl_iter_crt_serial().
580  *
581  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
582  *   negative error value.
583  **/
584 int
gnutls_x509_crl_get_crt_serial(gnutls_x509_crl_t crl,unsigned indx,unsigned char * serial,size_t * serial_size,time_t * t)585 gnutls_x509_crl_get_crt_serial(gnutls_x509_crl_t crl, unsigned indx,
586 			       unsigned char *serial,
587 			       size_t * serial_size, time_t * t)
588 {
589 
590 	int result, _serial_size;
591 	char serial_name[MAX_NAME_SIZE];
592 	char date_name[MAX_NAME_SIZE];
593 
594 	if (crl == NULL) {
595 		gnutls_assert();
596 		return GNUTLS_E_INVALID_REQUEST;
597 	}
598 
599 	snprintf(serial_name, sizeof(serial_name),
600 		 "tbsCertList.revokedCertificates.?%u.userCertificate",
601 		 indx + 1);
602 	snprintf(date_name, sizeof(date_name),
603 		 "tbsCertList.revokedCertificates.?%u.revocationDate",
604 		 indx + 1);
605 
606 	_serial_size = *serial_size;
607 	result =
608 	    asn1_read_value(crl->crl, serial_name, serial, &_serial_size);
609 
610 	*serial_size = _serial_size;
611 	if (result != ASN1_SUCCESS) {
612 		gnutls_assert();
613 		if (result == ASN1_ELEMENT_NOT_FOUND)
614 			return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
615 		return _gnutls_asn2err(result);
616 	}
617 
618 	if (t) {
619 		*t = _gnutls_x509_get_time(crl->crl, date_name, 0);
620 	}
621 
622 	return 0;
623 }
624 
625 /**
626  * gnutls_x509_crl_iter_deinit:
627  * @iter: The iterator to be deinitialized
628  *
629  * This function will deinitialize an iterator type.
630  **/
gnutls_x509_crl_iter_deinit(gnutls_x509_crl_iter_t iter)631 void gnutls_x509_crl_iter_deinit(gnutls_x509_crl_iter_t iter)
632 {
633 	if (!iter)
634 		return;
635 
636 	gnutls_free(iter);
637 }
638 
639 /**
640  * gnutls_x509_crl_iter_crt_serial:
641  * @crl: should contain a #gnutls_x509_crl_t type
642  * @iter: A pointer to an iterator (initially the iterator should be %NULL)
643  * @serial: where the serial number will be copied
644  * @serial_size: initially holds the size of serial
645  * @t: if non null, will hold the time this certificate was revoked
646  *
647  * This function performs the same as gnutls_x509_crl_get_crt_serial(),
648  * but reads sequentially and keeps state in the iterator
649  * between calls. That allows it to provide better performance in sequences
650  * with many elements (50000+).
651  *
652  * When past the last element is accessed %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
653  * is returned and the iterator is reset.
654  *
655  * After use, the iterator must be deinitialized using gnutls_x509_crl_iter_deinit().
656  *
657  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
658  *   negative error value.
659  **/
660 int
gnutls_x509_crl_iter_crt_serial(gnutls_x509_crl_t crl,gnutls_x509_crl_iter_t * iter,unsigned char * serial,size_t * serial_size,time_t * t)661 gnutls_x509_crl_iter_crt_serial(gnutls_x509_crl_t crl,
662 				gnutls_x509_crl_iter_t *iter,
663 				unsigned char *serial,
664 				size_t * serial_size, time_t * t)
665 {
666 
667 	int result, _serial_size;
668 	char serial_name[MAX_NAME_SIZE];
669 	char date_name[MAX_NAME_SIZE];
670 
671 	if (crl == NULL || iter == NULL) {
672 		gnutls_assert();
673 		return GNUTLS_E_INVALID_REQUEST;
674 	}
675 
676 	if (*iter == NULL) {
677 		*iter = gnutls_calloc(1, sizeof(struct gnutls_x509_crl_iter));
678 		if (*iter == NULL)
679 			return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
680 	}
681 
682 	if ((*iter)->rcache == NULL) {
683 		(*iter)->rcache = asn1_find_node (crl->crl, "tbsCertList.revokedCertificates.?1");
684 		(*iter)->rcache_idx = 1;
685 	} else {
686 		snprintf(serial_name, sizeof(serial_name),
687 			 "?%d", (*iter)->rcache_idx);
688 		(*iter)->rcache = asn1_find_node ((*iter)->rcache, serial_name);
689 	}
690 	if ((*iter)->rcache == NULL) {
691 		/* reset */
692 		(*iter)->rcache = NULL;
693 		return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
694 	}
695 
696 	snprintf(serial_name, sizeof(serial_name),
697 		 "?%d.userCertificate", (*iter)->rcache_idx);
698 
699 	_serial_size = *serial_size;
700 	result =
701 	    asn1_read_value((*iter)->rcache, serial_name, serial, &_serial_size);
702 
703 	*serial_size = _serial_size;
704 	if (result != ASN1_SUCCESS) {
705 		gnutls_assert();
706 		if (result == ASN1_ELEMENT_NOT_FOUND) {
707 			/* reset */
708 			(*iter)->rcache = NULL;
709 			return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
710 		}
711 		return _gnutls_asn2err(result);
712 	}
713 
714 	if (t) {
715 		snprintf(date_name, sizeof(date_name),
716 			 "?%d.revocationDate", (*iter)->rcache_idx);
717 		*t = _gnutls_x509_get_time((*iter)->rcache, date_name, 0);
718 	}
719 
720 	(*iter)->rcache_idx++;
721 
722 	return 0;
723 }
724 
725 /**
726  * gnutls_x509_crl_get_raw_issuer_dn:
727  * @crl: should contain a gnutls_x509_crl_t type
728  * @dn: will hold the starting point of the DN
729  *
730  * This function will return a pointer to the DER encoded DN structure
731  * and the length.
732  *
733  * Returns: a negative error code on error, and (0) on success.
734  *
735  * Since: 2.12.0
736  **/
737 int
gnutls_x509_crl_get_raw_issuer_dn(gnutls_x509_crl_t crl,gnutls_datum_t * dn)738 gnutls_x509_crl_get_raw_issuer_dn(gnutls_x509_crl_t crl,
739 				  gnutls_datum_t * dn)
740 {
741 	if (crl->raw_issuer_dn.size != 0) {
742 		return _gnutls_set_datum(dn, crl->raw_issuer_dn.data,
743 					 crl->raw_issuer_dn.size);
744 	} else {
745 		return _gnutls_x509_get_raw_field(crl->crl, "tbsCertList.issuer.rdnSequence", dn);
746 	}
747 }
748 
749 /**
750  * gnutls_x509_crl_export:
751  * @crl: Holds the revocation list
752  * @format: the format of output params. One of PEM or DER.
753  * @output_data: will contain a private key PEM or DER encoded
754  * @output_data_size: holds the size of output_data (and will
755  *   be replaced by the actual size of parameters)
756  *
757  * This function will export the revocation list to DER or PEM format.
758  *
759  * If the buffer provided is not long enough to hold the output, then
760  * %GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
761  *
762  * If the structure is PEM encoded, it will have a header
763  * of "BEGIN X509 CRL".
764  *
765  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
766  *   negative error value.
767  **/
768 int
gnutls_x509_crl_export(gnutls_x509_crl_t crl,gnutls_x509_crt_fmt_t format,void * output_data,size_t * output_data_size)769 gnutls_x509_crl_export(gnutls_x509_crl_t crl,
770 		       gnutls_x509_crt_fmt_t format, void *output_data,
771 		       size_t * output_data_size)
772 {
773 	if (crl == NULL) {
774 		gnutls_assert();
775 		return GNUTLS_E_INVALID_REQUEST;
776 	}
777 
778 	return _gnutls_x509_export_int(crl->crl, format, PEM_CRL,
779 				       output_data, output_data_size);
780 }
781 
782 /**
783  * gnutls_x509_crl_export2:
784  * @crl: Holds the revocation list
785  * @format: the format of output params. One of PEM or DER.
786  * @out: will contain a private key PEM or DER encoded
787  *
788  * This function will export the revocation list to DER or PEM format.
789  *
790  * The output buffer is allocated using gnutls_malloc().
791  *
792  * If the structure is PEM encoded, it will have a header
793  * of "BEGIN X509 CRL".
794  *
795  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
796  *   negative error value.
797  *
798  * Since 3.1.3
799  **/
800 int
gnutls_x509_crl_export2(gnutls_x509_crl_t crl,gnutls_x509_crt_fmt_t format,gnutls_datum_t * out)801 gnutls_x509_crl_export2(gnutls_x509_crl_t crl,
802 			gnutls_x509_crt_fmt_t format, gnutls_datum_t * out)
803 {
804 	if (crl == NULL) {
805 		gnutls_assert();
806 		return GNUTLS_E_INVALID_REQUEST;
807 	}
808 
809 	return _gnutls_x509_export_int2(crl->crl, format, PEM_CRL, out);
810 }
811 
812 /*-
813  * _gnutls_x509_crl_cpy - This function copies a gnutls_x509_crl_t type
814  * @dest: The data where to copy
815  * @src: The data to be copied
816  *
817  * This function will copy an X.509 certificate structure.
818  *
819  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
820  *   negative error value.
821  -*/
_gnutls_x509_crl_cpy(gnutls_x509_crl_t dest,gnutls_x509_crl_t src)822 int _gnutls_x509_crl_cpy(gnutls_x509_crl_t dest, gnutls_x509_crl_t src)
823 {
824 	int ret;
825 	gnutls_datum_t tmp;
826 
827 	ret = gnutls_x509_crl_export2(src, GNUTLS_X509_FMT_DER, &tmp);
828 	if (ret < 0)
829 		return gnutls_assert_val(ret);
830 
831 	ret = gnutls_x509_crl_import(dest, &tmp, GNUTLS_X509_FMT_DER);
832 
833 	gnutls_free(tmp.data);
834 
835 	if (ret < 0) {
836 		gnutls_assert();
837 		return ret;
838 	}
839 
840 	return 0;
841 
842 }
843 
844 static int
_get_authority_key_id(gnutls_x509_crl_t cert,ASN1_TYPE * c2,unsigned int * critical)845 _get_authority_key_id(gnutls_x509_crl_t cert, ASN1_TYPE * c2,
846 		      unsigned int *critical)
847 {
848 	int ret;
849 	gnutls_datum_t id;
850 
851 	*c2 = ASN1_TYPE_EMPTY;
852 
853 	if (cert == NULL) {
854 		gnutls_assert();
855 		return GNUTLS_E_INVALID_REQUEST;
856 	}
857 
858 	if ((ret =
859 	     _gnutls_x509_crl_get_extension(cert, "2.5.29.35", 0, &id,
860 					    critical)) < 0) {
861 		return gnutls_assert_val(ret);
862 	}
863 
864 	if (id.size == 0 || id.data == NULL) {
865 		gnutls_assert();
866 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
867 	}
868 
869 	ret = asn1_create_element
870 	    (_gnutls_get_pkix(), "PKIX1.AuthorityKeyIdentifier", c2);
871 	if (ret != ASN1_SUCCESS) {
872 		gnutls_assert();
873 		_gnutls_free_datum(&id);
874 		return _gnutls_asn2err(ret);
875 	}
876 
877 	ret = _asn1_strict_der_decode(c2, id.data, id.size, NULL);
878 	_gnutls_free_datum(&id);
879 
880 	if (ret != ASN1_SUCCESS) {
881 		gnutls_assert();
882 		asn1_delete_structure(c2);
883 		return _gnutls_asn2err(ret);
884 	}
885 
886 	return 0;
887 }
888 
889 /**
890  * gnutls_x509_crl_get_authority_key_gn_serial:
891  * @crl: should contain a #gnutls_x509_crl_t type
892  * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
893  * @alt: is the place where the alternative name will be copied to
894  * @alt_size: holds the size of alt.
895  * @alt_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
896  * @serial: buffer to store the serial number (may be null)
897  * @serial_size: Holds the size of the serial field (may be null)
898  * @critical: will be non-zero if the extension is marked as critical (may be null)
899  *
900  * This function will return the X.509 authority key
901  * identifier when stored as a general name (authorityCertIssuer)
902  * and serial number.
903  *
904  * Because more than one general names might be stored
905  * @seq can be used as a counter to request them all until
906  * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
907  *
908  * Returns: Returns 0 on success, or an error code.
909  *
910  * Since: 3.0
911  **/
912 int
gnutls_x509_crl_get_authority_key_gn_serial(gnutls_x509_crl_t crl,unsigned int seq,void * alt,size_t * alt_size,unsigned int * alt_type,void * serial,size_t * serial_size,unsigned int * critical)913 gnutls_x509_crl_get_authority_key_gn_serial(gnutls_x509_crl_t crl,
914 					    unsigned int seq,
915 					    void *alt,
916 					    size_t * alt_size,
917 					    unsigned int *alt_type,
918 					    void *serial,
919 					    size_t * serial_size,
920 					    unsigned int *critical)
921 {
922 	int ret, result, len;
923 	ASN1_TYPE c2;
924 
925 	ret = _get_authority_key_id(crl, &c2, critical);
926 	if (ret < 0)
927 		return gnutls_assert_val(ret);
928 
929 	ret =
930 	    _gnutls_parse_general_name(c2, "authorityCertIssuer", seq, alt,
931 				       alt_size, alt_type, 0);
932 	if (ret < 0) {
933 		ret = gnutls_assert_val(ret);
934 		goto fail;
935 	}
936 
937 	if (serial) {
938 		len = *serial_size;
939 		result =
940 		    asn1_read_value(c2, "authorityCertSerialNumber",
941 				    serial, &len);
942 
943 		*serial_size = len;
944 
945 		if (result < 0) {
946 			ret = _gnutls_asn2err(result);
947 			goto fail;
948 		}
949 
950 	}
951 
952 	ret = 0;
953 
954       fail:
955 	asn1_delete_structure(&c2);
956 
957 	return ret;
958 }
959 
960 
961 /**
962  * gnutls_x509_crl_get_authority_key_id:
963  * @crl: should contain a #gnutls_x509_crl_t type
964  * @id: The place where the identifier will be copied
965  * @id_size: Holds the size of the result field.
966  * @critical: will be non-zero if the extension is marked as critical
967  *   (may be null)
968  *
969  * This function will return the CRL authority's key identifier.  This
970  * is obtained by the X.509 Authority Key identifier extension field
971  * (2.5.29.35).  Note that this function
972  * only returns the keyIdentifier field of the extension and
973  * %GNUTLS_E_X509_UNSUPPORTED_EXTENSION, if the extension contains
974  * the name and serial number of the certificate. In that case
975  * gnutls_x509_crl_get_authority_key_gn_serial() may be used.
976  *
977  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
978  *   negative error code in case of an error.
979  *
980  * Since: 2.8.0
981  **/
982 int
gnutls_x509_crl_get_authority_key_id(gnutls_x509_crl_t crl,void * id,size_t * id_size,unsigned int * critical)983 gnutls_x509_crl_get_authority_key_id(gnutls_x509_crl_t crl, void *id,
984 				     size_t * id_size,
985 				     unsigned int *critical)
986 {
987 	int result, len, ret;
988 	ASN1_TYPE c2;
989 
990 	ret = _get_authority_key_id(crl, &c2, critical);
991 	if (ret < 0)
992 		return gnutls_assert_val(ret);
993 
994 	len = *id_size;
995 	result = asn1_read_value(c2, "keyIdentifier", id, &len);
996 
997 	*id_size = len;
998 	asn1_delete_structure(&c2);
999 
1000 	if (result == ASN1_VALUE_NOT_FOUND
1001 	    || result == ASN1_ELEMENT_NOT_FOUND)
1002 		return
1003 		    gnutls_assert_val(GNUTLS_E_X509_UNSUPPORTED_EXTENSION);
1004 
1005 	if (result != ASN1_SUCCESS) {
1006 		gnutls_assert();
1007 		return _gnutls_asn2err(result);
1008 	}
1009 
1010 	return 0;
1011 }
1012 
1013 /**
1014  * gnutls_x509_crl_get_number:
1015  * @crl: should contain a #gnutls_x509_crl_t type
1016  * @ret: The place where the number will be copied
1017  * @ret_size: Holds the size of the result field.
1018  * @critical: will be non-zero if the extension is marked as critical
1019  *   (may be null)
1020  *
1021  * This function will return the CRL number extension.  This is
1022  * obtained by the CRL Number extension field (2.5.29.20).
1023  *
1024  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1025  *   negative error code in case of an error.
1026  *
1027  * Since: 2.8.0
1028  **/
1029 int
gnutls_x509_crl_get_number(gnutls_x509_crl_t crl,void * ret,size_t * ret_size,unsigned int * critical)1030 gnutls_x509_crl_get_number(gnutls_x509_crl_t crl, void *ret,
1031 			   size_t * ret_size, unsigned int *critical)
1032 {
1033 	int result;
1034 	gnutls_datum_t id;
1035 
1036 	if (crl == NULL) {
1037 		gnutls_assert();
1038 		return GNUTLS_E_INVALID_REQUEST;
1039 	}
1040 
1041 	if (ret)
1042 		memset(ret, 0, *ret_size);
1043 	else
1044 		*ret_size = 0;
1045 
1046 	if ((result =
1047 	     _gnutls_x509_crl_get_extension(crl, "2.5.29.20", 0, &id,
1048 					    critical)) < 0) {
1049 		return result;
1050 	}
1051 
1052 	if (id.size == 0 || id.data == NULL) {
1053 		gnutls_assert();
1054 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1055 	}
1056 
1057 	result =
1058 	    _gnutls_x509_ext_extract_number(ret, ret_size, id.data,
1059 					    id.size);
1060 
1061 	_gnutls_free_datum(&id);
1062 
1063 	if (result < 0) {
1064 		gnutls_assert();
1065 		return result;
1066 	}
1067 
1068 	return 0;
1069 }
1070 
1071 /**
1072  * gnutls_x509_crl_get_extension_oid:
1073  * @crl: should contain a #gnutls_x509_crl_t type
1074  * @indx: Specifies which extension OID to send, use (0) to get the first one.
1075  * @oid: a pointer to store the OID (may be null)
1076  * @sizeof_oid: initially holds the size of @oid
1077  *
1078  * This function will return the requested extension OID in the CRL.
1079  * The extension OID will be stored as a string in the provided
1080  * buffer.
1081  *
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.
1086  *
1087  * Since: 2.8.0
1088  **/
1089 int
gnutls_x509_crl_get_extension_oid(gnutls_x509_crl_t crl,unsigned indx,void * oid,size_t * sizeof_oid)1090 gnutls_x509_crl_get_extension_oid(gnutls_x509_crl_t crl, unsigned indx,
1091 				  void *oid, size_t * sizeof_oid)
1092 {
1093 	int result;
1094 
1095 	if (crl == NULL) {
1096 		gnutls_assert();
1097 		return GNUTLS_E_INVALID_REQUEST;
1098 	}
1099 
1100 	result =
1101 	    _gnutls_x509_crl_get_extension_oid(crl, indx, oid, sizeof_oid);
1102 	if (result < 0) {
1103 		return result;
1104 	}
1105 
1106 	return 0;
1107 
1108 }
1109 
1110 /**
1111  * gnutls_x509_crl_get_extension_info:
1112  * @crl: should contain a #gnutls_x509_crl_t type
1113  * @indx: Specifies which extension OID to send, use (0) to get the first one.
1114  * @oid: a pointer to store the OID
1115  * @sizeof_oid: initially holds the maximum size of @oid, on return
1116  *   holds actual size of @oid.
1117  * @critical: output variable with critical flag, may be NULL.
1118  *
1119  * This function will return the requested extension OID in the CRL,
1120  * and the critical flag for it.  The extension OID will be stored as
1121  * a string in the provided buffer.  Use
1122  * gnutls_x509_crl_get_extension_data() to extract the data.
1123  *
1124  * If the buffer provided is not long enough to hold the output, then
1125  * *@sizeof_oid is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
1126  * returned.
1127  *
1128  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1129  *   negative error code in case of an error.  If your have reached the
1130  *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1131  *   will be returned.
1132  *
1133  * Since: 2.8.0
1134  **/
1135 int
gnutls_x509_crl_get_extension_info(gnutls_x509_crl_t crl,unsigned indx,void * oid,size_t * sizeof_oid,unsigned int * critical)1136 gnutls_x509_crl_get_extension_info(gnutls_x509_crl_t crl, unsigned indx,
1137 				   void *oid, size_t * sizeof_oid,
1138 				   unsigned int *critical)
1139 {
1140 	int result;
1141 	char str_critical[10];
1142 	char name[MAX_NAME_SIZE];
1143 	int len;
1144 
1145 	if (!crl) {
1146 		gnutls_assert();
1147 		return GNUTLS_E_INVALID_REQUEST;
1148 	}
1149 
1150 	snprintf(name, sizeof(name),
1151 		 "tbsCertList.crlExtensions.?%u.extnID", indx + 1);
1152 
1153 	len = *sizeof_oid;
1154 	result = asn1_read_value(crl->crl, name, oid, &len);
1155 	*sizeof_oid = len;
1156 
1157 	if (result == ASN1_ELEMENT_NOT_FOUND)
1158 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1159 	else if (result != ASN1_SUCCESS) {
1160 		gnutls_assert();
1161 		return _gnutls_asn2err(result);
1162 	}
1163 
1164 	snprintf(name, sizeof(name),
1165 		 "tbsCertList.crlExtensions.?%u.critical", indx + 1);
1166 	len = sizeof(str_critical);
1167 	result = asn1_read_value(crl->crl, name, str_critical, &len);
1168 	if (result != ASN1_SUCCESS) {
1169 		gnutls_assert();
1170 		return _gnutls_asn2err(result);
1171 	}
1172 
1173 	if (critical) {
1174 		if (str_critical[0] == 'T')
1175 			*critical = 1;
1176 		else
1177 			*critical = 0;
1178 	}
1179 
1180 	return 0;
1181 
1182 }
1183 
1184 /**
1185  * gnutls_x509_crl_get_extension_data:
1186  * @crl: should contain a #gnutls_x509_crl_t type
1187  * @indx: Specifies which extension OID to send. Use (0) to get the first one.
1188  * @data: a pointer to a structure to hold the data (may be null)
1189  * @sizeof_data: initially holds the size of @oid
1190  *
1191  * This function will return the requested extension data in the CRL.
1192  * The extension data will be stored as a string in the provided
1193  * buffer.
1194  *
1195  * Use gnutls_x509_crl_get_extension_info() to extract the OID and
1196  * critical flag.  Use gnutls_x509_crl_get_extension_info() instead,
1197  * if you want to get data indexed by the extension OID rather than
1198  * sequence.
1199  *
1200  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1201  *   negative error code in case of an error.  If your have reached the
1202  *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1203  *   will be returned.
1204  *
1205  * Since: 2.8.0
1206  **/
1207 int
gnutls_x509_crl_get_extension_data(gnutls_x509_crl_t crl,unsigned indx,void * data,size_t * sizeof_data)1208 gnutls_x509_crl_get_extension_data(gnutls_x509_crl_t crl, unsigned indx,
1209 				   void *data, size_t * sizeof_data)
1210 {
1211 	int result, len;
1212 	char name[MAX_NAME_SIZE];
1213 
1214 	if (!crl) {
1215 		gnutls_assert();
1216 		return GNUTLS_E_INVALID_REQUEST;
1217 	}
1218 
1219 	snprintf(name, sizeof(name),
1220 		 "tbsCertList.crlExtensions.?%u.extnValue", indx + 1);
1221 
1222 	len = *sizeof_data;
1223 	result = asn1_read_value(crl->crl, name, data, &len);
1224 	*sizeof_data = len;
1225 
1226 	if (result == ASN1_ELEMENT_NOT_FOUND)
1227 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1228 	else if (result < 0) {
1229 		gnutls_assert();
1230 		return _gnutls_asn2err(result);
1231 	}
1232 
1233 	return 0;
1234 }
1235 
1236 /**
1237  * gnutls_x509_crl_list_import2:
1238  * @crls: Will contain the parsed crl list.
1239  * @size: It will contain the size of the list.
1240  * @data: The PEM encoded CRL.
1241  * @format: One of DER or PEM.
1242  * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
1243  *
1244  * This function will convert the given PEM encoded CRL list
1245  * to the native gnutls_x509_crl_t format. The output will be stored
1246  * in @crls.  They will be automatically initialized.
1247  *
1248  * If the Certificate is PEM encoded it should have a header of "X509
1249  * CRL".
1250  *
1251  * Returns: the number of certificates read or a negative error value.
1252  *
1253  * Since: 3.0
1254  **/
1255 int
gnutls_x509_crl_list_import2(gnutls_x509_crl_t ** crls,unsigned int * size,const gnutls_datum_t * data,gnutls_x509_crt_fmt_t format,unsigned int flags)1256 gnutls_x509_crl_list_import2(gnutls_x509_crl_t ** crls,
1257 			     unsigned int *size,
1258 			     const gnutls_datum_t * data,
1259 			     gnutls_x509_crt_fmt_t format,
1260 			     unsigned int flags)
1261 {
1262 	unsigned int init = 1024;
1263 	int ret;
1264 
1265 	*crls = gnutls_malloc(sizeof(gnutls_x509_crl_t) * init);
1266 	if (*crls == NULL) {
1267 		gnutls_assert();
1268 		return GNUTLS_E_MEMORY_ERROR;
1269 	}
1270 
1271 	ret =
1272 	    gnutls_x509_crl_list_import(*crls, &init, data, format,
1273 					flags | GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
1274 	if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
1275 		*crls =
1276 		    gnutls_realloc_fast(*crls,
1277 					sizeof(gnutls_x509_crl_t) * init);
1278 		if (*crls == NULL) {
1279 			gnutls_assert();
1280 			return GNUTLS_E_MEMORY_ERROR;
1281 		}
1282 
1283 		ret =
1284 		    gnutls_x509_crl_list_import(*crls, &init, data, format,
1285 						flags);
1286 	}
1287 
1288 	if (ret < 0) {
1289 		gnutls_free(*crls);
1290 		*crls = NULL;
1291 		return ret;
1292 	}
1293 
1294 	*size = init;
1295 	return 0;
1296 }
1297 
1298 /**
1299  * gnutls_x509_crl_list_import:
1300  * @crls: Indicates where the parsed CRLs will be copied to. Must not be initialized.
1301  * @crl_max: Initially must hold the maximum number of crls. It will be updated with the number of crls available.
1302  * @data: The PEM encoded CRLs
1303  * @format: One of DER or PEM.
1304  * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
1305  *
1306  * This function will convert the given PEM encoded CRL list
1307  * to the native gnutls_x509_crl_t format. The output will be stored
1308  * in @crls.  They will be automatically initialized.
1309  *
1310  * If the Certificate is PEM encoded it should have a header of "X509 CRL".
1311  *
1312  * Returns: the number of certificates read or a negative error value.
1313  *
1314  * Since: 3.0
1315  **/
1316 int
gnutls_x509_crl_list_import(gnutls_x509_crl_t * crls,unsigned int * crl_max,const gnutls_datum_t * data,gnutls_x509_crt_fmt_t format,unsigned int flags)1317 gnutls_x509_crl_list_import(gnutls_x509_crl_t * crls,
1318 			    unsigned int *crl_max,
1319 			    const gnutls_datum_t * data,
1320 			    gnutls_x509_crt_fmt_t format,
1321 			    unsigned int flags)
1322 {
1323 	int size;
1324 	const char *ptr;
1325 	gnutls_datum_t tmp;
1326 	int ret, nocopy = 0;
1327 	unsigned int count = 0, j;
1328 
1329 	if (format == GNUTLS_X509_FMT_DER) {
1330 		if (*crl_max < 1) {
1331 			*crl_max = 1;
1332 			return GNUTLS_E_SHORT_MEMORY_BUFFER;
1333 		}
1334 
1335 		count = 1;	/* import only the first one */
1336 
1337 		ret = gnutls_x509_crl_init(&crls[0]);
1338 		if (ret < 0) {
1339 			gnutls_assert();
1340 			goto error;
1341 		}
1342 
1343 		ret = gnutls_x509_crl_import(crls[0], data, format);
1344 		if (ret < 0) {
1345 			gnutls_assert();
1346 			goto error;
1347 		}
1348 
1349 		*crl_max = 1;
1350 		return 1;
1351 	}
1352 
1353 	/* move to the certificate
1354 	 */
1355 	ptr = memmem(data->data, data->size,
1356 		     PEM_CRL_SEP, sizeof(PEM_CRL_SEP) - 1);
1357 	if (ptr == NULL) {
1358 		gnutls_assert();
1359 		return GNUTLS_E_BASE64_DECODING_ERROR;
1360 	}
1361 
1362 	count = 0;
1363 
1364 	do {
1365 		if (count >= *crl_max) {
1366 			if (!
1367 			    (flags &
1368 			     GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED)) {
1369 				break;
1370 			} else if (nocopy == 0) {
1371 				for (j = 0; j < count; j++)
1372 					gnutls_x509_crl_deinit(crls[j]);
1373 				nocopy = 1;
1374 			}
1375 		}
1376 
1377 		if (!nocopy) {
1378 			ret = gnutls_x509_crl_init(&crls[count]);
1379 			if (ret < 0) {
1380 				gnutls_assert();
1381 				goto error;
1382 			}
1383 
1384 			tmp.data = (void *) ptr;
1385 			tmp.size =
1386 			    data->size - (ptr - (char *) data->data);
1387 			ret =
1388 			    gnutls_x509_crl_import(crls[count], &tmp,
1389 						   GNUTLS_X509_FMT_PEM);
1390 			if (ret < 0) {
1391 				gnutls_assert();
1392 				count++;
1393 				goto error;
1394 			}
1395 		}
1396 
1397 		/* now we move ptr after the pem header
1398 		 */
1399 		ptr++;
1400 		/* find the next certificate (if any)
1401 		 */
1402 		size = data->size - (ptr - (char *) data->data);
1403 
1404 		if (size > 0) {
1405 			ptr =
1406 			    memmem(ptr, size, PEM_CRL_SEP,
1407 				   sizeof(PEM_CRL_SEP) - 1);
1408 		} else
1409 			ptr = NULL;
1410 
1411 		count++;
1412 	}
1413 	while (ptr != NULL);
1414 
1415 	*crl_max = count;
1416 
1417 	if (nocopy == 0)
1418 		return count;
1419 	else
1420 		return GNUTLS_E_SHORT_MEMORY_BUFFER;
1421 
1422       error:
1423 	for (j = 0; j < count; j++)
1424 		gnutls_x509_crl_deinit(crls[j]);
1425 	return ret;
1426 }
1427