Line data Source code
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 :
35 635 : static int crl_reinit(gnutls_x509_crl_t crl)
36 : {
37 635 : int result;
38 :
39 635 : if (crl->crl)
40 0 : asn1_delete_structure(&crl->crl);
41 :
42 635 : result = asn1_create_element(_gnutls_get_pkix(),
43 : "PKIX1.CertificateList",
44 : &crl->crl);
45 635 : if (result != ASN1_SUCCESS) {
46 0 : gnutls_assert();
47 0 : return _gnutls_asn2err(result);
48 : }
49 635 : crl->rcache = NULL;
50 635 : crl->rcache_idx = 0;
51 635 : crl->raw_issuer_dn.size = 0;
52 :
53 635 : 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 : **/
69 635 : int gnutls_x509_crl_init(gnutls_x509_crl_t * crl)
70 : {
71 635 : FAIL_IF_LIB_ERROR;
72 :
73 635 : *crl = gnutls_calloc(1, sizeof(gnutls_x509_crl_int));
74 :
75 635 : if (*crl) {
76 635 : int result = crl_reinit(*crl);
77 635 : if (result < 0) {
78 0 : gnutls_assert();
79 0 : gnutls_free(*crl);
80 0 : 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 : **/
93 632 : void gnutls_x509_crl_deinit(gnutls_x509_crl_t crl)
94 : {
95 632 : if (!crl)
96 : return;
97 :
98 632 : if (crl->crl)
99 475 : asn1_delete_structure(&crl->crl);
100 632 : gnutls_free(crl->der.data);
101 :
102 632 : 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
120 628 : gnutls_x509_crl_import(gnutls_x509_crl_t crl,
121 : const gnutls_datum_t * data,
122 : gnutls_x509_crt_fmt_t format)
123 : {
124 628 : int result = 0;
125 :
126 628 : if (crl == NULL) {
127 0 : gnutls_assert();
128 0 : return GNUTLS_E_INVALID_REQUEST;
129 : }
130 :
131 628 : _gnutls_free_datum(&crl->der);
132 :
133 : /* If the CRL is in PEM format then decode it
134 : */
135 628 : if (format == GNUTLS_X509_FMT_PEM) {
136 420 : result =
137 420 : _gnutls_fbase64_decode(PEM_CRL, data->data, data->size,
138 : &crl->der);
139 :
140 420 : if (result < 0) {
141 46 : gnutls_assert();
142 46 : return result;
143 : }
144 : } else {
145 208 : result = _gnutls_set_datum(&crl->der, data->data, data->size);
146 208 : if (result < 0) {
147 0 : gnutls_assert();
148 0 : return result;
149 : }
150 : }
151 :
152 582 : if (crl->expanded) {
153 0 : result = crl_reinit(crl);
154 0 : if (result < 0) {
155 0 : gnutls_assert();
156 0 : goto cleanup;
157 : }
158 : }
159 582 : crl->expanded = 1;
160 :
161 582 : result =
162 582 : _asn1_strict_der_decode(&crl->crl, crl->der.data, crl->der.size, NULL);
163 582 : if (result != ASN1_SUCCESS) {
164 157 : result = _gnutls_asn2err(result);
165 157 : gnutls_assert();
166 157 : goto cleanup;
167 : }
168 :
169 425 : result = _gnutls_x509_get_raw_field2(crl->crl, &crl->der,
170 : "tbsCertList.issuer.rdnSequence",
171 : &crl->raw_issuer_dn);
172 425 : if (result < 0) {
173 1 : gnutls_assert();
174 1 : goto cleanup;
175 : }
176 :
177 : return 0;
178 :
179 158 : cleanup:
180 158 : _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
207 0 : gnutls_x509_crl_get_issuer_dn(gnutls_x509_crl_t crl, char *buf,
208 : size_t * sizeof_buf)
209 : {
210 0 : if (crl == NULL) {
211 0 : gnutls_assert();
212 0 : return GNUTLS_E_INVALID_REQUEST;
213 : }
214 :
215 0 : 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
247 0 : 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 0 : gnutls_datum_t td;
253 0 : int ret;
254 :
255 0 : if (crl == NULL) {
256 0 : gnutls_assert();
257 0 : return GNUTLS_E_INVALID_REQUEST;
258 : }
259 :
260 0 : ret = _gnutls_x509_parse_dn_oid(crl->crl,
261 : "tbsCertList.issuer.rdnSequence",
262 : oid, indx, raw_flag, &td);
263 0 : if (ret < 0)
264 0 : return gnutls_assert_val(ret);
265 :
266 0 : 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
287 0 : gnutls_x509_crl_get_dn_oid(gnutls_x509_crl_t crl,
288 : unsigned indx, void *oid, size_t * sizeof_oid)
289 : {
290 0 : if (crl == NULL) {
291 0 : gnutls_assert();
292 0 : return GNUTLS_E_INVALID_REQUEST;
293 : }
294 :
295 0 : 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
319 0 : gnutls_x509_crl_get_issuer_dn2(gnutls_x509_crl_t crl, gnutls_datum_t * dn)
320 : {
321 0 : if (crl == NULL) {
322 0 : gnutls_assert();
323 0 : return GNUTLS_E_INVALID_REQUEST;
324 : }
325 :
326 0 : 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
352 352 : gnutls_x509_crl_get_issuer_dn3(gnutls_x509_crl_t crl, gnutls_datum_t * dn, unsigned flags)
353 : {
354 352 : if (crl == NULL) {
355 0 : gnutls_assert();
356 0 : return GNUTLS_E_INVALID_REQUEST;
357 : }
358 :
359 352 : 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 : **/
377 236 : int gnutls_x509_crl_get_signature_algorithm(gnutls_x509_crl_t crl)
378 : {
379 236 : 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 : **/
398 4 : int gnutls_x509_crl_get_signature_oid(gnutls_x509_crl_t crl, char *oid, size_t *oid_size)
399 : {
400 4 : char str[MAX_OID_SIZE];
401 4 : int len, result, ret;
402 4 : gnutls_datum_t out;
403 :
404 4 : len = sizeof(str);
405 4 : result = asn1_read_value(crl->crl, "signatureAlgorithm.algorithm", str, &len);
406 4 : if (result != ASN1_SUCCESS) {
407 0 : gnutls_assert();
408 0 : return _gnutls_asn2err(result);
409 : }
410 :
411 4 : out.data = (void*)str;
412 4 : out.size = len;
413 :
414 4 : ret = _gnutls_copy_string(&out, (void*)oid, oid_size);
415 4 : if (ret < 0) {
416 0 : gnutls_assert();
417 0 : 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
435 438 : gnutls_x509_crl_get_signature(gnutls_x509_crl_t crl,
436 : char *sig, size_t * sizeof_sig)
437 : {
438 438 : int result;
439 438 : unsigned int bits;
440 438 : int len;
441 :
442 438 : if (crl == NULL) {
443 0 : gnutls_assert();
444 0 : return GNUTLS_E_INVALID_REQUEST;
445 : }
446 :
447 438 : len = 0;
448 438 : result = asn1_read_value(crl->crl, "signature", NULL, &len);
449 :
450 438 : if (result != ASN1_MEM_ERROR) {
451 0 : gnutls_assert();
452 0 : return _gnutls_asn2err(result);
453 : }
454 :
455 438 : bits = len;
456 438 : if (bits % 8 != 0) {
457 0 : gnutls_assert();
458 0 : return GNUTLS_E_CERTIFICATE_ERROR;
459 : }
460 :
461 438 : len = bits / 8;
462 :
463 438 : if (*sizeof_sig < (unsigned) len) {
464 219 : *sizeof_sig = bits / 8;
465 219 : return GNUTLS_E_SHORT_MEMORY_BUFFER;
466 : }
467 :
468 219 : result = asn1_read_value(crl->crl, "signature", sig, &len);
469 219 : if (result != ASN1_SUCCESS) {
470 0 : gnutls_assert();
471 0 : 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 : **/
485 438 : int gnutls_x509_crl_get_version(gnutls_x509_crl_t crl)
486 : {
487 438 : if (crl == NULL) {
488 0 : gnutls_assert();
489 0 : return GNUTLS_E_INVALID_REQUEST;
490 : }
491 :
492 438 : 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 : **/
503 236 : time_t gnutls_x509_crl_get_this_update(gnutls_x509_crl_t crl)
504 : {
505 236 : if (crl == NULL) {
506 0 : gnutls_assert();
507 0 : return (time_t) - 1;
508 : }
509 :
510 236 : 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 : **/
524 236 : time_t gnutls_x509_crl_get_next_update(gnutls_x509_crl_t crl)
525 : {
526 236 : if (crl == NULL) {
527 0 : gnutls_assert();
528 0 : return (time_t) - 1;
529 : }
530 :
531 236 : 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 : **/
544 223 : int gnutls_x509_crl_get_crt_count(gnutls_x509_crl_t crl)
545 : {
546 :
547 223 : int count, result;
548 :
549 223 : if (crl == NULL) {
550 0 : gnutls_assert();
551 0 : return GNUTLS_E_INVALID_REQUEST;
552 : }
553 :
554 223 : result =
555 223 : asn1_number_of_elements(crl->crl,
556 : "tbsCertList.revokedCertificates",
557 : &count);
558 :
559 223 : if (result != ASN1_SUCCESS) {
560 119 : gnutls_assert();
561 119 : return 0; /* no certificates */
562 : }
563 :
564 104 : 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
585 1 : 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 1 : int result, _serial_size;
591 1 : char serial_name[MAX_NAME_SIZE];
592 1 : char date_name[MAX_NAME_SIZE];
593 :
594 1 : if (crl == NULL) {
595 0 : gnutls_assert();
596 0 : return GNUTLS_E_INVALID_REQUEST;
597 : }
598 :
599 1 : snprintf(serial_name, sizeof(serial_name),
600 : "tbsCertList.revokedCertificates.?%u.userCertificate",
601 : indx + 1);
602 1 : snprintf(date_name, sizeof(date_name),
603 : "tbsCertList.revokedCertificates.?%u.revocationDate",
604 : indx + 1);
605 :
606 1 : _serial_size = *serial_size;
607 1 : result =
608 1 : asn1_read_value(crl->crl, serial_name, serial, &_serial_size);
609 :
610 1 : *serial_size = _serial_size;
611 1 : if (result != ASN1_SUCCESS) {
612 0 : gnutls_assert();
613 0 : if (result == ASN1_ELEMENT_NOT_FOUND)
614 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
615 0 : return _gnutls_asn2err(result);
616 : }
617 :
618 1 : if (t) {
619 1 : *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 : **/
631 355 : void gnutls_x509_crl_iter_deinit(gnutls_x509_crl_iter_t iter)
632 : {
633 355 : if (!iter)
634 : return;
635 :
636 231 : 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
661 11875 : 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 11875 : int result, _serial_size;
668 11875 : char serial_name[MAX_NAME_SIZE];
669 11875 : char date_name[MAX_NAME_SIZE];
670 :
671 11875 : if (crl == NULL || iter == NULL) {
672 0 : gnutls_assert();
673 0 : return GNUTLS_E_INVALID_REQUEST;
674 : }
675 :
676 11875 : if (*iter == NULL) {
677 231 : *iter = gnutls_calloc(1, sizeof(struct gnutls_x509_crl_iter));
678 231 : if (*iter == NULL)
679 0 : return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
680 : }
681 :
682 11875 : if ((*iter)->rcache == NULL) {
683 231 : (*iter)->rcache = asn1_find_node (crl->crl, "tbsCertList.revokedCertificates.?1");
684 231 : (*iter)->rcache_idx = 1;
685 : } else {
686 11644 : snprintf(serial_name, sizeof(serial_name),
687 : "?%d", (*iter)->rcache_idx);
688 11644 : (*iter)->rcache = asn1_find_node ((*iter)->rcache, serial_name);
689 : }
690 11875 : if ((*iter)->rcache == NULL) {
691 : /* reset */
692 129 : (*iter)->rcache = NULL;
693 129 : return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
694 : }
695 :
696 11746 : snprintf(serial_name, sizeof(serial_name),
697 : "?%d.userCertificate", (*iter)->rcache_idx);
698 :
699 11746 : _serial_size = *serial_size;
700 11746 : result =
701 11746 : asn1_read_value((*iter)->rcache, serial_name, serial, &_serial_size);
702 :
703 11746 : *serial_size = _serial_size;
704 11746 : if (result != ASN1_SUCCESS) {
705 0 : gnutls_assert();
706 0 : if (result == ASN1_ELEMENT_NOT_FOUND) {
707 : /* reset */
708 0 : (*iter)->rcache = NULL;
709 0 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
710 : }
711 0 : return _gnutls_asn2err(result);
712 : }
713 :
714 11746 : if (t) {
715 11684 : snprintf(date_name, sizeof(date_name),
716 11684 : "?%d.revocationDate", (*iter)->rcache_idx);
717 11684 : *t = _gnutls_x509_get_time((*iter)->rcache, date_name, 0);
718 : }
719 :
720 11746 : (*iter)->rcache_idx++;
721 :
722 11746 : 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
738 0 : gnutls_x509_crl_get_raw_issuer_dn(gnutls_x509_crl_t crl,
739 : gnutls_datum_t * dn)
740 : {
741 0 : if (crl->raw_issuer_dn.size != 0) {
742 0 : return _gnutls_set_datum(dn, crl->raw_issuer_dn.data,
743 : crl->raw_issuer_dn.size);
744 : } else {
745 0 : 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
769 0 : 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 0 : if (crl == NULL) {
774 0 : gnutls_assert();
775 0 : return GNUTLS_E_INVALID_REQUEST;
776 : }
777 :
778 0 : 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
801 217 : gnutls_x509_crl_export2(gnutls_x509_crl_t crl,
802 : gnutls_x509_crt_fmt_t format, gnutls_datum_t * out)
803 : {
804 217 : if (crl == NULL) {
805 0 : gnutls_assert();
806 0 : return GNUTLS_E_INVALID_REQUEST;
807 : }
808 :
809 217 : 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 : -*/
822 1 : int _gnutls_x509_crl_cpy(gnutls_x509_crl_t dest, gnutls_x509_crl_t src)
823 : {
824 1 : int ret;
825 1 : gnutls_datum_t tmp;
826 :
827 1 : ret = gnutls_x509_crl_export2(src, GNUTLS_X509_FMT_DER, &tmp);
828 1 : if (ret < 0)
829 0 : return gnutls_assert_val(ret);
830 :
831 1 : ret = gnutls_x509_crl_import(dest, &tmp, GNUTLS_X509_FMT_DER);
832 :
833 1 : gnutls_free(tmp.data);
834 :
835 1 : if (ret < 0) {
836 0 : gnutls_assert();
837 0 : return ret;
838 : }
839 :
840 : return 0;
841 :
842 : }
843 :
844 : static int
845 0 : _get_authority_key_id(gnutls_x509_crl_t cert, ASN1_TYPE * c2,
846 : unsigned int *critical)
847 : {
848 0 : int ret;
849 0 : gnutls_datum_t id;
850 :
851 0 : *c2 = ASN1_TYPE_EMPTY;
852 :
853 0 : if (cert == NULL) {
854 0 : gnutls_assert();
855 0 : return GNUTLS_E_INVALID_REQUEST;
856 : }
857 :
858 0 : if ((ret =
859 0 : _gnutls_x509_crl_get_extension(cert, "2.5.29.35", 0, &id,
860 : critical)) < 0) {
861 0 : return gnutls_assert_val(ret);
862 : }
863 :
864 0 : if (id.size == 0 || id.data == NULL) {
865 0 : gnutls_assert();
866 0 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
867 : }
868 :
869 0 : ret = asn1_create_element
870 : (_gnutls_get_pkix(), "PKIX1.AuthorityKeyIdentifier", c2);
871 0 : if (ret != ASN1_SUCCESS) {
872 0 : gnutls_assert();
873 0 : _gnutls_free_datum(&id);
874 0 : return _gnutls_asn2err(ret);
875 : }
876 :
877 0 : ret = _asn1_strict_der_decode(c2, id.data, id.size, NULL);
878 0 : _gnutls_free_datum(&id);
879 :
880 0 : if (ret != ASN1_SUCCESS) {
881 0 : gnutls_assert();
882 0 : asn1_delete_structure(c2);
883 0 : 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
913 0 : 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 0 : int ret, result, len;
923 0 : ASN1_TYPE c2;
924 :
925 0 : ret = _get_authority_key_id(crl, &c2, critical);
926 0 : if (ret < 0)
927 0 : return gnutls_assert_val(ret);
928 :
929 0 : ret =
930 0 : _gnutls_parse_general_name(c2, "authorityCertIssuer", seq, alt,
931 : alt_size, alt_type, 0);
932 0 : if (ret < 0) {
933 0 : ret = gnutls_assert_val(ret);
934 0 : goto fail;
935 : }
936 :
937 0 : if (serial) {
938 0 : len = *serial_size;
939 0 : result =
940 0 : asn1_read_value(c2, "authorityCertSerialNumber",
941 : serial, &len);
942 :
943 0 : *serial_size = len;
944 :
945 0 : if (result < 0) {
946 0 : ret = _gnutls_asn2err(result);
947 0 : goto fail;
948 : }
949 :
950 : }
951 :
952 : ret = 0;
953 :
954 0 : fail:
955 0 : asn1_delete_structure(&c2);
956 :
957 0 : 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
983 0 : 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 0 : int result, len, ret;
988 0 : ASN1_TYPE c2;
989 :
990 0 : ret = _get_authority_key_id(crl, &c2, critical);
991 0 : if (ret < 0)
992 0 : return gnutls_assert_val(ret);
993 :
994 0 : len = *id_size;
995 0 : result = asn1_read_value(c2, "keyIdentifier", id, &len);
996 :
997 0 : *id_size = len;
998 0 : asn1_delete_structure(&c2);
999 :
1000 0 : if (result == ASN1_VALUE_NOT_FOUND
1001 0 : || result == ASN1_ELEMENT_NOT_FOUND)
1002 0 : return
1003 0 : gnutls_assert_val(GNUTLS_E_X509_UNSUPPORTED_EXTENSION);
1004 :
1005 0 : if (result != ASN1_SUCCESS) {
1006 0 : gnutls_assert();
1007 0 : 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
1030 350 : gnutls_x509_crl_get_number(gnutls_x509_crl_t crl, void *ret,
1031 : size_t * ret_size, unsigned int *critical)
1032 : {
1033 350 : int result;
1034 350 : gnutls_datum_t id;
1035 :
1036 350 : if (crl == NULL) {
1037 0 : gnutls_assert();
1038 0 : return GNUTLS_E_INVALID_REQUEST;
1039 : }
1040 :
1041 350 : if (ret)
1042 350 : memset(ret, 0, *ret_size);
1043 : else
1044 0 : *ret_size = 0;
1045 :
1046 700 : if ((result =
1047 350 : _gnutls_x509_crl_get_extension(crl, "2.5.29.20", 0, &id,
1048 : critical)) < 0) {
1049 : return result;
1050 : }
1051 :
1052 350 : if (id.size == 0 || id.data == NULL) {
1053 0 : gnutls_assert();
1054 0 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1055 : }
1056 :
1057 350 : result =
1058 350 : _gnutls_x509_ext_extract_number(ret, ret_size, id.data,
1059 : id.size);
1060 :
1061 350 : _gnutls_free_datum(&id);
1062 :
1063 350 : if (result < 0) {
1064 0 : gnutls_assert();
1065 0 : 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
1090 0 : gnutls_x509_crl_get_extension_oid(gnutls_x509_crl_t crl, unsigned indx,
1091 : void *oid, size_t * sizeof_oid)
1092 : {
1093 0 : int result;
1094 :
1095 0 : if (crl == NULL) {
1096 0 : gnutls_assert();
1097 0 : return GNUTLS_E_INVALID_REQUEST;
1098 : }
1099 :
1100 0 : result =
1101 0 : _gnutls_x509_crl_get_extension_oid(crl, indx, oid, sizeof_oid);
1102 0 : if (result < 0) {
1103 0 : 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
1136 655 : 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 655 : int result;
1141 655 : char str_critical[10];
1142 655 : char name[MAX_NAME_SIZE];
1143 655 : int len;
1144 :
1145 655 : if (!crl) {
1146 0 : gnutls_assert();
1147 0 : return GNUTLS_E_INVALID_REQUEST;
1148 : }
1149 :
1150 655 : snprintf(name, sizeof(name),
1151 : "tbsCertList.crlExtensions.?%u.extnID", indx + 1);
1152 :
1153 655 : len = *sizeof_oid;
1154 655 : result = asn1_read_value(crl->crl, name, oid, &len);
1155 655 : *sizeof_oid = len;
1156 :
1157 655 : if (result == ASN1_ELEMENT_NOT_FOUND)
1158 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1159 438 : else if (result != ASN1_SUCCESS) {
1160 0 : gnutls_assert();
1161 0 : return _gnutls_asn2err(result);
1162 : }
1163 :
1164 438 : snprintf(name, sizeof(name),
1165 : "tbsCertList.crlExtensions.?%u.critical", indx + 1);
1166 438 : len = sizeof(str_critical);
1167 438 : result = asn1_read_value(crl->crl, name, str_critical, &len);
1168 438 : if (result != ASN1_SUCCESS) {
1169 0 : gnutls_assert();
1170 0 : return _gnutls_asn2err(result);
1171 : }
1172 :
1173 438 : if (critical) {
1174 438 : if (str_critical[0] == 'T')
1175 5 : *critical = 1;
1176 : else
1177 433 : *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
1208 0 : gnutls_x509_crl_get_extension_data(gnutls_x509_crl_t crl, unsigned indx,
1209 : void *data, size_t * sizeof_data)
1210 : {
1211 0 : int result, len;
1212 0 : char name[MAX_NAME_SIZE];
1213 :
1214 0 : if (!crl) {
1215 0 : gnutls_assert();
1216 0 : return GNUTLS_E_INVALID_REQUEST;
1217 : }
1218 :
1219 0 : snprintf(name, sizeof(name),
1220 : "tbsCertList.crlExtensions.?%u.extnValue", indx + 1);
1221 :
1222 0 : len = *sizeof_data;
1223 0 : result = asn1_read_value(crl->crl, name, data, &len);
1224 0 : *sizeof_data = len;
1225 :
1226 0 : if (result == ASN1_ELEMENT_NOT_FOUND)
1227 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1228 0 : else if (result < 0) {
1229 0 : gnutls_assert();
1230 0 : 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
1256 593 : 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 593 : unsigned int init = 1024;
1263 593 : int ret;
1264 :
1265 593 : *crls = gnutls_malloc(sizeof(gnutls_x509_crl_t) * init);
1266 593 : if (*crls == NULL) {
1267 0 : gnutls_assert();
1268 0 : return GNUTLS_E_MEMORY_ERROR;
1269 : }
1270 :
1271 593 : ret =
1272 593 : gnutls_x509_crl_list_import(*crls, &init, data, format,
1273 : flags | GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
1274 593 : if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
1275 0 : *crls =
1276 0 : gnutls_realloc_fast(*crls,
1277 : sizeof(gnutls_x509_crl_t) * init);
1278 0 : if (*crls == NULL) {
1279 0 : gnutls_assert();
1280 0 : return GNUTLS_E_MEMORY_ERROR;
1281 : }
1282 :
1283 0 : ret =
1284 0 : gnutls_x509_crl_list_import(*crls, &init, data, format,
1285 : flags);
1286 : }
1287 :
1288 593 : if (ret < 0) {
1289 512 : gnutls_free(*crls);
1290 512 : *crls = NULL;
1291 512 : return ret;
1292 : }
1293 :
1294 81 : *size = init;
1295 81 : 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
1317 593 : 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 593 : int size;
1324 593 : const char *ptr;
1325 593 : gnutls_datum_t tmp;
1326 593 : int ret, nocopy = 0;
1327 593 : unsigned int count = 0, j;
1328 :
1329 593 : if (format == GNUTLS_X509_FMT_DER) {
1330 0 : if (*crl_max < 1) {
1331 0 : *crl_max = 1;
1332 0 : return GNUTLS_E_SHORT_MEMORY_BUFFER;
1333 : }
1334 :
1335 0 : count = 1; /* import only the first one */
1336 :
1337 0 : ret = gnutls_x509_crl_init(&crls[0]);
1338 0 : if (ret < 0) {
1339 0 : gnutls_assert();
1340 0 : goto error;
1341 : }
1342 :
1343 0 : ret = gnutls_x509_crl_import(crls[0], data, format);
1344 0 : if (ret < 0) {
1345 0 : gnutls_assert();
1346 0 : goto error;
1347 : }
1348 :
1349 0 : *crl_max = 1;
1350 0 : return 1;
1351 : }
1352 :
1353 : /* move to the certificate
1354 : */
1355 593 : ptr = memmem(data->data, data->size,
1356 : PEM_CRL_SEP, sizeof(PEM_CRL_SEP) - 1);
1357 593 : if (ptr == NULL) {
1358 311 : gnutls_assert();
1359 311 : return GNUTLS_E_BASE64_DECODING_ERROR;
1360 : }
1361 :
1362 : count = 0;
1363 :
1364 405 : do {
1365 405 : if (count >= *crl_max) {
1366 0 : if (!
1367 0 : (flags &
1368 : GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED)) {
1369 : break;
1370 0 : } else if (nocopy == 0) {
1371 0 : for (j = 0; j < count; j++)
1372 0 : gnutls_x509_crl_deinit(crls[j]);
1373 : nocopy = 1;
1374 : }
1375 : }
1376 :
1377 405 : if (!nocopy) {
1378 405 : ret = gnutls_x509_crl_init(&crls[count]);
1379 405 : if (ret < 0) {
1380 0 : gnutls_assert();
1381 0 : goto error;
1382 : }
1383 :
1384 405 : tmp.data = (void *) ptr;
1385 405 : tmp.size =
1386 405 : data->size - (ptr - (char *) data->data);
1387 405 : ret =
1388 405 : gnutls_x509_crl_import(crls[count], &tmp,
1389 : GNUTLS_X509_FMT_PEM);
1390 405 : if (ret < 0) {
1391 201 : gnutls_assert();
1392 201 : count++;
1393 201 : goto error;
1394 : }
1395 : }
1396 :
1397 : /* now we move ptr after the pem header
1398 : */
1399 204 : ptr++;
1400 : /* find the next certificate (if any)
1401 : */
1402 204 : size = data->size - (ptr - (char *) data->data);
1403 :
1404 204 : if (size > 0) {
1405 204 : ptr =
1406 204 : memmem(ptr, size, PEM_CRL_SEP,
1407 : sizeof(PEM_CRL_SEP) - 1);
1408 : } else
1409 : ptr = NULL;
1410 :
1411 204 : count++;
1412 : }
1413 204 : while (ptr != NULL);
1414 :
1415 81 : *crl_max = count;
1416 :
1417 81 : if (nocopy == 0)
1418 81 : return count;
1419 : else
1420 : return GNUTLS_E_SHORT_MEMORY_BUFFER;
1421 :
1422 201 : error:
1423 402 : for (j = 0; j < count; j++)
1424 201 : gnutls_x509_crl_deinit(crls[j]);
1425 : return ret;
1426 : }
|