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