blob: 00d51bdd893ac8a81da929d14feb6d1b91feaa1d [file] [log] [blame] [raw]
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001/*
2 * X.509 certificate and private key decoding
3 *
4 * Copyright (C) 2006-2013, Brainspark B.V.
5 *
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
37#include "polarssl/config.h"
38
39#if defined(POLARSSL_X509_CRL_PARSE_C)
40
41#include "polarssl/x509_crl.h"
42#include "polarssl/oid.h"
43#if defined(POLARSSL_PEM_PARSE_C)
44#include "polarssl/pem.h"
45#endif
46
47#if defined(POLARSSL_MEMORY_C)
48#include "polarssl/memory.h"
49#else
50#define polarssl_malloc malloc
51#define polarssl_free free
52#endif
53
54#include <string.h>
55#include <stdlib.h>
56#if defined(_WIN32)
57#include <windows.h>
58#else
59#include <time.h>
60#endif
61
62#if defined(POLARSSL_FS_IO)
63#include <stdio.h>
64#endif
65
66/*
67 * Version ::= INTEGER { v1(0), v2(1) }
68 */
69static int x509_crl_get_version( unsigned char **p,
70 const unsigned char *end,
71 int *ver )
72{
73 int ret;
74
75 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
76 {
77 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
78 {
79 *ver = 0;
80 return( 0 );
81 }
82
Paul Bakker51876562013-09-17 14:36:05 +020083 return( POLARSSL_ERR_X509_INVALID_VERSION + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +020084 }
85
86 return( 0 );
87}
88
89/*
90 * X.509 CRL v2 extensions (no extensions parsed yet.)
91 */
92static int x509_get_crl_ext( unsigned char **p,
93 const unsigned char *end,
94 x509_buf *ext )
95{
96 int ret;
97 size_t len = 0;
98
99 /* Get explicit tag */
100 if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 )
101 {
102 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
103 return( 0 );
104
105 return( ret );
106 }
107
108 while( *p < end )
109 {
110 if( ( ret = asn1_get_tag( p, end, &len,
111 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200112 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200113
114 *p += len;
115 }
116
117 if( *p != end )
Paul Bakker51876562013-09-17 14:36:05 +0200118 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200119 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
120
121 return( 0 );
122}
123
124/*
125 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
126 */
127static int x509_get_crl_entry_ext( unsigned char **p,
128 const unsigned char *end,
129 x509_buf *ext )
130{
131 int ret;
132 size_t len = 0;
133
134 /* OPTIONAL */
135 if (end <= *p)
136 return( 0 );
137
138 ext->tag = **p;
139 ext->p = *p;
140
141 /*
142 * Get CRL-entry extension sequence header
143 * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
144 */
145 if( ( ret = asn1_get_tag( p, end, &ext->len,
146 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
147 {
148 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
149 {
150 ext->p = NULL;
151 return( 0 );
152 }
Paul Bakker51876562013-09-17 14:36:05 +0200153 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200154 }
155
156 end = *p + ext->len;
157
158 if( end != *p + ext->len )
Paul Bakker51876562013-09-17 14:36:05 +0200159 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200160 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
161
162 while( *p < end )
163 {
164 if( ( ret = asn1_get_tag( p, end, &len,
165 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200166 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200167
168 *p += len;
169 }
170
171 if( *p != end )
Paul Bakker51876562013-09-17 14:36:05 +0200172 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200173 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
174
175 return( 0 );
176}
177
178/*
179 * X.509 CRL Entries
180 */
181static int x509_get_entries( unsigned char **p,
182 const unsigned char *end,
183 x509_crl_entry *entry )
184{
185 int ret;
186 size_t entry_len;
187 x509_crl_entry *cur_entry = entry;
188
189 if( *p == end )
190 return( 0 );
191
192 if( ( ret = asn1_get_tag( p, end, &entry_len,
193 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
194 {
195 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
196 return( 0 );
197
198 return( ret );
199 }
200
201 end = *p + entry_len;
202
203 while( *p < end )
204 {
205 size_t len2;
206 const unsigned char *end2;
207
208 if( ( ret = asn1_get_tag( p, end, &len2,
209 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
210 {
211 return( ret );
212 }
213
214 cur_entry->raw.tag = **p;
215 cur_entry->raw.p = *p;
216 cur_entry->raw.len = len2;
217 end2 = *p + len2;
218
219 if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
220 return( ret );
221
222 if( ( ret = x509_get_time( p, end2, &cur_entry->revocation_date ) ) != 0 )
223 return( ret );
224
225 if( ( ret = x509_get_crl_entry_ext( p, end2, &cur_entry->entry_ext ) ) != 0 )
226 return( ret );
227
228 if ( *p < end )
229 {
230 cur_entry->next = polarssl_malloc( sizeof( x509_crl_entry ) );
231
232 if( cur_entry->next == NULL )
233 return( POLARSSL_ERR_X509_MALLOC_FAILED );
234
235 cur_entry = cur_entry->next;
236 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
237 }
238 }
239
240 return( 0 );
241}
242
243/*
244 * Parse one or more CRLs and add them to the chained list
245 */
Paul Bakkerddf26b42013-09-18 13:46:23 +0200246int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200247{
248 int ret;
249 size_t len;
250 unsigned char *p, *end;
251 x509_crl *crl;
252#if defined(POLARSSL_PEM_PARSE_C)
253 size_t use_len;
254 pem_context pem;
255#endif
256
257 crl = chain;
258
259 /*
260 * Check for valid input
261 */
262 if( crl == NULL || buf == NULL )
Paul Bakker51876562013-09-17 14:36:05 +0200263 return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200264
265 while( crl->version != 0 && crl->next != NULL )
266 crl = crl->next;
267
268 /*
269 * Add new CRL on the end of the chain if needed.
270 */
271 if ( crl->version != 0 && crl->next == NULL)
272 {
273 crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
274
275 if( crl->next == NULL )
276 {
277 x509_crl_free( crl );
278 return( POLARSSL_ERR_X509_MALLOC_FAILED );
279 }
280
281 crl = crl->next;
Paul Bakker369d2eb2013-09-18 11:58:25 +0200282 x509_crl_init( crl );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200283 }
284
285#if defined(POLARSSL_PEM_PARSE_C)
286 pem_init( &pem );
287 ret = pem_read_buffer( &pem,
288 "-----BEGIN X509 CRL-----",
289 "-----END X509 CRL-----",
290 buf, NULL, 0, &use_len );
291
292 if( ret == 0 )
293 {
294 /*
295 * Was PEM encoded
296 */
297 buflen -= use_len;
298 buf += use_len;
299
300 /*
301 * Steal PEM buffer
302 */
303 p = pem.buf;
304 pem.buf = NULL;
305 len = pem.buflen;
306 pem_free( &pem );
307 }
308 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
309 {
310 pem_free( &pem );
311 return( ret );
312 }
313 else
314#endif
315 {
316 /*
317 * nope, copy the raw DER data
318 */
319 p = (unsigned char *) polarssl_malloc( len = buflen );
320
321 if( p == NULL )
322 return( POLARSSL_ERR_X509_MALLOC_FAILED );
323
324 memcpy( p, buf, buflen );
325
326 buflen = 0;
327 }
328
329 crl->raw.p = p;
330 crl->raw.len = len;
331 end = p + len;
332
333 /*
334 * CertificateList ::= SEQUENCE {
335 * tbsCertList TBSCertList,
336 * signatureAlgorithm AlgorithmIdentifier,
337 * signatureValue BIT STRING }
338 */
339 if( ( ret = asn1_get_tag( &p, end, &len,
340 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
341 {
342 x509_crl_free( crl );
Paul Bakker51876562013-09-17 14:36:05 +0200343 return( POLARSSL_ERR_X509_INVALID_FORMAT );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200344 }
345
346 if( len != (size_t) ( end - p ) )
347 {
348 x509_crl_free( crl );
Paul Bakker51876562013-09-17 14:36:05 +0200349 return( POLARSSL_ERR_X509_INVALID_FORMAT +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200350 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
351 }
352
353 /*
354 * TBSCertList ::= SEQUENCE {
355 */
356 crl->tbs.p = p;
357
358 if( ( ret = asn1_get_tag( &p, end, &len,
359 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
360 {
361 x509_crl_free( crl );
Paul Bakker51876562013-09-17 14:36:05 +0200362 return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200363 }
364
365 end = p + len;
366 crl->tbs.len = end - crl->tbs.p;
367
368 /*
369 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
370 * -- if present, MUST be v2
371 *
372 * signature AlgorithmIdentifier
373 */
374 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
375 ( ret = x509_get_alg_null( &p, end, &crl->sig_oid1 ) ) != 0 )
376 {
377 x509_crl_free( crl );
378 return( ret );
379 }
380
381 crl->version++;
382
383 if( crl->version > 2 )
384 {
385 x509_crl_free( crl );
Paul Bakker51876562013-09-17 14:36:05 +0200386 return( POLARSSL_ERR_X509_UNKNOWN_VERSION );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200387 }
388
389 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_md,
390 &crl->sig_pk ) ) != 0 )
391 {
392 x509_crl_free( crl );
Paul Bakker51876562013-09-17 14:36:05 +0200393 return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200394 }
395
396 /*
397 * issuer Name
398 */
399 crl->issuer_raw.p = p;
400
401 if( ( ret = asn1_get_tag( &p, end, &len,
402 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
403 {
404 x509_crl_free( crl );
Paul Bakker51876562013-09-17 14:36:05 +0200405 return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200406 }
407
408 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
409 {
410 x509_crl_free( crl );
411 return( ret );
412 }
413
414 crl->issuer_raw.len = p - crl->issuer_raw.p;
415
416 /*
417 * thisUpdate Time
418 * nextUpdate Time OPTIONAL
419 */
420 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
421 {
422 x509_crl_free( crl );
423 return( ret );
424 }
425
426 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
427 {
Paul Bakker51876562013-09-17 14:36:05 +0200428 if ( ret != ( POLARSSL_ERR_X509_INVALID_DATE +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200429 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker51876562013-09-17 14:36:05 +0200430 ret != ( POLARSSL_ERR_X509_INVALID_DATE +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200431 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
432 {
433 x509_crl_free( crl );
434 return( ret );
435 }
436 }
437
438 /*
439 * revokedCertificates SEQUENCE OF SEQUENCE {
440 * userCertificate CertificateSerialNumber,
441 * revocationDate Time,
442 * crlEntryExtensions Extensions OPTIONAL
443 * -- if present, MUST be v2
444 * } OPTIONAL
445 */
446 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
447 {
448 x509_crl_free( crl );
449 return( ret );
450 }
451
452 /*
453 * crlExtensions EXPLICIT Extensions OPTIONAL
454 * -- if present, MUST be v2
455 */
456 if( crl->version == 2 )
457 {
458 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
459
460 if( ret != 0 )
461 {
462 x509_crl_free( crl );
463 return( ret );
464 }
465 }
466
467 if( p != end )
468 {
469 x509_crl_free( crl );
Paul Bakker51876562013-09-17 14:36:05 +0200470 return( POLARSSL_ERR_X509_INVALID_FORMAT +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200471 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
472 }
473
474 end = crl->raw.p + crl->raw.len;
475
476 /*
477 * signatureAlgorithm AlgorithmIdentifier,
478 * signatureValue BIT STRING
479 */
480 if( ( ret = x509_get_alg_null( &p, end, &crl->sig_oid2 ) ) != 0 )
481 {
482 x509_crl_free( crl );
483 return( ret );
484 }
485
486 if( crl->sig_oid1.len != crl->sig_oid2.len ||
487 memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
488 {
489 x509_crl_free( crl );
Paul Bakker51876562013-09-17 14:36:05 +0200490 return( POLARSSL_ERR_X509_SIG_MISMATCH );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200491 }
492
493 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
494 {
495 x509_crl_free( crl );
496 return( ret );
497 }
498
499 if( p != end )
500 {
501 x509_crl_free( crl );
Paul Bakker51876562013-09-17 14:36:05 +0200502 return( POLARSSL_ERR_X509_INVALID_FORMAT +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200503 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
504 }
505
506 if( buflen > 0 )
507 {
508 crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
509
510 if( crl->next == NULL )
511 {
512 x509_crl_free( crl );
513 return( POLARSSL_ERR_X509_MALLOC_FAILED );
514 }
515
516 crl = crl->next;
Paul Bakker369d2eb2013-09-18 11:58:25 +0200517 x509_crl_init( crl );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200518
Paul Bakkerddf26b42013-09-18 13:46:23 +0200519 return( x509_crl_parse( crl, buf, buflen ) );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200520 }
521
522 return( 0 );
523}
524
525#if defined(POLARSSL_FS_IO)
526/*
527 * Load one or more CRLs and add them to the chained list
528 */
Paul Bakkerddf26b42013-09-18 13:46:23 +0200529int x509_crl_parse_file( x509_crl *chain, const char *path )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200530{
531 int ret;
532 size_t n;
533 unsigned char *buf;
534
535 if ( ( ret = x509_load_file( path, &buf, &n ) ) != 0 )
536 return( ret );
537
Paul Bakkerddf26b42013-09-18 13:46:23 +0200538 ret = x509_crl_parse( chain, buf, n );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200539
540 memset( buf, 0, n + 1 );
541 polarssl_free( buf );
542
543 return( ret );
544}
545#endif /* POLARSSL_FS_IO */
546
547#if defined _MSC_VER && !defined snprintf
548#include <stdarg.h>
549
550#if !defined vsnprintf
551#define vsnprintf _vsnprintf
552#endif // vsnprintf
553
554/*
555 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
556 * Result value is not size of buffer needed, but -1 if no fit is possible.
557 *
558 * This fuction tries to 'fix' this by at least suggesting enlarging the
559 * size by 20.
560 */
561static int compat_snprintf(char *str, size_t size, const char *format, ...)
562{
563 va_list ap;
564 int res = -1;
565
566 va_start( ap, format );
567
568 res = vsnprintf( str, size, format, ap );
569
570 va_end( ap );
571
572 // No quick fix possible
573 if ( res < 0 )
574 return( (int) size + 20 );
575
576 return res;
577}
578
579#define snprintf compat_snprintf
580#endif
581
582#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
583
584#define SAFE_SNPRINTF() \
585{ \
586 if( ret == -1 ) \
587 return( -1 ); \
588 \
589 if ( (unsigned int) ret > n ) { \
590 p[n - 1] = '\0'; \
591 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
592 } \
593 \
594 n -= (unsigned int) ret; \
595 p += (unsigned int) ret; \
596}
597
598/*
599 * Return an informational string about the certificate.
600 */
601#define BEFORE_COLON 14
602#define BC "14"
603/*
604 * Return an informational string about the CRL.
605 */
Paul Bakkerddf26b42013-09-18 13:46:23 +0200606int x509_crl_info( char *buf, size_t size, const char *prefix,
607 const x509_crl *crl )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200608{
609 int ret;
610 size_t n;
611 char *p;
612 const char *desc;
613 const x509_crl_entry *entry;
614
615 p = buf;
616 n = size;
617
618 ret = snprintf( p, n, "%sCRL version : %d",
619 prefix, crl->version );
620 SAFE_SNPRINTF();
621
622 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
623 SAFE_SNPRINTF();
Paul Bakker86d0c192013-09-18 11:11:02 +0200624 ret = x509_dn_gets( p, n, &crl->issuer );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200625 SAFE_SNPRINTF();
626
627 ret = snprintf( p, n, "\n%sthis update : " \
628 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
629 crl->this_update.year, crl->this_update.mon,
630 crl->this_update.day, crl->this_update.hour,
631 crl->this_update.min, crl->this_update.sec );
632 SAFE_SNPRINTF();
633
634 ret = snprintf( p, n, "\n%snext update : " \
635 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
636 crl->next_update.year, crl->next_update.mon,
637 crl->next_update.day, crl->next_update.hour,
638 crl->next_update.min, crl->next_update.sec );
639 SAFE_SNPRINTF();
640
641 entry = &crl->entry;
642
643 ret = snprintf( p, n, "\n%sRevoked certificates:",
644 prefix );
645 SAFE_SNPRINTF();
646
647 while( entry != NULL && entry->raw.len != 0 )
648 {
649 ret = snprintf( p, n, "\n%sserial number: ",
650 prefix );
651 SAFE_SNPRINTF();
652
Paul Bakker86d0c192013-09-18 11:11:02 +0200653 ret = x509_serial_gets( p, n, &entry->serial);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200654 SAFE_SNPRINTF();
655
656 ret = snprintf( p, n, " revocation date: " \
657 "%04d-%02d-%02d %02d:%02d:%02d",
658 entry->revocation_date.year, entry->revocation_date.mon,
659 entry->revocation_date.day, entry->revocation_date.hour,
660 entry->revocation_date.min, entry->revocation_date.sec );
661 SAFE_SNPRINTF();
662
663 entry = entry->next;
664 }
665
666 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
667 SAFE_SNPRINTF();
668
669 ret = oid_get_sig_alg_desc( &crl->sig_oid1, &desc );
670 if( ret != 0 )
671 ret = snprintf( p, n, "???" );
672 else
673 ret = snprintf( p, n, "%s", desc );
674 SAFE_SNPRINTF();
675
676 ret = snprintf( p, n, "\n" );
677 SAFE_SNPRINTF();
678
679 return( (int) ( size - n ) );
680}
681
682/*
Paul Bakker369d2eb2013-09-18 11:58:25 +0200683 * Initialize a CRL chain
684 */
685void x509_crl_init( x509_crl *crl )
686{
687 memset( crl, 0, sizeof(x509_crl) );
688}
689
690/*
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200691 * Unallocate all CRL data
692 */
693void x509_crl_free( x509_crl *crl )
694{
695 x509_crl *crl_cur = crl;
696 x509_crl *crl_prv;
697 x509_name *name_cur;
698 x509_name *name_prv;
699 x509_crl_entry *entry_cur;
700 x509_crl_entry *entry_prv;
701
702 if( crl == NULL )
703 return;
704
705 do
706 {
707 name_cur = crl_cur->issuer.next;
708 while( name_cur != NULL )
709 {
710 name_prv = name_cur;
711 name_cur = name_cur->next;
712 memset( name_prv, 0, sizeof( x509_name ) );
713 polarssl_free( name_prv );
714 }
715
716 entry_cur = crl_cur->entry.next;
717 while( entry_cur != NULL )
718 {
719 entry_prv = entry_cur;
720 entry_cur = entry_cur->next;
721 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
722 polarssl_free( entry_prv );
723 }
724
725 if( crl_cur->raw.p != NULL )
726 {
727 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
728 polarssl_free( crl_cur->raw.p );
729 }
730
731 crl_cur = crl_cur->next;
732 }
733 while( crl_cur != NULL );
734
735 crl_cur = crl;
736 do
737 {
738 crl_prv = crl_cur;
739 crl_cur = crl_cur->next;
740
741 memset( crl_prv, 0, sizeof( x509_crl ) );
742 if( crl_prv != crl )
743 polarssl_free( crl_prv );
744 }
745 while( crl_cur != NULL );
746}
747
748#endif