blob: 7901992e20d8dd9eb86cd8dc89cbb9839ff9f498 [file] [log] [blame]
Jens Wiklander817466c2018-05-22 13:49:31 +02001/*
Jens Wiklander32b31802023-10-06 16:59:46 +02002 * X.509 Certificate Revocation List (CRL) parsing
Jens Wiklander817466c2018-05-22 13:49:31 +02003 *
Jerome Forissier79013242021-07-28 10:24:04 +02004 * Copyright The Mbed TLS Contributors
Tom Van Eyckc1633172024-04-09 18:44:13 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Jens Wiklander817466c2018-05-22 13:49:31 +02006 */
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
Jerome Forissier79013242021-07-28 10:24:04 +020018#include "common.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020019
20#if defined(MBEDTLS_X509_CRL_PARSE_C)
21
22#include "mbedtls/x509_crl.h"
Tom Van Eyckc1633172024-04-09 18:44:13 +020023#include "x509_internal.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020024#include "mbedtls/error.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020025#include "mbedtls/oid.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010026#include "mbedtls/platform_util.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020027
28#include <string.h>
29
30#if defined(MBEDTLS_PEM_PARSE_C)
31#include "mbedtls/pem.h"
32#endif
33
Jens Wiklander817466c2018-05-22 13:49:31 +020034#include "mbedtls/platform.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020035
Jerome Forissier039e02d2022-08-09 17:10:15 +020036#if defined(MBEDTLS_HAVE_TIME)
Jens Wiklander817466c2018-05-22 13:49:31 +020037#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
38#include <windows.h>
39#else
40#include <time.h>
41#endif
Jerome Forissier039e02d2022-08-09 17:10:15 +020042#endif
Jens Wiklander817466c2018-05-22 13:49:31 +020043
44#if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32)
45#include <stdio.h>
46#endif
47
Jens Wiklander817466c2018-05-22 13:49:31 +020048/*
49 * Version ::= INTEGER { v1(0), v2(1) }
50 */
Jens Wiklander32b31802023-10-06 16:59:46 +020051static int x509_crl_get_version(unsigned char **p,
52 const unsigned char *end,
53 int *ver)
Jens Wiklander817466c2018-05-22 13:49:31 +020054{
Jerome Forissier11fa71b2020-04-20 17:17:56 +020055 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +020056
Jens Wiklander32b31802023-10-06 16:59:46 +020057 if ((ret = mbedtls_asn1_get_int(p, end, ver)) != 0) {
58 if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
Jens Wiklander817466c2018-05-22 13:49:31 +020059 *ver = 0;
Jens Wiklander32b31802023-10-06 16:59:46 +020060 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +020061 }
62
Jens Wiklander32b31802023-10-06 16:59:46 +020063 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_VERSION, ret);
Jens Wiklander817466c2018-05-22 13:49:31 +020064 }
65
Jens Wiklander32b31802023-10-06 16:59:46 +020066 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +020067}
68
69/*
Jens Wiklander3d3b0592019-03-20 15:30:29 +010070 * 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)
Jens Wiklander817466c2018-05-22 13:49:31 +020075 */
Jens Wiklander32b31802023-10-06 16:59:46 +020076static int x509_get_crl_ext(unsigned char **p,
77 const unsigned char *end,
78 mbedtls_x509_buf *ext)
Jens Wiklander817466c2018-05-22 13:49:31 +020079{
Jerome Forissier11fa71b2020-04-20 17:17:56 +020080 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +020081
Jens Wiklander32b31802023-10-06 16:59:46 +020082 if (*p == end) {
83 return 0;
84 }
Jerome Forissier5b25c762020-04-07 11:18:49 +020085
Jens Wiklander3d3b0592019-03-20 15:30:29 +010086 /*
87 * crlExtensions [0] EXPLICIT Extensions OPTIONAL
88 * -- if present, version MUST be v2
89 */
Jens Wiklander32b31802023-10-06 16:59:46 +020090 if ((ret = mbedtls_x509_get_ext(p, end, ext, 0)) != 0) {
91 return ret;
92 }
Jerome Forissier5b25c762020-04-07 11:18:49 +020093
94 end = ext->p + ext->len;
Jens Wiklander817466c2018-05-22 13:49:31 +020095
Jens Wiklander32b31802023-10-06 16:59:46 +020096 while (*p < end) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +010097 /*
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 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200108 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 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200112
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100113 end_ext_data = *p + len;
114
115 /* Get OID (currently ignored) */
Jens Wiklander32b31802023-10-06 16:59:46 +0200116 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);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100119 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200120 *p += len;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100121
122 /* Get optional critical */
Jens Wiklander32b31802023-10-06 16:59:46 +0200123 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);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100127 }
128
129 /* Data should be octet string type */
Jens Wiklander32b31802023-10-06 16:59:46 +0200130 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 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100134
135 /* Ignore data so far and just check its length */
136 *p += len;
Jens Wiklander32b31802023-10-06 16:59:46 +0200137 if (*p != end_ext_data) {
138 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
139 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
140 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100141
142 /* Abort on (unsupported) critical extensions */
Jens Wiklander32b31802023-10-06 16:59:46 +0200143 if (is_critical) {
144 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
145 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
146 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200147 }
148
Jens Wiklander32b31802023-10-06 16:59:46 +0200149 if (*p != end) {
150 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
151 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
152 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200153
Jens Wiklander32b31802023-10-06 16:59:46 +0200154 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200155}
156
157/*
158 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
159 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200160static int x509_get_crl_entry_ext(unsigned char **p,
161 const unsigned char *end,
162 mbedtls_x509_buf *ext)
Jens Wiklander817466c2018-05-22 13:49:31 +0200163{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200164 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200165 size_t len = 0;
166
167 /* OPTIONAL */
Jens Wiklander32b31802023-10-06 16:59:46 +0200168 if (end <= *p) {
169 return 0;
170 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200171
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 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200179 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) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200182 ext->p = NULL;
Jens Wiklander32b31802023-10-06 16:59:46 +0200183 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200184 }
Jens Wiklander32b31802023-10-06 16:59:46 +0200185 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
Jens Wiklander817466c2018-05-22 13:49:31 +0200186 }
187
188 end = *p + ext->len;
189
Jens Wiklander32b31802023-10-06 16:59:46 +0200190 if (end != *p + ext->len) {
191 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
192 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
193 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200194
Jens Wiklander32b31802023-10-06 16:59:46 +0200195 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 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200200
201 *p += len;
202 }
203
Jens Wiklander32b31802023-10-06 16:59:46 +0200204 if (*p != end) {
205 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
206 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
207 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200208
Jens Wiklander32b31802023-10-06 16:59:46 +0200209 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200210}
211
212/*
213 * X.509 CRL Entries
214 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200215static int x509_get_entries(unsigned char **p,
216 const unsigned char *end,
217 mbedtls_x509_crl_entry *entry)
Jens Wiklander817466c2018-05-22 13:49:31 +0200218{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200219 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200220 size_t entry_len;
221 mbedtls_x509_crl_entry *cur_entry = entry;
222
Jens Wiklander32b31802023-10-06 16:59:46 +0200223 if (*p == end) {
224 return 0;
225 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200226
Jens Wiklander32b31802023-10-06 16:59:46 +0200227 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 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200232
Jens Wiklander32b31802023-10-06 16:59:46 +0200233 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200234 }
235
236 end = *p + entry_len;
237
Jens Wiklander32b31802023-10-06 16:59:46 +0200238 while (*p < end) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200239 size_t len2;
240 const unsigned char *end2;
241
Jerome Forissier79013242021-07-28 10:24:04 +0200242 cur_entry->raw.tag = **p;
Jens Wiklander32b31802023-10-06 16:59:46 +0200243 if ((ret = mbedtls_asn1_get_tag(p, end, &len2,
244 MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED)) != 0) {
245 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200246 }
247
Jens Wiklander817466c2018-05-22 13:49:31 +0200248 cur_entry->raw.p = *p;
249 cur_entry->raw.len = len2;
250 end2 = *p + len2;
251
Jens Wiklander32b31802023-10-06 16:59:46 +0200252 if ((ret = mbedtls_x509_get_serial(p, end2, &cur_entry->serial)) != 0) {
253 return ret;
254 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200255
Jens Wiklander32b31802023-10-06 16:59:46 +0200256 if ((ret = mbedtls_x509_get_time(p, end2,
257 &cur_entry->revocation_date)) != 0) {
258 return ret;
259 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200260
Jens Wiklander32b31802023-10-06 16:59:46 +0200261 if ((ret = x509_get_crl_entry_ext(p, end2,
262 &cur_entry->entry_ext)) != 0) {
263 return ret;
264 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200265
Jens Wiklander32b31802023-10-06 16:59:46 +0200266 if (*p < end) {
267 cur_entry->next = mbedtls_calloc(1, sizeof(mbedtls_x509_crl_entry));
Jens Wiklander817466c2018-05-22 13:49:31 +0200268
Jens Wiklander32b31802023-10-06 16:59:46 +0200269 if (cur_entry->next == NULL) {
270 return MBEDTLS_ERR_X509_ALLOC_FAILED;
271 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200272
273 cur_entry = cur_entry->next;
274 }
275 }
276
Jens Wiklander32b31802023-10-06 16:59:46 +0200277 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200278}
279
280/*
281 * Parse one CRLs in DER format and append it to the chained list
282 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200283int mbedtls_x509_crl_parse_der(mbedtls_x509_crl *chain,
284 const unsigned char *buf, size_t buflen)
Jens Wiklander817466c2018-05-22 13:49:31 +0200285{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200286 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200287 size_t len;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100288 unsigned char *p = NULL, *end = NULL;
Jens Wiklander817466c2018-05-22 13:49:31 +0200289 mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
290 mbedtls_x509_crl *crl = chain;
291
292 /*
293 * Check for valid input
294 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200295 if (crl == NULL || buf == NULL) {
296 return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
297 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200298
Jens Wiklander32b31802023-10-06 16:59:46 +0200299 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));
Jens Wiklander817466c2018-05-22 13:49:31 +0200302
303 /*
304 * Add new CRL on the end of the chain if needed.
305 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200306 while (crl->version != 0 && crl->next != NULL) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200307 crl = crl->next;
Jens Wiklander32b31802023-10-06 16:59:46 +0200308 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200309
Jens Wiklander32b31802023-10-06 16:59:46 +0200310 if (crl->version != 0 && crl->next == NULL) {
311 crl->next = mbedtls_calloc(1, sizeof(mbedtls_x509_crl));
Jens Wiklander817466c2018-05-22 13:49:31 +0200312
Jens Wiklander32b31802023-10-06 16:59:46 +0200313 if (crl->next == NULL) {
314 mbedtls_x509_crl_free(crl);
315 return MBEDTLS_ERR_X509_ALLOC_FAILED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200316 }
317
Jens Wiklander32b31802023-10-06 16:59:46 +0200318 mbedtls_x509_crl_init(crl->next);
Jens Wiklander817466c2018-05-22 13:49:31 +0200319 crl = crl->next;
320 }
321
322 /*
323 * Copy raw DER-encoded CRL
324 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200325 if (buflen == 0) {
326 return MBEDTLS_ERR_X509_INVALID_FORMAT;
327 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100328
Jens Wiklander32b31802023-10-06 16:59:46 +0200329 p = mbedtls_calloc(1, buflen);
330 if (p == NULL) {
331 return MBEDTLS_ERR_X509_ALLOC_FAILED;
332 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200333
Jens Wiklander32b31802023-10-06 16:59:46 +0200334 memcpy(p, buf, buflen);
Jens Wiklander817466c2018-05-22 13:49:31 +0200335
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 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200347 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;
Jens Wiklander817466c2018-05-22 13:49:31 +0200351 }
352
Jens Wiklander32b31802023-10-06 16:59:46 +0200353 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);
Jens Wiklander817466c2018-05-22 13:49:31 +0200357 }
358
359 /*
360 * TBSCertList ::= SEQUENCE {
361 */
362 crl->tbs.p = p;
363
Jens Wiklander32b31802023-10-06 16:59:46 +0200364 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);
Jens Wiklander817466c2018-05-22 13:49:31 +0200368 }
369
370 end = p + len;
Tom Van Eyckc1633172024-04-09 18:44:13 +0200371 crl->tbs.len = (size_t) (end - crl->tbs.p);
Jens Wiklander817466c2018-05-22 13:49:31 +0200372
373 /*
374 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
375 * -- if present, MUST be v2
376 *
377 * signature AlgorithmIdentifier
378 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200379 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;
Jens Wiklander817466c2018-05-22 13:49:31 +0200383 }
384
Jens Wiklander32b31802023-10-06 16:59:46 +0200385 if (crl->version < 0 || crl->version > 1) {
386 mbedtls_x509_crl_free(crl);
387 return MBEDTLS_ERR_X509_UNKNOWN_VERSION;
Jens Wiklander817466c2018-05-22 13:49:31 +0200388 }
389
390 crl->version++;
391
Jens Wiklander32b31802023-10-06 16:59:46 +0200392 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;
Jens Wiklander817466c2018-05-22 13:49:31 +0200397 }
398
399 /*
400 * issuer Name
401 */
402 crl->issuer_raw.p = p;
403
Jens Wiklander32b31802023-10-06 16:59:46 +0200404 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);
Jens Wiklander817466c2018-05-22 13:49:31 +0200408 }
409
Jens Wiklander32b31802023-10-06 16:59:46 +0200410 if ((ret = mbedtls_x509_get_name(&p, p + len, &crl->issuer)) != 0) {
411 mbedtls_x509_crl_free(crl);
412 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200413 }
414
Tom Van Eyckc1633172024-04-09 18:44:13 +0200415 crl->issuer_raw.len = (size_t) (p - crl->issuer_raw.p);
Jens Wiklander817466c2018-05-22 13:49:31 +0200416
417 /*
418 * thisUpdate Time
419 * nextUpdate Time OPTIONAL
420 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200421 if ((ret = mbedtls_x509_get_time(&p, end, &crl->this_update)) != 0) {
422 mbedtls_x509_crl_free(crl);
423 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200424 }
425
Jens Wiklander32b31802023-10-06 16:59:46 +0200426 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;
Jens Wiklander817466c2018-05-22 13:49:31 +0200433 }
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 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200444 if ((ret = x509_get_entries(&p, end, &crl->entry)) != 0) {
445 mbedtls_x509_crl_free(crl);
446 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200447 }
448
449 /*
450 * crlExtensions EXPLICIT Extensions OPTIONAL
451 * -- if present, MUST be v2
452 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200453 if (crl->version == 2) {
454 ret = x509_get_crl_ext(&p, end, &crl->crl_ext);
Jens Wiklander817466c2018-05-22 13:49:31 +0200455
Jens Wiklander32b31802023-10-06 16:59:46 +0200456 if (ret != 0) {
457 mbedtls_x509_crl_free(crl);
458 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200459 }
460 }
461
Jens Wiklander32b31802023-10-06 16:59:46 +0200462 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);
Jens Wiklander817466c2018-05-22 13:49:31 +0200466 }
467
468 end = crl->raw.p + crl->raw.len;
469
470 /*
471 * signatureAlgorithm AlgorithmIdentifier,
472 * signatureValue BIT STRING
473 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200474 if ((ret = mbedtls_x509_get_alg(&p, end, &sig_oid2, &sig_params2)) != 0) {
475 mbedtls_x509_crl_free(crl);
476 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200477 }
478
Jens Wiklander32b31802023-10-06 16:59:46 +0200479 if (crl->sig_oid.len != sig_oid2.len ||
480 memcmp(crl->sig_oid.p, sig_oid2.p, crl->sig_oid.len) != 0 ||
Jens Wiklander817466c2018-05-22 13:49:31 +0200481 sig_params1.len != sig_params2.len ||
Jens Wiklander32b31802023-10-06 16:59:46 +0200482 (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;
Jens Wiklander817466c2018-05-22 13:49:31 +0200486 }
487
Jens Wiklander32b31802023-10-06 16:59:46 +0200488 if ((ret = mbedtls_x509_get_sig(&p, end, &crl->sig)) != 0) {
489 mbedtls_x509_crl_free(crl);
490 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200491 }
492
Jens Wiklander32b31802023-10-06 16:59:46 +0200493 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);
Jens Wiklander817466c2018-05-22 13:49:31 +0200497 }
498
Jens Wiklander32b31802023-10-06 16:59:46 +0200499 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200500}
501
502/*
503 * Parse one or more CRLs and add them to the chained list
504 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200505int mbedtls_x509_crl_parse(mbedtls_x509_crl *chain, const unsigned char *buf, size_t buflen)
Jens Wiklander817466c2018-05-22 13:49:31 +0200506{
507#if defined(MBEDTLS_PEM_PARSE_C)
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200508 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
509 size_t use_len = 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200510 mbedtls_pem_context pem;
511 int is_pem = 0;
512
Jens Wiklander32b31802023-10-06 16:59:46 +0200513 if (chain == NULL || buf == NULL) {
514 return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
515 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200516
Jens Wiklander32b31802023-10-06 16:59:46 +0200517 do {
518 mbedtls_pem_init(&pem);
Jens Wiklander817466c2018-05-22 13:49:31 +0200519
520 // Avoid calling mbedtls_pem_read_buffer() on non-null-terminated
521 // string
Jens Wiklander32b31802023-10-06 16:59:46 +0200522 if (buflen == 0 || buf[buflen - 1] != '\0') {
Jens Wiklander817466c2018-05-22 13:49:31 +0200523 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
Jens Wiklander32b31802023-10-06 16:59:46 +0200524 } else {
525 ret = mbedtls_pem_read_buffer(&pem,
526 "-----BEGIN X509 CRL-----",
527 "-----END X509 CRL-----",
528 buf, NULL, 0, &use_len);
529 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200530
Jens Wiklander32b31802023-10-06 16:59:46 +0200531 if (ret == 0) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200532 /*
533 * Was PEM encoded
534 */
535 is_pem = 1;
536
537 buflen -= use_len;
538 buf += use_len;
539
Jens Wiklander32b31802023-10-06 16:59:46 +0200540 if ((ret = mbedtls_x509_crl_parse_der(chain,
541 pem.buf, pem.buflen)) != 0) {
542 mbedtls_pem_free(&pem);
543 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200544 }
Jens Wiklander32b31802023-10-06 16:59:46 +0200545 } else if (is_pem) {
546 mbedtls_pem_free(&pem);
547 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200548 }
549
Jens Wiklander32b31802023-10-06 16:59:46 +0200550 mbedtls_pem_free(&pem);
Jens Wiklander817466c2018-05-22 13:49:31 +0200551 }
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. */
Jens Wiklander32b31802023-10-06 16:59:46 +0200554 while (is_pem && buflen > 1);
Jens Wiklander817466c2018-05-22 13:49:31 +0200555
Jens Wiklander32b31802023-10-06 16:59:46 +0200556 if (is_pem) {
557 return 0;
558 } else
Jens Wiklander817466c2018-05-22 13:49:31 +0200559#endif /* MBEDTLS_PEM_PARSE_C */
Jens Wiklander32b31802023-10-06 16:59:46 +0200560 return mbedtls_x509_crl_parse_der(chain, buf, buflen);
Jens Wiklander817466c2018-05-22 13:49:31 +0200561}
562
563#if defined(MBEDTLS_FS_IO)
564/*
565 * Load one or more CRLs and add them to the chained list
566 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200567int mbedtls_x509_crl_parse_file(mbedtls_x509_crl *chain, const char *path)
Jens Wiklander817466c2018-05-22 13:49:31 +0200568{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200569 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200570 size_t n;
571 unsigned char *buf;
572
Jens Wiklander32b31802023-10-06 16:59:46 +0200573 if ((ret = mbedtls_pk_load_file(path, &buf, &n)) != 0) {
574 return ret;
575 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200576
Jens Wiklander32b31802023-10-06 16:59:46 +0200577 ret = mbedtls_x509_crl_parse(chain, buf, n);
Jens Wiklander817466c2018-05-22 13:49:31 +0200578
Tom Van Eyckc1633172024-04-09 18:44:13 +0200579 mbedtls_zeroize_and_free(buf, n);
Jens Wiklander817466c2018-05-22 13:49:31 +0200580
Jens Wiklander32b31802023-10-06 16:59:46 +0200581 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200582}
583#endif /* MBEDTLS_FS_IO */
584
Jens Wiklander32b31802023-10-06 16:59:46 +0200585#if !defined(MBEDTLS_X509_REMOVE_INFO)
Jens Wiklander817466c2018-05-22 13:49:31 +0200586/*
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 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200594int mbedtls_x509_crl_info(char *buf, size_t size, const char *prefix,
595 const mbedtls_x509_crl *crl)
Jens Wiklander817466c2018-05-22 13:49:31 +0200596{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200597 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200598 size_t n;
599 char *p;
600 const mbedtls_x509_crl_entry *entry;
601
602 p = buf;
603 n = size;
604
Jens Wiklander32b31802023-10-06 16:59:46 +0200605 ret = mbedtls_snprintf(p, n, "%sCRL version : %d",
606 prefix, crl->version);
Jens Wiklander817466c2018-05-22 13:49:31 +0200607 MBEDTLS_X509_SAFE_SNPRINTF;
608
Jens Wiklander32b31802023-10-06 16:59:46 +0200609 ret = mbedtls_snprintf(p, n, "\n%sissuer name : ", prefix);
Jens Wiklander817466c2018-05-22 13:49:31 +0200610 MBEDTLS_X509_SAFE_SNPRINTF;
Jens Wiklander32b31802023-10-06 16:59:46 +0200611 ret = mbedtls_x509_dn_gets(p, n, &crl->issuer);
Jens Wiklander817466c2018-05-22 13:49:31 +0200612 MBEDTLS_X509_SAFE_SNPRINTF;
613
Jens Wiklander32b31802023-10-06 16:59:46 +0200614 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);
Jens Wiklander817466c2018-05-22 13:49:31 +0200619 MBEDTLS_X509_SAFE_SNPRINTF;
620
Jens Wiklander32b31802023-10-06 16:59:46 +0200621 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);
Jens Wiklander817466c2018-05-22 13:49:31 +0200626 MBEDTLS_X509_SAFE_SNPRINTF;
627
628 entry = &crl->entry;
629
Jens Wiklander32b31802023-10-06 16:59:46 +0200630 ret = mbedtls_snprintf(p, n, "\n%sRevoked certificates:",
631 prefix);
Jens Wiklander817466c2018-05-22 13:49:31 +0200632 MBEDTLS_X509_SAFE_SNPRINTF;
633
Jens Wiklander32b31802023-10-06 16:59:46 +0200634 while (entry != NULL && entry->raw.len != 0) {
635 ret = mbedtls_snprintf(p, n, "\n%sserial number: ",
636 prefix);
Jens Wiklander817466c2018-05-22 13:49:31 +0200637 MBEDTLS_X509_SAFE_SNPRINTF;
638
Jens Wiklander32b31802023-10-06 16:59:46 +0200639 ret = mbedtls_x509_serial_gets(p, n, &entry->serial);
Jens Wiklander817466c2018-05-22 13:49:31 +0200640 MBEDTLS_X509_SAFE_SNPRINTF;
641
Jens Wiklander32b31802023-10-06 16:59:46 +0200642 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);
Jens Wiklander817466c2018-05-22 13:49:31 +0200647 MBEDTLS_X509_SAFE_SNPRINTF;
648
649 entry = entry->next;
650 }
651
Jens Wiklander32b31802023-10-06 16:59:46 +0200652 ret = mbedtls_snprintf(p, n, "\n%ssigned using : ", prefix);
Jens Wiklander817466c2018-05-22 13:49:31 +0200653 MBEDTLS_X509_SAFE_SNPRINTF;
654
Jens Wiklander32b31802023-10-06 16:59:46 +0200655 ret = mbedtls_x509_sig_alg_gets(p, n, &crl->sig_oid, crl->sig_pk, crl->sig_md,
656 crl->sig_opts);
Jens Wiklander817466c2018-05-22 13:49:31 +0200657 MBEDTLS_X509_SAFE_SNPRINTF;
658
Jens Wiklander32b31802023-10-06 16:59:46 +0200659 ret = mbedtls_snprintf(p, n, "\n");
Jens Wiklander817466c2018-05-22 13:49:31 +0200660 MBEDTLS_X509_SAFE_SNPRINTF;
661
Jens Wiklander32b31802023-10-06 16:59:46 +0200662 return (int) (size - n);
Jens Wiklander817466c2018-05-22 13:49:31 +0200663}
Jens Wiklander32b31802023-10-06 16:59:46 +0200664#endif /* MBEDTLS_X509_REMOVE_INFO */
Jens Wiklander817466c2018-05-22 13:49:31 +0200665
666/*
667 * Initialize a CRL chain
668 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200669void mbedtls_x509_crl_init(mbedtls_x509_crl *crl)
Jens Wiklander817466c2018-05-22 13:49:31 +0200670{
Jens Wiklander32b31802023-10-06 16:59:46 +0200671 memset(crl, 0, sizeof(mbedtls_x509_crl));
Jens Wiklander817466c2018-05-22 13:49:31 +0200672}
673
674/*
675 * Unallocate all CRL data
676 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200677void mbedtls_x509_crl_free(mbedtls_x509_crl *crl)
Jens Wiklander817466c2018-05-22 13:49:31 +0200678{
679 mbedtls_x509_crl *crl_cur = crl;
680 mbedtls_x509_crl *crl_prv;
Jens Wiklander817466c2018-05-22 13:49:31 +0200681 mbedtls_x509_crl_entry *entry_cur;
682 mbedtls_x509_crl_entry *entry_prv;
683
Jens Wiklander32b31802023-10-06 16:59:46 +0200684 while (crl_cur != NULL) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200685#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
Jens Wiklander32b31802023-10-06 16:59:46 +0200686 mbedtls_free(crl_cur->sig_opts);
Jens Wiklander817466c2018-05-22 13:49:31 +0200687#endif
688
Jens Wiklander32b31802023-10-06 16:59:46 +0200689 mbedtls_asn1_free_named_data_list_shallow(crl_cur->issuer.next);
Jens Wiklander817466c2018-05-22 13:49:31 +0200690
691 entry_cur = crl_cur->entry.next;
Jens Wiklander32b31802023-10-06 16:59:46 +0200692 while (entry_cur != NULL) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200693 entry_prv = entry_cur;
694 entry_cur = entry_cur->next;
Tom Van Eyckc1633172024-04-09 18:44:13 +0200695 mbedtls_zeroize_and_free(entry_prv,
Jens Wiklander32b31802023-10-06 16:59:46 +0200696 sizeof(mbedtls_x509_crl_entry));
Jens Wiklander817466c2018-05-22 13:49:31 +0200697 }
698
Jens Wiklander32b31802023-10-06 16:59:46 +0200699 if (crl_cur->raw.p != NULL) {
Tom Van Eyckc1633172024-04-09 18:44:13 +0200700 mbedtls_zeroize_and_free(crl_cur->raw.p, crl_cur->raw.len);
Jens Wiklander817466c2018-05-22 13:49:31 +0200701 }
702
Jens Wiklander817466c2018-05-22 13:49:31 +0200703 crl_prv = crl_cur;
704 crl_cur = crl_cur->next;
705
Jens Wiklander32b31802023-10-06 16:59:46 +0200706 mbedtls_platform_zeroize(crl_prv, sizeof(mbedtls_x509_crl));
707 if (crl_prv != crl) {
708 mbedtls_free(crl_prv);
709 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200710 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200711}
712
713#endif /* MBEDTLS_X509_CRL_PARSE_C */