1 /*
2 * X.509 Certificate Revocation List (CRL) parsing
3 *
4 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 */
7 /*
8 * The ITU-T X.509 standard defines a certificate format for PKI.
9 *
10 * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
11 * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
12 * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
13 *
14 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
15 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
16 */
17
18 #include "common.h"
19
20 #if defined(MBEDTLS_X509_CRL_PARSE_C)
21
22 #include "mbedtls/x509_crl.h"
23 #include "x509_internal.h"
24 #include "mbedtls/error.h"
25 #include "mbedtls/oid.h"
26 #include "mbedtls/platform_util.h"
27
28 #include <string.h>
29
30 #if defined(MBEDTLS_PEM_PARSE_C)
31 #include "mbedtls/pem.h"
32 #endif
33
34 #include "mbedtls/platform.h"
35
36 #if defined(MBEDTLS_HAVE_TIME)
37 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
38 #include <windows.h>
39 #else
40 #include <time.h>
41 #endif
42 #endif
43
44 #if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32)
45 #include <stdio.h>
46 #endif
47
48 /*
49 * Version ::= INTEGER { v1(0), v2(1) }
50 */
x509_crl_get_version(unsigned char ** p,const unsigned char * end,int * ver)51 static int x509_crl_get_version(unsigned char **p,
52 const unsigned char *end,
53 int *ver)
54 {
55 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
56
57 if ((ret = mbedtls_asn1_get_int(p, end, ver)) != 0) {
58 if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
59 *ver = 0;
60 return 0;
61 }
62
63 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_VERSION, ret);
64 }
65
66 return 0;
67 }
68
69 /*
70 * X.509 CRL v2 extensions
71 *
72 * We currently don't parse any extension's content, but we do check that the
73 * list of extensions is well-formed and abort on critical extensions (that
74 * are unsupported as we don't support any extension so far)
75 */
x509_get_crl_ext(unsigned char ** p,const unsigned char * end,mbedtls_x509_buf * ext)76 static int x509_get_crl_ext(unsigned char **p,
77 const unsigned char *end,
78 mbedtls_x509_buf *ext)
79 {
80 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
81
82 if (*p == end) {
83 return 0;
84 }
85
86 /*
87 * crlExtensions [0] EXPLICIT Extensions OPTIONAL
88 * -- if present, version MUST be v2
89 */
90 if ((ret = mbedtls_x509_get_ext(p, end, ext, 0)) != 0) {
91 return ret;
92 }
93
94 end = ext->p + ext->len;
95
96 while (*p < end) {
97 /*
98 * Extension ::= SEQUENCE {
99 * extnID OBJECT IDENTIFIER,
100 * critical BOOLEAN DEFAULT FALSE,
101 * extnValue OCTET STRING }
102 */
103 int is_critical = 0;
104 const unsigned char *end_ext_data;
105 size_t len;
106
107 /* Get enclosing sequence tag */
108 if ((ret = mbedtls_asn1_get_tag(p, end, &len,
109 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
110 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
111 }
112
113 end_ext_data = *p + len;
114
115 /* Get OID (currently ignored) */
116 if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &len,
117 MBEDTLS_ASN1_OID)) != 0) {
118 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
119 }
120 *p += len;
121
122 /* Get optional critical */
123 if ((ret = mbedtls_asn1_get_bool(p, end_ext_data,
124 &is_critical)) != 0 &&
125 (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) {
126 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
127 }
128
129 /* Data should be octet string type */
130 if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &len,
131 MBEDTLS_ASN1_OCTET_STRING)) != 0) {
132 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
133 }
134
135 /* Ignore data so far and just check its length */
136 *p += len;
137 if (*p != end_ext_data) {
138 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
139 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
140 }
141
142 /* Abort on (unsupported) critical extensions */
143 if (is_critical) {
144 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
145 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
146 }
147 }
148
149 if (*p != end) {
150 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
151 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
152 }
153
154 return 0;
155 }
156
157 /*
158 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
159 */
x509_get_crl_entry_ext(unsigned char ** p,const unsigned char * end,mbedtls_x509_buf * ext)160 static int x509_get_crl_entry_ext(unsigned char **p,
161 const unsigned char *end,
162 mbedtls_x509_buf *ext)
163 {
164 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
165 size_t len = 0;
166
167 /* OPTIONAL */
168 if (end <= *p) {
169 return 0;
170 }
171
172 ext->tag = **p;
173 ext->p = *p;
174
175 /*
176 * Get CRL-entry extension sequence header
177 * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
178 */
179 if ((ret = mbedtls_asn1_get_tag(p, end, &ext->len,
180 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
181 if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
182 ext->p = NULL;
183 return 0;
184 }
185 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
186 }
187
188 end = *p + ext->len;
189
190 if (end != *p + ext->len) {
191 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
192 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
193 }
194
195 while (*p < end) {
196 if ((ret = mbedtls_asn1_get_tag(p, end, &len,
197 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
198 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
199 }
200
201 *p += len;
202 }
203
204 if (*p != end) {
205 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
206 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
207 }
208
209 return 0;
210 }
211
212 /*
213 * X.509 CRL Entries
214 */
x509_get_entries(unsigned char ** p,const unsigned char * end,mbedtls_x509_crl_entry * entry)215 static int x509_get_entries(unsigned char **p,
216 const unsigned char *end,
217 mbedtls_x509_crl_entry *entry)
218 {
219 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
220 size_t entry_len;
221 mbedtls_x509_crl_entry *cur_entry = entry;
222
223 if (*p == end) {
224 return 0;
225 }
226
227 if ((ret = mbedtls_asn1_get_tag(p, end, &entry_len,
228 MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED)) != 0) {
229 if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
230 return 0;
231 }
232
233 return ret;
234 }
235
236 end = *p + entry_len;
237
238 while (*p < end) {
239 size_t len2;
240 const unsigned char *end2;
241
242 cur_entry->raw.tag = **p;
243 if ((ret = mbedtls_asn1_get_tag(p, end, &len2,
244 MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED)) != 0) {
245 return ret;
246 }
247
248 cur_entry->raw.p = *p;
249 cur_entry->raw.len = len2;
250 end2 = *p + len2;
251
252 if ((ret = mbedtls_x509_get_serial(p, end2, &cur_entry->serial)) != 0) {
253 return ret;
254 }
255
256 if ((ret = mbedtls_x509_get_time(p, end2,
257 &cur_entry->revocation_date)) != 0) {
258 return ret;
259 }
260
261 if ((ret = x509_get_crl_entry_ext(p, end2,
262 &cur_entry->entry_ext)) != 0) {
263 return ret;
264 }
265
266 if (*p < end) {
267 cur_entry->next = mbedtls_calloc(1, sizeof(mbedtls_x509_crl_entry));
268
269 if (cur_entry->next == NULL) {
270 return MBEDTLS_ERR_X509_ALLOC_FAILED;
271 }
272
273 cur_entry = cur_entry->next;
274 }
275 }
276
277 return 0;
278 }
279
280 /*
281 * Parse one CRLs in DER format and append it to the chained list
282 */
mbedtls_x509_crl_parse_der(mbedtls_x509_crl * chain,const unsigned char * buf,size_t buflen)283 int mbedtls_x509_crl_parse_der(mbedtls_x509_crl *chain,
284 const unsigned char *buf, size_t buflen)
285 {
286 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
287 size_t len;
288 unsigned char *p = NULL, *end = NULL;
289 mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
290 mbedtls_x509_crl *crl = chain;
291
292 /*
293 * Check for valid input
294 */
295 if (crl == NULL || buf == NULL) {
296 return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
297 }
298
299 memset(&sig_params1, 0, sizeof(mbedtls_x509_buf));
300 memset(&sig_params2, 0, sizeof(mbedtls_x509_buf));
301 memset(&sig_oid2, 0, sizeof(mbedtls_x509_buf));
302
303 /*
304 * Add new CRL on the end of the chain if needed.
305 */
306 while (crl->version != 0 && crl->next != NULL) {
307 crl = crl->next;
308 }
309
310 if (crl->version != 0 && crl->next == NULL) {
311 crl->next = mbedtls_calloc(1, sizeof(mbedtls_x509_crl));
312
313 if (crl->next == NULL) {
314 mbedtls_x509_crl_free(crl);
315 return MBEDTLS_ERR_X509_ALLOC_FAILED;
316 }
317
318 mbedtls_x509_crl_init(crl->next);
319 crl = crl->next;
320 }
321
322 /*
323 * Copy raw DER-encoded CRL
324 */
325 if (buflen == 0) {
326 return MBEDTLS_ERR_X509_INVALID_FORMAT;
327 }
328
329 p = mbedtls_calloc(1, buflen);
330 if (p == NULL) {
331 return MBEDTLS_ERR_X509_ALLOC_FAILED;
332 }
333
334 memcpy(p, buf, buflen);
335
336 crl->raw.p = p;
337 crl->raw.len = buflen;
338
339 end = p + buflen;
340
341 /*
342 * CertificateList ::= SEQUENCE {
343 * tbsCertList TBSCertList,
344 * signatureAlgorithm AlgorithmIdentifier,
345 * signatureValue BIT STRING }
346 */
347 if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
348 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
349 mbedtls_x509_crl_free(crl);
350 return MBEDTLS_ERR_X509_INVALID_FORMAT;
351 }
352
353 if (len != (size_t) (end - p)) {
354 mbedtls_x509_crl_free(crl);
355 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT,
356 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
357 }
358
359 /*
360 * TBSCertList ::= SEQUENCE {
361 */
362 crl->tbs.p = p;
363
364 if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
365 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
366 mbedtls_x509_crl_free(crl);
367 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
368 }
369
370 end = p + len;
371 crl->tbs.len = (size_t) (end - crl->tbs.p);
372
373 /*
374 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
375 * -- if present, MUST be v2
376 *
377 * signature AlgorithmIdentifier
378 */
379 if ((ret = x509_crl_get_version(&p, end, &crl->version)) != 0 ||
380 (ret = mbedtls_x509_get_alg(&p, end, &crl->sig_oid, &sig_params1)) != 0) {
381 mbedtls_x509_crl_free(crl);
382 return ret;
383 }
384
385 if (crl->version < 0 || crl->version > 1) {
386 mbedtls_x509_crl_free(crl);
387 return MBEDTLS_ERR_X509_UNKNOWN_VERSION;
388 }
389
390 crl->version++;
391
392 if ((ret = mbedtls_x509_get_sig_alg(&crl->sig_oid, &sig_params1,
393 &crl->sig_md, &crl->sig_pk,
394 &crl->sig_opts)) != 0) {
395 mbedtls_x509_crl_free(crl);
396 return MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG;
397 }
398
399 /*
400 * issuer Name
401 */
402 crl->issuer_raw.p = p;
403
404 if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
405 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
406 mbedtls_x509_crl_free(crl);
407 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
408 }
409
410 if ((ret = mbedtls_x509_get_name(&p, p + len, &crl->issuer)) != 0) {
411 mbedtls_x509_crl_free(crl);
412 return ret;
413 }
414
415 crl->issuer_raw.len = (size_t) (p - crl->issuer_raw.p);
416
417 /*
418 * thisUpdate Time
419 * nextUpdate Time OPTIONAL
420 */
421 if ((ret = mbedtls_x509_get_time(&p, end, &crl->this_update)) != 0) {
422 mbedtls_x509_crl_free(crl);
423 return ret;
424 }
425
426 if ((ret = mbedtls_x509_get_time(&p, end, &crl->next_update)) != 0) {
427 if (ret != (MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE,
428 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) &&
429 ret != (MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE,
430 MBEDTLS_ERR_ASN1_OUT_OF_DATA))) {
431 mbedtls_x509_crl_free(crl);
432 return ret;
433 }
434 }
435
436 /*
437 * revokedCertificates SEQUENCE OF SEQUENCE {
438 * userCertificate CertificateSerialNumber,
439 * revocationDate Time,
440 * crlEntryExtensions Extensions OPTIONAL
441 * -- if present, MUST be v2
442 * } OPTIONAL
443 */
444 if ((ret = x509_get_entries(&p, end, &crl->entry)) != 0) {
445 mbedtls_x509_crl_free(crl);
446 return ret;
447 }
448
449 /*
450 * crlExtensions EXPLICIT Extensions OPTIONAL
451 * -- if present, MUST be v2
452 */
453 if (crl->version == 2) {
454 ret = x509_get_crl_ext(&p, end, &crl->crl_ext);
455
456 if (ret != 0) {
457 mbedtls_x509_crl_free(crl);
458 return ret;
459 }
460 }
461
462 if (p != end) {
463 mbedtls_x509_crl_free(crl);
464 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT,
465 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
466 }
467
468 end = crl->raw.p + crl->raw.len;
469
470 /*
471 * signatureAlgorithm AlgorithmIdentifier,
472 * signatureValue BIT STRING
473 */
474 if ((ret = mbedtls_x509_get_alg(&p, end, &sig_oid2, &sig_params2)) != 0) {
475 mbedtls_x509_crl_free(crl);
476 return ret;
477 }
478
479 if (crl->sig_oid.len != sig_oid2.len ||
480 memcmp(crl->sig_oid.p, sig_oid2.p, crl->sig_oid.len) != 0 ||
481 sig_params1.len != sig_params2.len ||
482 (sig_params1.len != 0 &&
483 memcmp(sig_params1.p, sig_params2.p, sig_params1.len) != 0)) {
484 mbedtls_x509_crl_free(crl);
485 return MBEDTLS_ERR_X509_SIG_MISMATCH;
486 }
487
488 if ((ret = mbedtls_x509_get_sig(&p, end, &crl->sig)) != 0) {
489 mbedtls_x509_crl_free(crl);
490 return ret;
491 }
492
493 if (p != end) {
494 mbedtls_x509_crl_free(crl);
495 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT,
496 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
497 }
498
499 return 0;
500 }
501
502 /*
503 * Parse one or more CRLs and add them to the chained list
504 */
mbedtls_x509_crl_parse(mbedtls_x509_crl * chain,const unsigned char * buf,size_t buflen)505 int mbedtls_x509_crl_parse(mbedtls_x509_crl *chain, const unsigned char *buf, size_t buflen)
506 {
507 #if defined(MBEDTLS_PEM_PARSE_C)
508 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
509 size_t use_len = 0;
510 mbedtls_pem_context pem;
511 int is_pem = 0;
512
513 if (chain == NULL || buf == NULL) {
514 return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
515 }
516
517 do {
518 mbedtls_pem_init(&pem);
519
520 // Avoid calling mbedtls_pem_read_buffer() on non-null-terminated
521 // string
522 if (buflen == 0 || buf[buflen - 1] != '\0') {
523 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
524 } else {
525 ret = mbedtls_pem_read_buffer(&pem,
526 "-----BEGIN X509 CRL-----",
527 "-----END X509 CRL-----",
528 buf, NULL, 0, &use_len);
529 }
530
531 if (ret == 0) {
532 /*
533 * Was PEM encoded
534 */
535 is_pem = 1;
536
537 buflen -= use_len;
538 buf += use_len;
539
540 if ((ret = mbedtls_x509_crl_parse_der(chain,
541 pem.buf, pem.buflen)) != 0) {
542 mbedtls_pem_free(&pem);
543 return ret;
544 }
545 } else if (is_pem) {
546 mbedtls_pem_free(&pem);
547 return ret;
548 }
549
550 mbedtls_pem_free(&pem);
551 }
552 /* In the PEM case, buflen is 1 at the end, for the terminated NULL byte.
553 * And a valid CRL cannot be less than 1 byte anyway. */
554 while (is_pem && buflen > 1);
555
556 if (is_pem) {
557 return 0;
558 } else
559 #endif /* MBEDTLS_PEM_PARSE_C */
560 return mbedtls_x509_crl_parse_der(chain, buf, buflen);
561 }
562
563 #if defined(MBEDTLS_FS_IO)
564 /*
565 * Load one or more CRLs and add them to the chained list
566 */
mbedtls_x509_crl_parse_file(mbedtls_x509_crl * chain,const char * path)567 int mbedtls_x509_crl_parse_file(mbedtls_x509_crl *chain, const char *path)
568 {
569 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
570 size_t n;
571 unsigned char *buf;
572
573 if ((ret = mbedtls_pk_load_file(path, &buf, &n)) != 0) {
574 return ret;
575 }
576
577 ret = mbedtls_x509_crl_parse(chain, buf, n);
578
579 mbedtls_zeroize_and_free(buf, n);
580
581 return ret;
582 }
583 #endif /* MBEDTLS_FS_IO */
584
585 #if !defined(MBEDTLS_X509_REMOVE_INFO)
586 /*
587 * Return an informational string about the certificate.
588 */
589 #define BEFORE_COLON 14
590 #define BC "14"
591 /*
592 * Return an informational string about the CRL.
593 */
mbedtls_x509_crl_info(char * buf,size_t size,const char * prefix,const mbedtls_x509_crl * crl)594 int mbedtls_x509_crl_info(char *buf, size_t size, const char *prefix,
595 const mbedtls_x509_crl *crl)
596 {
597 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
598 size_t n;
599 char *p;
600 const mbedtls_x509_crl_entry *entry;
601
602 p = buf;
603 n = size;
604
605 ret = mbedtls_snprintf(p, n, "%sCRL version : %d",
606 prefix, crl->version);
607 MBEDTLS_X509_SAFE_SNPRINTF;
608
609 ret = mbedtls_snprintf(p, n, "\n%sissuer name : ", prefix);
610 MBEDTLS_X509_SAFE_SNPRINTF;
611 ret = mbedtls_x509_dn_gets(p, n, &crl->issuer);
612 MBEDTLS_X509_SAFE_SNPRINTF;
613
614 ret = mbedtls_snprintf(p, n, "\n%sthis update : " \
615 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
616 crl->this_update.year, crl->this_update.mon,
617 crl->this_update.day, crl->this_update.hour,
618 crl->this_update.min, crl->this_update.sec);
619 MBEDTLS_X509_SAFE_SNPRINTF;
620
621 ret = mbedtls_snprintf(p, n, "\n%snext update : " \
622 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
623 crl->next_update.year, crl->next_update.mon,
624 crl->next_update.day, crl->next_update.hour,
625 crl->next_update.min, crl->next_update.sec);
626 MBEDTLS_X509_SAFE_SNPRINTF;
627
628 entry = &crl->entry;
629
630 ret = mbedtls_snprintf(p, n, "\n%sRevoked certificates:",
631 prefix);
632 MBEDTLS_X509_SAFE_SNPRINTF;
633
634 while (entry != NULL && entry->raw.len != 0) {
635 ret = mbedtls_snprintf(p, n, "\n%sserial number: ",
636 prefix);
637 MBEDTLS_X509_SAFE_SNPRINTF;
638
639 ret = mbedtls_x509_serial_gets(p, n, &entry->serial);
640 MBEDTLS_X509_SAFE_SNPRINTF;
641
642 ret = mbedtls_snprintf(p, n, " revocation date: " \
643 "%04d-%02d-%02d %02d:%02d:%02d",
644 entry->revocation_date.year, entry->revocation_date.mon,
645 entry->revocation_date.day, entry->revocation_date.hour,
646 entry->revocation_date.min, entry->revocation_date.sec);
647 MBEDTLS_X509_SAFE_SNPRINTF;
648
649 entry = entry->next;
650 }
651
652 ret = mbedtls_snprintf(p, n, "\n%ssigned using : ", prefix);
653 MBEDTLS_X509_SAFE_SNPRINTF;
654
655 ret = mbedtls_x509_sig_alg_gets(p, n, &crl->sig_oid, crl->sig_pk, crl->sig_md,
656 crl->sig_opts);
657 MBEDTLS_X509_SAFE_SNPRINTF;
658
659 ret = mbedtls_snprintf(p, n, "\n");
660 MBEDTLS_X509_SAFE_SNPRINTF;
661
662 return (int) (size - n);
663 }
664 #endif /* MBEDTLS_X509_REMOVE_INFO */
665
666 /*
667 * Initialize a CRL chain
668 */
mbedtls_x509_crl_init(mbedtls_x509_crl * crl)669 void mbedtls_x509_crl_init(mbedtls_x509_crl *crl)
670 {
671 memset(crl, 0, sizeof(mbedtls_x509_crl));
672 }
673
674 /*
675 * Unallocate all CRL data
676 */
mbedtls_x509_crl_free(mbedtls_x509_crl * crl)677 void mbedtls_x509_crl_free(mbedtls_x509_crl *crl)
678 {
679 mbedtls_x509_crl *crl_cur = crl;
680 mbedtls_x509_crl *crl_prv;
681 mbedtls_x509_crl_entry *entry_cur;
682 mbedtls_x509_crl_entry *entry_prv;
683
684 while (crl_cur != NULL) {
685 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
686 mbedtls_free(crl_cur->sig_opts);
687 #endif
688
689 mbedtls_asn1_free_named_data_list_shallow(crl_cur->issuer.next);
690
691 entry_cur = crl_cur->entry.next;
692 while (entry_cur != NULL) {
693 entry_prv = entry_cur;
694 entry_cur = entry_cur->next;
695 mbedtls_zeroize_and_free(entry_prv,
696 sizeof(mbedtls_x509_crl_entry));
697 }
698
699 if (crl_cur->raw.p != NULL) {
700 mbedtls_zeroize_and_free(crl_cur->raw.p, crl_cur->raw.len);
701 }
702
703 crl_prv = crl_cur;
704 crl_cur = crl_cur->next;
705
706 mbedtls_platform_zeroize(crl_prv, sizeof(mbedtls_x509_crl));
707 if (crl_prv != crl) {
708 mbedtls_free(crl_prv);
709 }
710 }
711 }
712
713 #endif /* MBEDTLS_X509_CRL_PARSE_C */
714