blob: fdbad238a6dd75c1587e48b161ecb916952db5d1 [file] [log] [blame]
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001/*
Tom Cosgrove1797b052022-12-04 17:19:59 +00002 * X.509 Certificate Revocation List (CRL) parsing
Paul Bakker7c6b2c32013-09-16 13:49:26 +02003 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Dave Rodgman16799db2023-11-02 19:47:20 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Paul Bakker7c6b2c32013-09-16 13:49:26 +02006 */
7/*
8 * The ITU-T X.509 standard defines a certificate format for PKI.
9 *
Manuel Pégourié-Gonnard1c082f32014-06-12 22:34:55 +020010 * 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)
Paul Bakker7c6b2c32013-09-16 13:49:26 +020013 *
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
Gilles Peskinedb09ef62020-06-03 01:43:33 +020018#include "common.h"
Paul Bakker7c6b2c32013-09-16 13:49:26 +020019
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020020#if defined(MBEDTLS_X509_CRL_PARSE_C)
Paul Bakker7c6b2c32013-09-16 13:49:26 +020021
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000022#include "mbedtls/x509_crl.h"
Janos Follath73c616b2019-12-18 15:07:04 +000023#include "mbedtls/error.h"
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000024#include "mbedtls/oid.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050025#include "mbedtls/platform_util.h"
Rich Evans00ab4702015-02-06 13:43:58 +000026
27#include <string.h>
28
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020029#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000030#include "mbedtls/pem.h"
Paul Bakker7c6b2c32013-09-16 13:49:26 +020031#endif
32
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000033#include "mbedtls/platform.h"
Paul Bakker7c6b2c32013-09-16 13:49:26 +020034
Daniel Axtensf0710242020-05-28 11:43:41 +100035#if defined(MBEDTLS_HAVE_TIME)
Paul Bakkerfa6a6202013-10-28 18:48:30 +010036#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
Paul Bakker7c6b2c32013-09-16 13:49:26 +020037#include <windows.h>
38#else
39#include <time.h>
40#endif
Daniel Axtensf0710242020-05-28 11:43:41 +100041#endif
Paul Bakker7c6b2c32013-09-16 13:49:26 +020042
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020043#if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32)
Paul Bakker7c6b2c32013-09-16 13:49:26 +020044#include <stdio.h>
45#endif
46
47/*
48 * Version ::= INTEGER { v1(0), v2(1) }
49 */
Gilles Peskine449bd832023-01-11 14:50:10 +010050static int x509_crl_get_version(unsigned char **p,
51 const unsigned char *end,
52 int *ver)
Paul Bakker7c6b2c32013-09-16 13:49:26 +020053{
Janos Follath865b3eb2019-12-16 11:46:15 +000054 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker7c6b2c32013-09-16 13:49:26 +020055
Gilles Peskine449bd832023-01-11 14:50:10 +010056 if ((ret = mbedtls_asn1_get_int(p, end, ver)) != 0) {
57 if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
Paul Bakker7c6b2c32013-09-16 13:49:26 +020058 *ver = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +010059 return 0;
Paul Bakker7c6b2c32013-09-16 13:49:26 +020060 }
61
Gilles Peskine449bd832023-01-11 14:50:10 +010062 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_VERSION, ret);
Paul Bakker7c6b2c32013-09-16 13:49:26 +020063 }
64
Gilles Peskine449bd832023-01-11 14:50:10 +010065 return 0;
Paul Bakker7c6b2c32013-09-16 13:49:26 +020066}
67
68/*
Manuel Pégourié-Gonnardfd3e4fb2018-03-13 11:53:30 +010069 * X.509 CRL v2 extensions
70 *
71 * We currently don't parse any extension's content, but we do check that the
72 * list of extensions is well-formed and abort on critical extensions (that
73 * are unsupported as we don't support any extension so far)
Paul Bakker7c6b2c32013-09-16 13:49:26 +020074 */
Gilles Peskine449bd832023-01-11 14:50:10 +010075static int x509_get_crl_ext(unsigned char **p,
76 const unsigned char *end,
77 mbedtls_x509_buf *ext)
Paul Bakker7c6b2c32013-09-16 13:49:26 +020078{
Janos Follath865b3eb2019-12-16 11:46:15 +000079 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker7c6b2c32013-09-16 13:49:26 +020080
Gilles Peskine449bd832023-01-11 14:50:10 +010081 if (*p == end) {
82 return 0;
83 }
Hanno Becker12f62fb2019-02-12 17:22:36 +000084
Manuel Pégourié-Gonnardfd3e4fb2018-03-13 11:53:30 +010085 /*
86 * crlExtensions [0] EXPLICIT Extensions OPTIONAL
87 * -- if present, version MUST be v2
88 */
Gilles Peskine449bd832023-01-11 14:50:10 +010089 if ((ret = mbedtls_x509_get_ext(p, end, ext, 0)) != 0) {
90 return ret;
91 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +020092
Hanno Becker12f62fb2019-02-12 17:22:36 +000093 end = ext->p + ext->len;
94
Gilles Peskine449bd832023-01-11 14:50:10 +010095 while (*p < end) {
Manuel Pégourié-Gonnardfd3e4fb2018-03-13 11:53:30 +010096 /*
97 * Extension ::= SEQUENCE {
98 * extnID OBJECT IDENTIFIER,
99 * critical BOOLEAN DEFAULT FALSE,
100 * extnValue OCTET STRING }
101 */
102 int is_critical = 0;
103 const unsigned char *end_ext_data;
104 size_t len;
105
106 /* Get enclosing sequence tag */
Gilles Peskine449bd832023-01-11 14:50:10 +0100107 if ((ret = mbedtls_asn1_get_tag(p, end, &len,
108 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
109 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
110 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200111
Manuel Pégourié-Gonnardfd3e4fb2018-03-13 11:53:30 +0100112 end_ext_data = *p + len;
113
114 /* Get OID (currently ignored) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100115 if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &len,
116 MBEDTLS_ASN1_OID)) != 0) {
117 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
Manuel Pégourié-Gonnardfd3e4fb2018-03-13 11:53:30 +0100118 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200119 *p += len;
Manuel Pégourié-Gonnardfd3e4fb2018-03-13 11:53:30 +0100120
121 /* Get optional critical */
Gilles Peskine449bd832023-01-11 14:50:10 +0100122 if ((ret = mbedtls_asn1_get_bool(p, end_ext_data,
123 &is_critical)) != 0 &&
124 (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) {
125 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
Manuel Pégourié-Gonnardfd3e4fb2018-03-13 11:53:30 +0100126 }
127
128 /* Data should be octet string type */
Gilles Peskine449bd832023-01-11 14:50:10 +0100129 if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &len,
130 MBEDTLS_ASN1_OCTET_STRING)) != 0) {
131 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
132 }
Manuel Pégourié-Gonnardfd3e4fb2018-03-13 11:53:30 +0100133
134 /* Ignore data so far and just check its length */
135 *p += len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100136 if (*p != end_ext_data) {
137 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
138 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
139 }
Manuel Pégourié-Gonnardfd3e4fb2018-03-13 11:53:30 +0100140
141 /* Abort on (unsupported) critical extensions */
Gilles Peskine449bd832023-01-11 14:50:10 +0100142 if (is_critical) {
143 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
144 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
145 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200146 }
147
Gilles Peskine449bd832023-01-11 14:50:10 +0100148 if (*p != end) {
149 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
150 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
151 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200152
Gilles Peskine449bd832023-01-11 14:50:10 +0100153 return 0;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200154}
155
156/*
157 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
158 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100159static int x509_get_crl_entry_ext(unsigned char **p,
160 const unsigned char *end,
161 mbedtls_x509_buf *ext)
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200162{
Janos Follath865b3eb2019-12-16 11:46:15 +0000163 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200164 size_t len = 0;
165
166 /* OPTIONAL */
Gilles Peskine449bd832023-01-11 14:50:10 +0100167 if (end <= *p) {
168 return 0;
169 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200170
171 ext->tag = **p;
172 ext->p = *p;
173
174 /*
175 * Get CRL-entry extension sequence header
176 * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
177 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100178 if ((ret = mbedtls_asn1_get_tag(p, end, &ext->len,
179 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
180 if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200181 ext->p = NULL;
Gilles Peskine449bd832023-01-11 14:50:10 +0100182 return 0;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200183 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100184 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200185 }
186
Paul Bakker9af723c2014-05-01 13:03:14 +0200187 end = *p + ext->len;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200188
Gilles Peskine449bd832023-01-11 14:50:10 +0100189 if (end != *p + ext->len) {
190 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
191 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
192 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200193
Gilles Peskine449bd832023-01-11 14:50:10 +0100194 while (*p < end) {
195 if ((ret = mbedtls_asn1_get_tag(p, end, &len,
196 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
197 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
198 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200199
200 *p += len;
201 }
202
Gilles Peskine449bd832023-01-11 14:50:10 +0100203 if (*p != end) {
204 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
205 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
206 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200207
Gilles Peskine449bd832023-01-11 14:50:10 +0100208 return 0;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200209}
210
211/*
212 * X.509 CRL Entries
213 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100214static int x509_get_entries(unsigned char **p,
215 const unsigned char *end,
216 mbedtls_x509_crl_entry *entry)
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200217{
Janos Follath865b3eb2019-12-16 11:46:15 +0000218 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200219 size_t entry_len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200220 mbedtls_x509_crl_entry *cur_entry = entry;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200221
Gilles Peskine449bd832023-01-11 14:50:10 +0100222 if (*p == end) {
223 return 0;
224 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200225
Gilles Peskine449bd832023-01-11 14:50:10 +0100226 if ((ret = mbedtls_asn1_get_tag(p, end, &entry_len,
227 MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED)) != 0) {
228 if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
229 return 0;
230 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200231
Gilles Peskine449bd832023-01-11 14:50:10 +0100232 return ret;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200233 }
234
235 end = *p + entry_len;
236
Gilles Peskine449bd832023-01-11 14:50:10 +0100237 while (*p < end) {
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200238 size_t len2;
239 const unsigned char *end2;
240
Gilles Peskine5dd5a492020-07-16 18:26:29 +0200241 cur_entry->raw.tag = **p;
Gilles Peskine449bd832023-01-11 14:50:10 +0100242 if ((ret = mbedtls_asn1_get_tag(p, end, &len2,
243 MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED)) != 0) {
244 return ret;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200245 }
246
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200247 cur_entry->raw.p = *p;
248 cur_entry->raw.len = len2;
249 end2 = *p + len2;
250
Gilles Peskine449bd832023-01-11 14:50:10 +0100251 if ((ret = mbedtls_x509_get_serial(p, end2, &cur_entry->serial)) != 0) {
252 return ret;
253 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200254
Gilles Peskine449bd832023-01-11 14:50:10 +0100255 if ((ret = mbedtls_x509_get_time(p, end2,
256 &cur_entry->revocation_date)) != 0) {
257 return ret;
258 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200259
Gilles Peskine449bd832023-01-11 14:50:10 +0100260 if ((ret = x509_get_crl_entry_ext(p, end2,
261 &cur_entry->entry_ext)) != 0) {
262 return ret;
263 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200264
Gilles Peskine449bd832023-01-11 14:50:10 +0100265 if (*p < end) {
266 cur_entry->next = mbedtls_calloc(1, sizeof(mbedtls_x509_crl_entry));
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200267
Gilles Peskine449bd832023-01-11 14:50:10 +0100268 if (cur_entry->next == NULL) {
269 return MBEDTLS_ERR_X509_ALLOC_FAILED;
270 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200271
272 cur_entry = cur_entry->next;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200273 }
274 }
275
Gilles Peskine449bd832023-01-11 14:50:10 +0100276 return 0;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200277}
278
279/*
Manuel Pégourié-Gonnard426d4ae2014-11-19 16:58:28 +0100280 * Parse one CRLs in DER format and append it to the chained list
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200281 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100282int mbedtls_x509_crl_parse_der(mbedtls_x509_crl *chain,
283 const unsigned char *buf, size_t buflen)
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200284{
Janos Follath865b3eb2019-12-16 11:46:15 +0000285 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200286 size_t len;
Andres Amaya Garciaf1ee6352017-07-06 10:06:58 +0100287 unsigned char *p = NULL, *end = NULL;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200288 mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
289 mbedtls_x509_crl *crl = chain;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200290
291 /*
292 * Check for valid input
293 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100294 if (crl == NULL || buf == NULL) {
295 return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
296 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200297
Gilles Peskine449bd832023-01-11 14:50:10 +0100298 memset(&sig_params1, 0, sizeof(mbedtls_x509_buf));
299 memset(&sig_params2, 0, sizeof(mbedtls_x509_buf));
300 memset(&sig_oid2, 0, sizeof(mbedtls_x509_buf));
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200301
302 /*
303 * Add new CRL on the end of the chain if needed.
304 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100305 while (crl->version != 0 && crl->next != NULL) {
Manuel Pégourié-Gonnard426d4ae2014-11-19 16:58:28 +0100306 crl = crl->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100307 }
Manuel Pégourié-Gonnard426d4ae2014-11-19 16:58:28 +0100308
Gilles Peskine449bd832023-01-11 14:50:10 +0100309 if (crl->version != 0 && crl->next == NULL) {
310 crl->next = mbedtls_calloc(1, sizeof(mbedtls_x509_crl));
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200311
Gilles Peskine449bd832023-01-11 14:50:10 +0100312 if (crl->next == NULL) {
313 mbedtls_x509_crl_free(crl);
314 return MBEDTLS_ERR_X509_ALLOC_FAILED;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200315 }
316
Gilles Peskine449bd832023-01-11 14:50:10 +0100317 mbedtls_x509_crl_init(crl->next);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200318 crl = crl->next;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200319 }
320
Manuel Pégourié-Gonnard426d4ae2014-11-19 16:58:28 +0100321 /*
322 * Copy raw DER-encoded CRL
323 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100324 if (buflen == 0) {
325 return MBEDTLS_ERR_X509_INVALID_FORMAT;
326 }
Andres Amaya Garciac9d62262017-12-12 20:15:03 +0000327
Gilles Peskine449bd832023-01-11 14:50:10 +0100328 p = mbedtls_calloc(1, buflen);
329 if (p == NULL) {
330 return MBEDTLS_ERR_X509_ALLOC_FAILED;
331 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200332
Gilles Peskine449bd832023-01-11 14:50:10 +0100333 memcpy(p, buf, buflen);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200334
335 crl->raw.p = p;
Manuel Pégourié-Gonnard426d4ae2014-11-19 16:58:28 +0100336 crl->raw.len = buflen;
337
338 end = p + buflen;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200339
340 /*
341 * CertificateList ::= SEQUENCE {
342 * tbsCertList TBSCertList,
343 * signatureAlgorithm AlgorithmIdentifier,
344 * signatureValue BIT STRING }
345 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100346 if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
347 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
348 mbedtls_x509_crl_free(crl);
349 return MBEDTLS_ERR_X509_INVALID_FORMAT;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200350 }
351
Gilles Peskine449bd832023-01-11 14:50:10 +0100352 if (len != (size_t) (end - p)) {
353 mbedtls_x509_crl_free(crl);
354 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT,
355 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200356 }
357
358 /*
359 * TBSCertList ::= SEQUENCE {
360 */
361 crl->tbs.p = p;
362
Gilles Peskine449bd832023-01-11 14:50:10 +0100363 if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
364 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
365 mbedtls_x509_crl_free(crl);
366 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200367 }
368
369 end = p + len;
Dave Rodgmane4a6f5a2023-11-04 12:20:09 +0000370 crl->tbs.len = (size_t) (end - crl->tbs.p);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200371
372 /*
373 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
374 * -- if present, MUST be v2
375 *
376 * signature AlgorithmIdentifier
377 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100378 if ((ret = x509_crl_get_version(&p, end, &crl->version)) != 0 ||
379 (ret = mbedtls_x509_get_alg(&p, end, &crl->sig_oid, &sig_params1)) != 0) {
380 mbedtls_x509_crl_free(crl);
381 return ret;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200382 }
383
Gilles Peskine449bd832023-01-11 14:50:10 +0100384 if (crl->version < 0 || crl->version > 1) {
385 mbedtls_x509_crl_free(crl);
386 return MBEDTLS_ERR_X509_UNKNOWN_VERSION;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200387 }
388
Andres AG4f753c12017-02-10 14:39:58 +0000389 crl->version++;
390
Gilles Peskine449bd832023-01-11 14:50:10 +0100391 if ((ret = mbedtls_x509_get_sig_alg(&crl->sig_oid, &sig_params1,
392 &crl->sig_md, &crl->sig_pk,
393 &crl->sig_opts)) != 0) {
394 mbedtls_x509_crl_free(crl);
395 return MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200396 }
397
398 /*
399 * issuer Name
400 */
401 crl->issuer_raw.p = p;
402
Gilles Peskine449bd832023-01-11 14:50:10 +0100403 if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
404 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
405 mbedtls_x509_crl_free(crl);
406 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200407 }
408
Gilles Peskine449bd832023-01-11 14:50:10 +0100409 if ((ret = mbedtls_x509_get_name(&p, p + len, &crl->issuer)) != 0) {
410 mbedtls_x509_crl_free(crl);
411 return ret;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200412 }
413
Dave Rodgmane4a6f5a2023-11-04 12:20:09 +0000414 crl->issuer_raw.len = (size_t) (p - crl->issuer_raw.p);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200415
416 /*
417 * thisUpdate Time
418 * nextUpdate Time OPTIONAL
419 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100420 if ((ret = mbedtls_x509_get_time(&p, end, &crl->this_update)) != 0) {
421 mbedtls_x509_crl_free(crl);
422 return ret;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200423 }
424
Gilles Peskine449bd832023-01-11 14:50:10 +0100425 if ((ret = mbedtls_x509_get_time(&p, end, &crl->next_update)) != 0) {
426 if (ret != (MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE,
427 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) &&
428 ret != (MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE,
429 MBEDTLS_ERR_ASN1_OUT_OF_DATA))) {
430 mbedtls_x509_crl_free(crl);
431 return ret;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200432 }
433 }
434
435 /*
436 * revokedCertificates SEQUENCE OF SEQUENCE {
437 * userCertificate CertificateSerialNumber,
438 * revocationDate Time,
439 * crlEntryExtensions Extensions OPTIONAL
440 * -- if present, MUST be v2
441 * } OPTIONAL
442 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100443 if ((ret = x509_get_entries(&p, end, &crl->entry)) != 0) {
444 mbedtls_x509_crl_free(crl);
445 return ret;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200446 }
447
448 /*
449 * crlExtensions EXPLICIT Extensions OPTIONAL
450 * -- if present, MUST be v2
451 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100452 if (crl->version == 2) {
453 ret = x509_get_crl_ext(&p, end, &crl->crl_ext);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200454
Gilles Peskine449bd832023-01-11 14:50:10 +0100455 if (ret != 0) {
456 mbedtls_x509_crl_free(crl);
457 return ret;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200458 }
459 }
460
Gilles Peskine449bd832023-01-11 14:50:10 +0100461 if (p != end) {
462 mbedtls_x509_crl_free(crl);
463 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT,
464 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200465 }
466
467 end = crl->raw.p + crl->raw.len;
468
469 /*
470 * signatureAlgorithm AlgorithmIdentifier,
471 * signatureValue BIT STRING
472 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100473 if ((ret = mbedtls_x509_get_alg(&p, end, &sig_oid2, &sig_params2)) != 0) {
474 mbedtls_x509_crl_free(crl);
475 return ret;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200476 }
477
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 if (crl->sig_oid.len != sig_oid2.len ||
479 memcmp(crl->sig_oid.p, sig_oid2.p, crl->sig_oid.len) != 0 ||
Manuel Pégourié-Gonnarddddbb1d2014-06-05 17:02:24 +0200480 sig_params1.len != sig_params2.len ||
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 (sig_params1.len != 0 &&
482 memcmp(sig_params1.p, sig_params2.p, sig_params1.len) != 0)) {
483 mbedtls_x509_crl_free(crl);
484 return MBEDTLS_ERR_X509_SIG_MISMATCH;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200485 }
486
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 if ((ret = mbedtls_x509_get_sig(&p, end, &crl->sig)) != 0) {
488 mbedtls_x509_crl_free(crl);
489 return ret;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200490 }
491
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 if (p != end) {
493 mbedtls_x509_crl_free(crl);
494 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT,
495 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200496 }
497
Gilles Peskine449bd832023-01-11 14:50:10 +0100498 return 0;
Manuel Pégourié-Gonnard426d4ae2014-11-19 16:58:28 +0100499}
500
501/*
502 * Parse one or more CRLs and add them to the chained list
503 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100504int mbedtls_x509_crl_parse(mbedtls_x509_crl *chain, const unsigned char *buf, size_t buflen)
Manuel Pégourié-Gonnard426d4ae2014-11-19 16:58:28 +0100505{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200506#if defined(MBEDTLS_PEM_PARSE_C)
Janos Follath865b3eb2019-12-16 11:46:15 +0000507 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Benjamin Kier36050732019-05-30 14:49:17 -0400508 size_t use_len = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200509 mbedtls_pem_context pem;
Manuel Pégourié-Gonnard6ed2d922014-11-19 19:05:03 +0100510 int is_pem = 0;
Manuel Pégourié-Gonnard426d4ae2014-11-19 16:58:28 +0100511
Gilles Peskine449bd832023-01-11 14:50:10 +0100512 if (chain == NULL || buf == NULL) {
513 return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
514 }
Manuel Pégourié-Gonnard426d4ae2014-11-19 16:58:28 +0100515
Gilles Peskine449bd832023-01-11 14:50:10 +0100516 do {
517 mbedtls_pem_init(&pem);
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200518
Simon Butcher97e82902016-05-19 00:22:37 +0100519 // Avoid calling mbedtls_pem_read_buffer() on non-null-terminated
520 // string
Gilles Peskine449bd832023-01-11 14:50:10 +0100521 if (buflen == 0 || buf[buflen - 1] != '\0') {
Simon Butcher97e82902016-05-19 00:22:37 +0100522 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100523 } else {
524 ret = mbedtls_pem_read_buffer(&pem,
525 "-----BEGIN X509 CRL-----",
526 "-----END X509 CRL-----",
527 buf, NULL, 0, &use_len);
528 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200529
Gilles Peskine449bd832023-01-11 14:50:10 +0100530 if (ret == 0) {
Manuel Pégourié-Gonnard6ed2d922014-11-19 19:05:03 +0100531 /*
532 * Was PEM encoded
533 */
534 is_pem = 1;
535
536 buflen -= use_len;
537 buf += use_len;
538
Gilles Peskine449bd832023-01-11 14:50:10 +0100539 if ((ret = mbedtls_x509_crl_parse_der(chain,
540 pem.buf, pem.buflen)) != 0) {
541 mbedtls_pem_free(&pem);
542 return ret;
Manuel Pégourié-Gonnard6ed2d922014-11-19 19:05:03 +0100543 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100544 } else if (is_pem) {
545 mbedtls_pem_free(&pem);
546 return ret;
Manuel Pégourié-Gonnard6ed2d922014-11-19 19:05:03 +0100547 }
Andres AG5708dcb2016-12-08 17:19:21 +0000548
Gilles Peskine449bd832023-01-11 14:50:10 +0100549 mbedtls_pem_free(&pem);
Manuel Pégourié-Gonnard6ed2d922014-11-19 19:05:03 +0100550 }
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200551 /* In the PEM case, buflen is 1 at the end, for the terminated NULL byte.
552 * And a valid CRL cannot be less than 1 byte anyway. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100553 while (is_pem && buflen > 1);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200554
Gilles Peskine449bd832023-01-11 14:50:10 +0100555 if (is_pem) {
556 return 0;
557 } else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200558#endif /* MBEDTLS_PEM_PARSE_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100559 return mbedtls_x509_crl_parse_der(chain, buf, buflen);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200560}
561
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200562#if defined(MBEDTLS_FS_IO)
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200563/*
564 * Load one or more CRLs and add them to the chained list
565 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100566int mbedtls_x509_crl_parse_file(mbedtls_x509_crl *chain, const char *path)
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200567{
Janos Follath865b3eb2019-12-16 11:46:15 +0000568 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200569 size_t n;
570 unsigned char *buf;
571
Gilles Peskine449bd832023-01-11 14:50:10 +0100572 if ((ret = mbedtls_pk_load_file(path, &buf, &n)) != 0) {
573 return ret;
574 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200575
Gilles Peskine449bd832023-01-11 14:50:10 +0100576 ret = mbedtls_x509_crl_parse(chain, buf, n);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200577
Tom Cosgroveca8c61b2023-07-17 15:17:40 +0100578 mbedtls_zeroize_and_free(buf, n);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200579
Gilles Peskine449bd832023-01-11 14:50:10 +0100580 return ret;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200581}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200582#endif /* MBEDTLS_FS_IO */
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200583
Hanno Becker612a2f12020-10-09 09:19:39 +0100584#if !defined(MBEDTLS_X509_REMOVE_INFO)
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200585/*
586 * Return an informational string about the certificate.
587 */
588#define BEFORE_COLON 14
589#define BC "14"
590/*
591 * Return an informational string about the CRL.
592 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100593int mbedtls_x509_crl_info(char *buf, size_t size, const char *prefix,
594 const mbedtls_x509_crl *crl)
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200595{
Janos Follath865b3eb2019-12-16 11:46:15 +0000596 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200597 size_t n;
598 char *p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200599 const mbedtls_x509_crl_entry *entry;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200600
601 p = buf;
602 n = size;
603
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 ret = mbedtls_snprintf(p, n, "%sCRL version : %d",
605 prefix, crl->version);
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200606 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200607
Gilles Peskine449bd832023-01-11 14:50:10 +0100608 ret = mbedtls_snprintf(p, n, "\n%sissuer name : ", prefix);
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200609 MBEDTLS_X509_SAFE_SNPRINTF;
Gilles Peskine449bd832023-01-11 14:50:10 +0100610 ret = mbedtls_x509_dn_gets(p, n, &crl->issuer);
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200611 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200612
Gilles Peskine449bd832023-01-11 14:50:10 +0100613 ret = mbedtls_snprintf(p, n, "\n%sthis update : " \
614 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
615 crl->this_update.year, crl->this_update.mon,
616 crl->this_update.day, crl->this_update.hour,
617 crl->this_update.min, crl->this_update.sec);
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200618 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200619
Gilles Peskine449bd832023-01-11 14:50:10 +0100620 ret = mbedtls_snprintf(p, n, "\n%snext update : " \
621 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
622 crl->next_update.year, crl->next_update.mon,
623 crl->next_update.day, crl->next_update.hour,
624 crl->next_update.min, crl->next_update.sec);
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200625 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200626
627 entry = &crl->entry;
628
Gilles Peskine449bd832023-01-11 14:50:10 +0100629 ret = mbedtls_snprintf(p, n, "\n%sRevoked certificates:",
630 prefix);
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200631 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200632
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 while (entry != NULL && entry->raw.len != 0) {
634 ret = mbedtls_snprintf(p, n, "\n%sserial number: ",
635 prefix);
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200636 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200637
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 ret = mbedtls_x509_serial_gets(p, n, &entry->serial);
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200639 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200640
Gilles Peskine449bd832023-01-11 14:50:10 +0100641 ret = mbedtls_snprintf(p, n, " revocation date: " \
642 "%04d-%02d-%02d %02d:%02d:%02d",
643 entry->revocation_date.year, entry->revocation_date.mon,
644 entry->revocation_date.day, entry->revocation_date.hour,
645 entry->revocation_date.min, entry->revocation_date.sec);
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200646 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200647
648 entry = entry->next;
649 }
650
Gilles Peskine449bd832023-01-11 14:50:10 +0100651 ret = mbedtls_snprintf(p, n, "\n%ssigned using : ", prefix);
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200652 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200653
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 ret = mbedtls_x509_sig_alg_gets(p, n, &crl->sig_oid, crl->sig_pk, crl->sig_md,
655 crl->sig_opts);
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200656 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200657
Gilles Peskine449bd832023-01-11 14:50:10 +0100658 ret = mbedtls_snprintf(p, n, "\n");
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200659 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200660
Gilles Peskine449bd832023-01-11 14:50:10 +0100661 return (int) (size - n);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200662}
Hanno Becker612a2f12020-10-09 09:19:39 +0100663#endif /* MBEDTLS_X509_REMOVE_INFO */
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200664
665/*
Paul Bakker369d2eb2013-09-18 11:58:25 +0200666 * Initialize a CRL chain
667 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100668void mbedtls_x509_crl_init(mbedtls_x509_crl *crl)
Paul Bakker369d2eb2013-09-18 11:58:25 +0200669{
Gilles Peskine449bd832023-01-11 14:50:10 +0100670 memset(crl, 0, sizeof(mbedtls_x509_crl));
Paul Bakker369d2eb2013-09-18 11:58:25 +0200671}
672
673/*
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200674 * Unallocate all CRL data
675 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100676void mbedtls_x509_crl_free(mbedtls_x509_crl *crl)
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200677{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200678 mbedtls_x509_crl *crl_cur = crl;
679 mbedtls_x509_crl *crl_prv;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200680 mbedtls_x509_crl_entry *entry_cur;
681 mbedtls_x509_crl_entry *entry_prv;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200682
Gilles Peskine449bd832023-01-11 14:50:10 +0100683 while (crl_cur != NULL) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200684#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100685 mbedtls_free(crl_cur->sig_opts);
Manuel Pégourié-Gonnardf75f2f72014-06-05 15:14:28 +0200686#endif
687
Gilles Peskine449bd832023-01-11 14:50:10 +0100688 mbedtls_asn1_free_named_data_list_shallow(crl_cur->issuer.next);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200689
690 entry_cur = crl_cur->entry.next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100691 while (entry_cur != NULL) {
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200692 entry_prv = entry_cur;
693 entry_cur = entry_cur->next;
Tom Cosgroveca8c61b2023-07-17 15:17:40 +0100694 mbedtls_zeroize_and_free(entry_prv,
Gilles Peskine449bd832023-01-11 14:50:10 +0100695 sizeof(mbedtls_x509_crl_entry));
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200696 }
697
Gilles Peskine449bd832023-01-11 14:50:10 +0100698 if (crl_cur->raw.p != NULL) {
Tom Cosgroveca8c61b2023-07-17 15:17:40 +0100699 mbedtls_zeroize_and_free(crl_cur->raw.p, crl_cur->raw.len);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200700 }
701
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200702 crl_prv = crl_cur;
703 crl_cur = crl_cur->next;
704
Gilles Peskine449bd832023-01-11 14:50:10 +0100705 mbedtls_platform_zeroize(crl_prv, sizeof(mbedtls_x509_crl));
706 if (crl_prv != crl) {
707 mbedtls_free(crl_prv);
708 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200709 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200710}
711
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200712#endif /* MBEDTLS_X509_CRL_PARSE_C */