PolarSSL v1.3.1
x509_crl.c
Go to the documentation of this file.
1 /*
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  */
69 static 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  {
78  {
79  *ver = 0;
80  return( 0 );
81  }
82 
83  return( POLARSSL_ERR_X509_INVALID_VERSION + ret );
84  }
85 
86  return( 0 );
87 }
88 
89 /*
90  * X.509 CRL v2 extensions (no extensions parsed yet.)
91  */
92 static 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  {
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 )
112  return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
113 
114  *p += len;
115  }
116 
117  if( *p != end )
120 
121  return( 0 );
122 }
123 
124 /*
125  * X.509 CRL v2 entry extensions (no extensions parsed yet.)
126  */
127 static 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  {
149  {
150  ext->p = NULL;
151  return( 0 );
152  }
153  return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
154  }
155 
156  end = *p + ext->len;
157 
158  if( end != *p + ext->len )
161 
162  while( *p < end )
163  {
164  if( ( ret = asn1_get_tag( p, end, &len,
165  ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
166  return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
167 
168  *p += len;
169  }
170 
171  if( *p != end )
174 
175  return( 0 );
176 }
177 
178 /*
179  * X.509 CRL Entries
180  */
181 static 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  {
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 )
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  */
246 int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen )
247 {
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 )
264 
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 );
279  }
280 
281  crl = crl->next;
282  x509_crl_init( crl );
283  }
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  }
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 )
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 );
344  }
345 
346  if( len != (size_t) ( end - p ) )
347  {
348  x509_crl_free( crl );
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 );
362  return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
363  }
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 );
387  }
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 );
394  }
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 );
405  return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
406  }
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  {
428  if ( ret != ( POLARSSL_ERR_X509_INVALID_DATE +
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 );
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 );
491  }
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 );
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 );
514  }
515 
516  crl = crl->next;
517  x509_crl_init( crl );
518 
519  return( x509_crl_parse( crl, buf, buflen ) );
520  }
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  */
529 int x509_crl_parse_file( x509_crl *chain, const char *path )
530 {
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 
538  ret = x509_crl_parse( chain, buf, n );
539 
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  */
561 static 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  */
606 int x509_crl_info( char *buf, size_t size, const char *prefix,
607  const x509_crl *crl )
608 {
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();
624  ret = x509_dn_gets( p, n, &crl->issuer );
625  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 
653  ret = x509_serial_gets( p, n, &entry->serial);
654  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 /*
683  * Initialize a CRL chain
684  */
685 void x509_crl_init( x509_crl *crl )
686 {
687  memset( crl, 0, sizeof(x509_crl) );
688 }
689 
690 /*
691  * Unallocate all CRL data
692  */
693 void 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