blob: 6e46e1f535bf1cf1dd33857cb68ba3b00036a4ad [file] [log] [blame]
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001/*
2 * X.509 certificate and private key decoding
3 *
Paul Bakker7dc4c442014-02-01 22:50:26 +01004 * Copyright (C) 2006-2014, Brainspark B.V.
Paul Bakker7c6b2c32013-09-16 13:49:26 +02005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25/*
26 * The ITU-T X.509 standard defines a certificate format for PKI.
27 *
28 * http://www.ietf.org/rfc/rfc3279.txt
29 * http://www.ietf.org/rfc/rfc3280.txt
30 *
31 * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
32 *
33 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
34 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
35 */
36
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020037#if !defined(POLARSSL_CONFIG_FILE)
Paul Bakker7c6b2c32013-09-16 13:49:26 +020038#include "polarssl/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020039#else
40#include POLARSSL_CONFIG_FILE
41#endif
Paul Bakker7c6b2c32013-09-16 13:49:26 +020042
43#if defined(POLARSSL_X509_CRL_PARSE_C)
44
45#include "polarssl/x509_crl.h"
46#include "polarssl/oid.h"
47#if defined(POLARSSL_PEM_PARSE_C)
48#include "polarssl/pem.h"
49#endif
50
Paul Bakker7dc4c442014-02-01 22:50:26 +010051#if defined(POLARSSL_PLATFORM_C)
52#include "polarssl/platform.h"
Paul Bakker7c6b2c32013-09-16 13:49:26 +020053#else
54#define polarssl_malloc malloc
55#define polarssl_free free
56#endif
57
58#include <string.h>
59#include <stdlib.h>
Paul Bakkerfa6a6202013-10-28 18:48:30 +010060#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
61
Paul Bakker7c6b2c32013-09-16 13:49:26 +020062#include <windows.h>
63#else
64#include <time.h>
65#endif
66
Paul Bakkerfa6a6202013-10-28 18:48:30 +010067#if defined(POLARSSL_FS_IO) || defined(EFIX64) || defined(EFI32)
Paul Bakker7c6b2c32013-09-16 13:49:26 +020068#include <stdio.h>
69#endif
70
71/*
72 * Version ::= INTEGER { v1(0), v2(1) }
73 */
74static int x509_crl_get_version( unsigned char **p,
75 const unsigned char *end,
76 int *ver )
77{
78 int ret;
79
80 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
81 {
82 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
83 {
84 *ver = 0;
85 return( 0 );
86 }
87
Paul Bakker51876562013-09-17 14:36:05 +020088 return( POLARSSL_ERR_X509_INVALID_VERSION + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +020089 }
90
91 return( 0 );
92}
93
94/*
95 * X.509 CRL v2 extensions (no extensions parsed yet.)
96 */
97static int x509_get_crl_ext( unsigned char **p,
98 const unsigned char *end,
99 x509_buf *ext )
100{
101 int ret;
102 size_t len = 0;
103
104 /* Get explicit tag */
105 if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 )
106 {
107 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
108 return( 0 );
109
110 return( ret );
111 }
112
113 while( *p < end )
114 {
115 if( ( ret = asn1_get_tag( p, end, &len,
116 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200117 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200118
119 *p += len;
120 }
121
122 if( *p != end )
Paul Bakker51876562013-09-17 14:36:05 +0200123 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200124 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
125
126 return( 0 );
127}
128
129/*
130 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
131 */
132static int x509_get_crl_entry_ext( unsigned char **p,
133 const unsigned char *end,
134 x509_buf *ext )
135{
136 int ret;
137 size_t len = 0;
138
139 /* OPTIONAL */
140 if (end <= *p)
141 return( 0 );
142
143 ext->tag = **p;
144 ext->p = *p;
145
146 /*
147 * Get CRL-entry extension sequence header
148 * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
149 */
150 if( ( ret = asn1_get_tag( p, end, &ext->len,
151 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
152 {
153 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
154 {
155 ext->p = NULL;
156 return( 0 );
157 }
Paul Bakker51876562013-09-17 14:36:05 +0200158 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200159 }
160
161 end = *p + ext->len;
162
163 if( end != *p + ext->len )
Paul Bakker51876562013-09-17 14:36:05 +0200164 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200165 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
166
167 while( *p < end )
168 {
169 if( ( ret = asn1_get_tag( p, end, &len,
170 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200171 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200172
173 *p += len;
174 }
175
176 if( *p != end )
Paul Bakker51876562013-09-17 14:36:05 +0200177 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200178 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
179
180 return( 0 );
181}
182
183/*
184 * X.509 CRL Entries
185 */
186static int x509_get_entries( unsigned char **p,
187 const unsigned char *end,
188 x509_crl_entry *entry )
189{
190 int ret;
191 size_t entry_len;
192 x509_crl_entry *cur_entry = entry;
193
194 if( *p == end )
195 return( 0 );
196
197 if( ( ret = asn1_get_tag( p, end, &entry_len,
198 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
199 {
200 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
201 return( 0 );
202
203 return( ret );
204 }
205
206 end = *p + entry_len;
207
208 while( *p < end )
209 {
210 size_t len2;
211 const unsigned char *end2;
212
213 if( ( ret = asn1_get_tag( p, end, &len2,
214 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
215 {
216 return( ret );
217 }
218
219 cur_entry->raw.tag = **p;
220 cur_entry->raw.p = *p;
221 cur_entry->raw.len = len2;
222 end2 = *p + len2;
223
224 if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
225 return( ret );
226
227 if( ( ret = x509_get_time( p, end2, &cur_entry->revocation_date ) ) != 0 )
228 return( ret );
229
230 if( ( ret = x509_get_crl_entry_ext( p, end2, &cur_entry->entry_ext ) ) != 0 )
231 return( ret );
232
233 if ( *p < end )
234 {
235 cur_entry->next = polarssl_malloc( sizeof( x509_crl_entry ) );
236
237 if( cur_entry->next == NULL )
238 return( POLARSSL_ERR_X509_MALLOC_FAILED );
239
240 cur_entry = cur_entry->next;
241 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
242 }
243 }
244
245 return( 0 );
246}
247
248/*
249 * Parse one or more CRLs and add them to the chained list
250 */
Paul Bakkerddf26b42013-09-18 13:46:23 +0200251int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200252{
253 int ret;
254 size_t len;
255 unsigned char *p, *end;
256 x509_crl *crl;
257#if defined(POLARSSL_PEM_PARSE_C)
258 size_t use_len;
259 pem_context pem;
260#endif
261
262 crl = chain;
263
264 /*
265 * Check for valid input
266 */
267 if( crl == NULL || buf == NULL )
Paul Bakker51876562013-09-17 14:36:05 +0200268 return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200269
270 while( crl->version != 0 && crl->next != NULL )
271 crl = crl->next;
272
273 /*
274 * Add new CRL on the end of the chain if needed.
275 */
276 if ( crl->version != 0 && crl->next == NULL)
277 {
278 crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
279
280 if( crl->next == NULL )
281 {
282 x509_crl_free( crl );
283 return( POLARSSL_ERR_X509_MALLOC_FAILED );
284 }
285
286 crl = crl->next;
Paul Bakker369d2eb2013-09-18 11:58:25 +0200287 x509_crl_init( crl );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200288 }
289
290#if defined(POLARSSL_PEM_PARSE_C)
291 pem_init( &pem );
292 ret = pem_read_buffer( &pem,
293 "-----BEGIN X509 CRL-----",
294 "-----END X509 CRL-----",
295 buf, NULL, 0, &use_len );
296
297 if( ret == 0 )
298 {
299 /*
300 * Was PEM encoded
301 */
302 buflen -= use_len;
303 buf += use_len;
304
305 /*
306 * Steal PEM buffer
307 */
308 p = pem.buf;
309 pem.buf = NULL;
310 len = pem.buflen;
311 pem_free( &pem );
312 }
313 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
314 {
315 pem_free( &pem );
316 return( ret );
317 }
318 else
319#endif
320 {
321 /*
322 * nope, copy the raw DER data
323 */
324 p = (unsigned char *) polarssl_malloc( len = buflen );
325
326 if( p == NULL )
327 return( POLARSSL_ERR_X509_MALLOC_FAILED );
328
329 memcpy( p, buf, buflen );
330
331 buflen = 0;
332 }
333
334 crl->raw.p = p;
335 crl->raw.len = len;
336 end = p + len;
337
338 /*
339 * CertificateList ::= SEQUENCE {
340 * tbsCertList TBSCertList,
341 * signatureAlgorithm AlgorithmIdentifier,
342 * signatureValue BIT STRING }
343 */
344 if( ( ret = asn1_get_tag( &p, end, &len,
345 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
346 {
347 x509_crl_free( crl );
Paul Bakker51876562013-09-17 14:36:05 +0200348 return( POLARSSL_ERR_X509_INVALID_FORMAT );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200349 }
350
351 if( len != (size_t) ( end - p ) )
352 {
353 x509_crl_free( crl );
Paul Bakker51876562013-09-17 14:36:05 +0200354 return( POLARSSL_ERR_X509_INVALID_FORMAT +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200355 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
356 }
357
358 /*
359 * TBSCertList ::= SEQUENCE {
360 */
361 crl->tbs.p = p;
362
363 if( ( ret = asn1_get_tag( &p, end, &len,
364 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
365 {
366 x509_crl_free( crl );
Paul Bakker51876562013-09-17 14:36:05 +0200367 return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200368 }
369
370 end = p + len;
371 crl->tbs.len = end - crl->tbs.p;
372
373 /*
374 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
375 * -- if present, MUST be v2
376 *
377 * signature AlgorithmIdentifier
378 */
379 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
Manuel Pégourié-Gonnardc9093082014-02-12 09:39:59 +0100380 ( ret = x509_get_alg_null( &p, end, &crl->sig_oid1 ) ) != 0 )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200381 {
382 x509_crl_free( crl );
383 return( ret );
384 }
385
386 crl->version++;
387
388 if( crl->version > 2 )
389 {
390 x509_crl_free( crl );
Paul Bakker51876562013-09-17 14:36:05 +0200391 return( POLARSSL_ERR_X509_UNKNOWN_VERSION );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200392 }
393
Manuel Pégourié-Gonnardc9093082014-02-12 09:39:59 +0100394 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_md,
395 &crl->sig_pk ) ) != 0 )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200396 {
397 x509_crl_free( crl );
Paul Bakker51876562013-09-17 14:36:05 +0200398 return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200399 }
400
401 /*
402 * issuer Name
403 */
404 crl->issuer_raw.p = p;
405
406 if( ( ret = asn1_get_tag( &p, end, &len,
407 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
408 {
409 x509_crl_free( crl );
Paul Bakker51876562013-09-17 14:36:05 +0200410 return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200411 }
412
413 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
414 {
415 x509_crl_free( crl );
416 return( ret );
417 }
418
419 crl->issuer_raw.len = p - crl->issuer_raw.p;
420
421 /*
422 * thisUpdate Time
423 * nextUpdate Time OPTIONAL
424 */
425 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
426 {
427 x509_crl_free( crl );
428 return( ret );
429 }
430
431 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
432 {
Paul Bakker51876562013-09-17 14:36:05 +0200433 if ( ret != ( POLARSSL_ERR_X509_INVALID_DATE +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200434 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker51876562013-09-17 14:36:05 +0200435 ret != ( POLARSSL_ERR_X509_INVALID_DATE +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200436 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
437 {
438 x509_crl_free( crl );
439 return( ret );
440 }
441 }
442
443 /*
444 * revokedCertificates SEQUENCE OF SEQUENCE {
445 * userCertificate CertificateSerialNumber,
446 * revocationDate Time,
447 * crlEntryExtensions Extensions OPTIONAL
448 * -- if present, MUST be v2
449 * } OPTIONAL
450 */
451 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
452 {
453 x509_crl_free( crl );
454 return( ret );
455 }
456
457 /*
458 * crlExtensions EXPLICIT Extensions OPTIONAL
459 * -- if present, MUST be v2
460 */
461 if( crl->version == 2 )
462 {
463 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
464
465 if( ret != 0 )
466 {
467 x509_crl_free( crl );
468 return( ret );
469 }
470 }
471
472 if( p != end )
473 {
474 x509_crl_free( crl );
Paul Bakker51876562013-09-17 14:36:05 +0200475 return( POLARSSL_ERR_X509_INVALID_FORMAT +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200476 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
477 }
478
479 end = crl->raw.p + crl->raw.len;
480
481 /*
482 * signatureAlgorithm AlgorithmIdentifier,
483 * signatureValue BIT STRING
484 */
Manuel Pégourié-Gonnardc9093082014-02-12 09:39:59 +0100485 if( ( ret = x509_get_alg_null( &p, end, &crl->sig_oid2 ) ) != 0 )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200486 {
487 x509_crl_free( crl );
488 return( ret );
489 }
490
491 if( crl->sig_oid1.len != crl->sig_oid2.len ||
Manuel Pégourié-Gonnardc9093082014-02-12 09:39:59 +0100492 memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200493 {
494 x509_crl_free( crl );
Paul Bakker51876562013-09-17 14:36:05 +0200495 return( POLARSSL_ERR_X509_SIG_MISMATCH );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200496 }
497
498 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
499 {
500 x509_crl_free( crl );
501 return( ret );
502 }
503
504 if( p != end )
505 {
506 x509_crl_free( crl );
Paul Bakker51876562013-09-17 14:36:05 +0200507 return( POLARSSL_ERR_X509_INVALID_FORMAT +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200508 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
509 }
510
511 if( buflen > 0 )
512 {
513 crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
514
515 if( crl->next == NULL )
516 {
517 x509_crl_free( crl );
518 return( POLARSSL_ERR_X509_MALLOC_FAILED );
519 }
520
521 crl = crl->next;
Paul Bakker369d2eb2013-09-18 11:58:25 +0200522 x509_crl_init( crl );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200523
Paul Bakkerddf26b42013-09-18 13:46:23 +0200524 return( x509_crl_parse( crl, buf, buflen ) );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200525 }
526
527 return( 0 );
528}
529
530#if defined(POLARSSL_FS_IO)
531/*
532 * Load one or more CRLs and add them to the chained list
533 */
Paul Bakkerddf26b42013-09-18 13:46:23 +0200534int x509_crl_parse_file( x509_crl *chain, const char *path )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200535{
536 int ret;
537 size_t n;
538 unsigned char *buf;
539
540 if ( ( ret = x509_load_file( path, &buf, &n ) ) != 0 )
541 return( ret );
542
Paul Bakkerddf26b42013-09-18 13:46:23 +0200543 ret = x509_crl_parse( chain, buf, n );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200544
545 memset( buf, 0, n + 1 );
546 polarssl_free( buf );
547
548 return( ret );
549}
550#endif /* POLARSSL_FS_IO */
551
Paul Bakker6edcd412013-10-29 15:22:54 +0100552#if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \
553 !defined(EFI32)
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200554#include <stdarg.h>
555
556#if !defined vsnprintf
557#define vsnprintf _vsnprintf
558#endif // vsnprintf
559
560/*
561 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
562 * Result value is not size of buffer needed, but -1 if no fit is possible.
563 *
564 * This fuction tries to 'fix' this by at least suggesting enlarging the
565 * size by 20.
566 */
567static int compat_snprintf(char *str, size_t size, const char *format, ...)
568{
569 va_list ap;
570 int res = -1;
571
572 va_start( ap, format );
573
574 res = vsnprintf( str, size, format, ap );
575
576 va_end( ap );
577
578 // No quick fix possible
579 if ( res < 0 )
580 return( (int) size + 20 );
581
582 return res;
583}
584
585#define snprintf compat_snprintf
586#endif
587
588#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
589
590#define SAFE_SNPRINTF() \
591{ \
592 if( ret == -1 ) \
593 return( -1 ); \
594 \
595 if ( (unsigned int) ret > n ) { \
596 p[n - 1] = '\0'; \
597 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
598 } \
599 \
600 n -= (unsigned int) ret; \
601 p += (unsigned int) ret; \
602}
603
604/*
605 * Return an informational string about the certificate.
606 */
607#define BEFORE_COLON 14
608#define BC "14"
609/*
610 * Return an informational string about the CRL.
611 */
Paul Bakkerddf26b42013-09-18 13:46:23 +0200612int x509_crl_info( char *buf, size_t size, const char *prefix,
613 const x509_crl *crl )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200614{
615 int ret;
616 size_t n;
617 char *p;
Manuel Pégourié-Gonnardc9093082014-02-12 09:39:59 +0100618 const char *desc;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200619 const x509_crl_entry *entry;
620
621 p = buf;
622 n = size;
623
624 ret = snprintf( p, n, "%sCRL version : %d",
625 prefix, crl->version );
626 SAFE_SNPRINTF();
627
628 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
629 SAFE_SNPRINTF();
Paul Bakker86d0c192013-09-18 11:11:02 +0200630 ret = x509_dn_gets( p, n, &crl->issuer );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200631 SAFE_SNPRINTF();
632
633 ret = snprintf( p, n, "\n%sthis update : " \
634 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
635 crl->this_update.year, crl->this_update.mon,
636 crl->this_update.day, crl->this_update.hour,
637 crl->this_update.min, crl->this_update.sec );
638 SAFE_SNPRINTF();
639
640 ret = snprintf( p, n, "\n%snext update : " \
641 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
642 crl->next_update.year, crl->next_update.mon,
643 crl->next_update.day, crl->next_update.hour,
644 crl->next_update.min, crl->next_update.sec );
645 SAFE_SNPRINTF();
646
647 entry = &crl->entry;
648
649 ret = snprintf( p, n, "\n%sRevoked certificates:",
650 prefix );
651 SAFE_SNPRINTF();
652
653 while( entry != NULL && entry->raw.len != 0 )
654 {
655 ret = snprintf( p, n, "\n%sserial number: ",
656 prefix );
657 SAFE_SNPRINTF();
658
Paul Bakker86d0c192013-09-18 11:11:02 +0200659 ret = x509_serial_gets( p, n, &entry->serial);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200660 SAFE_SNPRINTF();
661
662 ret = snprintf( p, n, " revocation date: " \
663 "%04d-%02d-%02d %02d:%02d:%02d",
664 entry->revocation_date.year, entry->revocation_date.mon,
665 entry->revocation_date.day, entry->revocation_date.hour,
666 entry->revocation_date.min, entry->revocation_date.sec );
667 SAFE_SNPRINTF();
668
669 entry = entry->next;
670 }
671
672 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
673 SAFE_SNPRINTF();
674
Manuel Pégourié-Gonnardc9093082014-02-12 09:39:59 +0100675 ret = oid_get_sig_alg_desc( &crl->sig_oid1, &desc );
676 if( ret != 0 )
677 ret = snprintf( p, n, "???" );
678 else
679 ret = snprintf( p, n, "%s", desc );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200680 SAFE_SNPRINTF();
681
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200682 ret = snprintf( p, n, "\n" );
683 SAFE_SNPRINTF();
684
685 return( (int) ( size - n ) );
686}
687
688/*
Paul Bakker369d2eb2013-09-18 11:58:25 +0200689 * Initialize a CRL chain
690 */
691void x509_crl_init( x509_crl *crl )
692{
693 memset( crl, 0, sizeof(x509_crl) );
694}
695
696/*
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200697 * Unallocate all CRL data
698 */
699void x509_crl_free( x509_crl *crl )
700{
701 x509_crl *crl_cur = crl;
702 x509_crl *crl_prv;
703 x509_name *name_cur;
704 x509_name *name_prv;
705 x509_crl_entry *entry_cur;
706 x509_crl_entry *entry_prv;
707
708 if( crl == NULL )
709 return;
710
711 do
712 {
713 name_cur = crl_cur->issuer.next;
714 while( name_cur != NULL )
715 {
716 name_prv = name_cur;
717 name_cur = name_cur->next;
718 memset( name_prv, 0, sizeof( x509_name ) );
719 polarssl_free( name_prv );
720 }
721
722 entry_cur = crl_cur->entry.next;
723 while( entry_cur != NULL )
724 {
725 entry_prv = entry_cur;
726 entry_cur = entry_cur->next;
727 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
728 polarssl_free( entry_prv );
729 }
730
731 if( crl_cur->raw.p != NULL )
732 {
733 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
734 polarssl_free( crl_cur->raw.p );
735 }
736
737 crl_cur = crl_cur->next;
738 }
739 while( crl_cur != NULL );
740
741 crl_cur = crl;
742 do
743 {
744 crl_prv = crl_cur;
745 crl_cur = crl_cur->next;
746
747 memset( crl_prv, 0, sizeof( x509_crl ) );
748 if( crl_prv != crl )
749 polarssl_free( crl_prv );
750 }
751 while( crl_cur != NULL );
752}
753
754#endif