blob: 81af93b6a9888931cd98b9bf336f508df1fc78c0 [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
Harry Ramsey0f6bc412024-10-04 10:36:54 +010018#include "x509_internal.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,
Valerio Setti68878cc2025-04-10 23:30:26 +0200392 &crl->sig_md, &crl->sig_pk)) != 0) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100393 mbedtls_x509_crl_free(crl);
394 return MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200395 }
396
397 /*
398 * issuer Name
399 */
400 crl->issuer_raw.p = p;
401
Gilles Peskine449bd832023-01-11 14:50:10 +0100402 if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
403 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
404 mbedtls_x509_crl_free(crl);
405 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200406 }
407
Gilles Peskine449bd832023-01-11 14:50:10 +0100408 if ((ret = mbedtls_x509_get_name(&p, p + len, &crl->issuer)) != 0) {
409 mbedtls_x509_crl_free(crl);
410 return ret;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200411 }
412
Dave Rodgmane4a6f5a2023-11-04 12:20:09 +0000413 crl->issuer_raw.len = (size_t) (p - crl->issuer_raw.p);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200414
415 /*
416 * thisUpdate Time
417 * nextUpdate Time OPTIONAL
418 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100419 if ((ret = mbedtls_x509_get_time(&p, end, &crl->this_update)) != 0) {
420 mbedtls_x509_crl_free(crl);
421 return ret;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200422 }
423
Gilles Peskine449bd832023-01-11 14:50:10 +0100424 if ((ret = mbedtls_x509_get_time(&p, end, &crl->next_update)) != 0) {
425 if (ret != (MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE,
426 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) &&
427 ret != (MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE,
428 MBEDTLS_ERR_ASN1_OUT_OF_DATA))) {
429 mbedtls_x509_crl_free(crl);
430 return ret;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200431 }
432 }
433
434 /*
435 * revokedCertificates SEQUENCE OF SEQUENCE {
436 * userCertificate CertificateSerialNumber,
437 * revocationDate Time,
438 * crlEntryExtensions Extensions OPTIONAL
439 * -- if present, MUST be v2
440 * } OPTIONAL
441 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100442 if ((ret = x509_get_entries(&p, end, &crl->entry)) != 0) {
443 mbedtls_x509_crl_free(crl);
444 return ret;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200445 }
446
447 /*
448 * crlExtensions EXPLICIT Extensions OPTIONAL
449 * -- if present, MUST be v2
450 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100451 if (crl->version == 2) {
452 ret = x509_get_crl_ext(&p, end, &crl->crl_ext);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200453
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 if (ret != 0) {
455 mbedtls_x509_crl_free(crl);
456 return ret;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200457 }
458 }
459
Gilles Peskine449bd832023-01-11 14:50:10 +0100460 if (p != end) {
461 mbedtls_x509_crl_free(crl);
462 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT,
463 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200464 }
465
466 end = crl->raw.p + crl->raw.len;
467
468 /*
469 * signatureAlgorithm AlgorithmIdentifier,
470 * signatureValue BIT STRING
471 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100472 if ((ret = mbedtls_x509_get_alg(&p, end, &sig_oid2, &sig_params2)) != 0) {
473 mbedtls_x509_crl_free(crl);
474 return ret;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200475 }
476
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 if (crl->sig_oid.len != sig_oid2.len ||
478 memcmp(crl->sig_oid.p, sig_oid2.p, crl->sig_oid.len) != 0 ||
Manuel Pégourié-Gonnarddddbb1d2014-06-05 17:02:24 +0200479 sig_params1.len != sig_params2.len ||
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 (sig_params1.len != 0 &&
481 memcmp(sig_params1.p, sig_params2.p, sig_params1.len) != 0)) {
482 mbedtls_x509_crl_free(crl);
483 return MBEDTLS_ERR_X509_SIG_MISMATCH;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200484 }
485
Gilles Peskine449bd832023-01-11 14:50:10 +0100486 if ((ret = mbedtls_x509_get_sig(&p, end, &crl->sig)) != 0) {
487 mbedtls_x509_crl_free(crl);
488 return ret;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200489 }
490
Gilles Peskine449bd832023-01-11 14:50:10 +0100491 if (p != end) {
492 mbedtls_x509_crl_free(crl);
493 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT,
494 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200495 }
496
Gilles Peskine449bd832023-01-11 14:50:10 +0100497 return 0;
Manuel Pégourié-Gonnard426d4ae2014-11-19 16:58:28 +0100498}
499
500/*
501 * Parse one or more CRLs and add them to the chained list
502 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100503int mbedtls_x509_crl_parse(mbedtls_x509_crl *chain, const unsigned char *buf, size_t buflen)
Manuel Pégourié-Gonnard426d4ae2014-11-19 16:58:28 +0100504{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200505#if defined(MBEDTLS_PEM_PARSE_C)
Janos Follath865b3eb2019-12-16 11:46:15 +0000506 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Benjamin Kier36050732019-05-30 14:49:17 -0400507 size_t use_len = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200508 mbedtls_pem_context pem;
Manuel Pégourié-Gonnard6ed2d922014-11-19 19:05:03 +0100509 int is_pem = 0;
Manuel Pégourié-Gonnard426d4ae2014-11-19 16:58:28 +0100510
Gilles Peskine449bd832023-01-11 14:50:10 +0100511 if (chain == NULL || buf == NULL) {
512 return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
513 }
Manuel Pégourié-Gonnard426d4ae2014-11-19 16:58:28 +0100514
Gilles Peskine449bd832023-01-11 14:50:10 +0100515 do {
516 mbedtls_pem_init(&pem);
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200517
Simon Butcher97e82902016-05-19 00:22:37 +0100518 // Avoid calling mbedtls_pem_read_buffer() on non-null-terminated
519 // string
Gilles Peskine449bd832023-01-11 14:50:10 +0100520 if (buflen == 0 || buf[buflen - 1] != '\0') {
Simon Butcher97e82902016-05-19 00:22:37 +0100521 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100522 } else {
523 ret = mbedtls_pem_read_buffer(&pem,
524 "-----BEGIN X509 CRL-----",
525 "-----END X509 CRL-----",
526 buf, NULL, 0, &use_len);
527 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200528
Gilles Peskine449bd832023-01-11 14:50:10 +0100529 if (ret == 0) {
Manuel Pégourié-Gonnard6ed2d922014-11-19 19:05:03 +0100530 /*
531 * Was PEM encoded
532 */
533 is_pem = 1;
534
535 buflen -= use_len;
536 buf += use_len;
537
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 if ((ret = mbedtls_x509_crl_parse_der(chain,
539 pem.buf, pem.buflen)) != 0) {
540 mbedtls_pem_free(&pem);
541 return ret;
Manuel Pégourié-Gonnard6ed2d922014-11-19 19:05:03 +0100542 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100543 } else if (is_pem) {
544 mbedtls_pem_free(&pem);
545 return ret;
Manuel Pégourié-Gonnard6ed2d922014-11-19 19:05:03 +0100546 }
Andres AG5708dcb2016-12-08 17:19:21 +0000547
Gilles Peskine449bd832023-01-11 14:50:10 +0100548 mbedtls_pem_free(&pem);
Manuel Pégourié-Gonnard6ed2d922014-11-19 19:05:03 +0100549 }
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200550 /* In the PEM case, buflen is 1 at the end, for the terminated NULL byte.
551 * And a valid CRL cannot be less than 1 byte anyway. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100552 while (is_pem && buflen > 1);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200553
Gilles Peskine449bd832023-01-11 14:50:10 +0100554 if (is_pem) {
555 return 0;
556 } else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200557#endif /* MBEDTLS_PEM_PARSE_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100558 return mbedtls_x509_crl_parse_der(chain, buf, buflen);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200559}
560
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200561#if defined(MBEDTLS_FS_IO)
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200562/*
563 * Load one or more CRLs and add them to the chained list
564 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100565int mbedtls_x509_crl_parse_file(mbedtls_x509_crl *chain, const char *path)
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200566{
Janos Follath865b3eb2019-12-16 11:46:15 +0000567 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200568 size_t n;
569 unsigned char *buf;
570
Gilles Peskine449bd832023-01-11 14:50:10 +0100571 if ((ret = mbedtls_pk_load_file(path, &buf, &n)) != 0) {
572 return ret;
573 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200574
Gilles Peskine449bd832023-01-11 14:50:10 +0100575 ret = mbedtls_x509_crl_parse(chain, buf, n);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200576
Tom Cosgroveca8c61b2023-07-17 15:17:40 +0100577 mbedtls_zeroize_and_free(buf, n);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200578
Gilles Peskine449bd832023-01-11 14:50:10 +0100579 return ret;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200580}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200581#endif /* MBEDTLS_FS_IO */
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200582
Hanno Becker612a2f12020-10-09 09:19:39 +0100583#if !defined(MBEDTLS_X509_REMOVE_INFO)
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200584/*
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200585 * Return an informational string about the CRL.
586 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100587int mbedtls_x509_crl_info(char *buf, size_t size, const char *prefix,
588 const mbedtls_x509_crl *crl)
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200589{
Janos Follath865b3eb2019-12-16 11:46:15 +0000590 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200591 size_t n;
592 char *p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200593 const mbedtls_x509_crl_entry *entry;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200594
595 p = buf;
596 n = size;
597
Gilles Peskine449bd832023-01-11 14:50:10 +0100598 ret = mbedtls_snprintf(p, n, "%sCRL version : %d",
599 prefix, crl->version);
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200600 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200601
Gilles Peskine449bd832023-01-11 14:50:10 +0100602 ret = mbedtls_snprintf(p, n, "\n%sissuer name : ", prefix);
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200603 MBEDTLS_X509_SAFE_SNPRINTF;
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 ret = mbedtls_x509_dn_gets(p, n, &crl->issuer);
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200605 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200606
Gilles Peskine449bd832023-01-11 14:50:10 +0100607 ret = mbedtls_snprintf(p, n, "\n%sthis update : " \
608 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
609 crl->this_update.year, crl->this_update.mon,
610 crl->this_update.day, crl->this_update.hour,
611 crl->this_update.min, crl->this_update.sec);
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200612 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200613
Gilles Peskine449bd832023-01-11 14:50:10 +0100614 ret = mbedtls_snprintf(p, n, "\n%snext update : " \
615 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
616 crl->next_update.year, crl->next_update.mon,
617 crl->next_update.day, crl->next_update.hour,
618 crl->next_update.min, crl->next_update.sec);
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200619 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200620
621 entry = &crl->entry;
622
Gilles Peskine449bd832023-01-11 14:50:10 +0100623 ret = mbedtls_snprintf(p, n, "\n%sRevoked certificates:",
624 prefix);
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200625 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200626
Gilles Peskine449bd832023-01-11 14:50:10 +0100627 while (entry != NULL && entry->raw.len != 0) {
628 ret = mbedtls_snprintf(p, n, "\n%sserial number: ",
629 prefix);
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200630 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200631
Gilles Peskine449bd832023-01-11 14:50:10 +0100632 ret = mbedtls_x509_serial_gets(p, n, &entry->serial);
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200633 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200634
Gilles Peskine449bd832023-01-11 14:50:10 +0100635 ret = mbedtls_snprintf(p, n, " revocation date: " \
636 "%04d-%02d-%02d %02d:%02d:%02d",
637 entry->revocation_date.year, entry->revocation_date.mon,
638 entry->revocation_date.day, entry->revocation_date.hour,
639 entry->revocation_date.min, entry->revocation_date.sec);
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200640 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200641
642 entry = entry->next;
643 }
644
Gilles Peskine449bd832023-01-11 14:50:10 +0100645 ret = mbedtls_snprintf(p, n, "\n%ssigned using : ", prefix);
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200646 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200647
Gilles Peskine449bd832023-01-11 14:50:10 +0100648 ret = mbedtls_x509_sig_alg_gets(p, n, &crl->sig_oid, crl->sig_pk, crl->sig_md,
649 crl->sig_opts);
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200650 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200651
Gilles Peskine449bd832023-01-11 14:50:10 +0100652 ret = mbedtls_snprintf(p, n, "\n");
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200653 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200654
Gilles Peskine449bd832023-01-11 14:50:10 +0100655 return (int) (size - n);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200656}
Hanno Becker612a2f12020-10-09 09:19:39 +0100657#endif /* MBEDTLS_X509_REMOVE_INFO */
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200658
659/*
Paul Bakker369d2eb2013-09-18 11:58:25 +0200660 * Initialize a CRL chain
661 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100662void mbedtls_x509_crl_init(mbedtls_x509_crl *crl)
Paul Bakker369d2eb2013-09-18 11:58:25 +0200663{
Gilles Peskine449bd832023-01-11 14:50:10 +0100664 memset(crl, 0, sizeof(mbedtls_x509_crl));
Paul Bakker369d2eb2013-09-18 11:58:25 +0200665}
666
667/*
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200668 * Unallocate all CRL data
669 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100670void mbedtls_x509_crl_free(mbedtls_x509_crl *crl)
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200671{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200672 mbedtls_x509_crl *crl_cur = crl;
673 mbedtls_x509_crl *crl_prv;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200674 mbedtls_x509_crl_entry *entry_cur;
675 mbedtls_x509_crl_entry *entry_prv;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200676
Gilles Peskine449bd832023-01-11 14:50:10 +0100677 while (crl_cur != NULL) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100678 mbedtls_asn1_free_named_data_list_shallow(crl_cur->issuer.next);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200679
680 entry_cur = crl_cur->entry.next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100681 while (entry_cur != NULL) {
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200682 entry_prv = entry_cur;
683 entry_cur = entry_cur->next;
Tom Cosgroveca8c61b2023-07-17 15:17:40 +0100684 mbedtls_zeroize_and_free(entry_prv,
Gilles Peskine449bd832023-01-11 14:50:10 +0100685 sizeof(mbedtls_x509_crl_entry));
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200686 }
687
Gilles Peskine449bd832023-01-11 14:50:10 +0100688 if (crl_cur->raw.p != NULL) {
Tom Cosgroveca8c61b2023-07-17 15:17:40 +0100689 mbedtls_zeroize_and_free(crl_cur->raw.p, crl_cur->raw.len);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200690 }
691
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200692 crl_prv = crl_cur;
693 crl_cur = crl_cur->next;
694
Gilles Peskine449bd832023-01-11 14:50:10 +0100695 mbedtls_platform_zeroize(crl_prv, sizeof(mbedtls_x509_crl));
696 if (crl_prv != crl) {
697 mbedtls_free(crl_prv);
698 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200699 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200700}
701
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200702#endif /* MBEDTLS_X509_CRL_PARSE_C */