PolarSSL v1.3.1
x509.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_USE_C)
40 
41 #include "polarssl/x509.h"
42 #include "polarssl/asn1.h"
43 #include "polarssl/oid.h"
44 #if defined(POLARSSL_PEM_PARSE_C)
45 #include "polarssl/pem.h"
46 #endif
47 
48 #if defined(POLARSSL_MEMORY_C)
49 #include "polarssl/memory.h"
50 #else
51 #define polarssl_malloc malloc
52 #define polarssl_free free
53 #endif
54 
55 #include <string.h>
56 #include <stdlib.h>
57 #if defined(_WIN32)
58 #include <windows.h>
59 #else
60 #include <time.h>
61 #endif
62 
63 #if defined(POLARSSL_FS_IO)
64 #include <stdio.h>
65 #if !defined(_WIN32)
66 #include <sys/types.h>
67 #include <sys/stat.h>
68 #include <dirent.h>
69 #endif
70 #endif
71 
72 /*
73  * CertificateSerialNumber ::= INTEGER
74  */
75 int x509_get_serial( unsigned char **p, const unsigned char *end,
76  x509_buf *serial )
77 {
78  int ret;
79 
80  if( ( end - *p ) < 1 )
83 
84  if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
85  **p != ASN1_INTEGER )
88 
89  serial->tag = *(*p)++;
90 
91  if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
92  return( POLARSSL_ERR_X509_INVALID_SERIAL + ret );
93 
94  serial->p = *p;
95  *p += serial->len;
96 
97  return( 0 );
98 }
99 
100 /* Get an algorithm identifier without parameters (eg for signatures)
101  *
102  * AlgorithmIdentifier ::= SEQUENCE {
103  * algorithm OBJECT IDENTIFIER,
104  * parameters ANY DEFINED BY algorithm OPTIONAL }
105  */
106 int x509_get_alg_null( unsigned char **p, const unsigned char *end,
107  x509_buf *alg )
108 {
109  int ret;
110 
111  if( ( ret = asn1_get_alg_null( p, end, alg ) ) != 0 )
112  return( POLARSSL_ERR_X509_INVALID_ALG + ret );
113 
114  return( 0 );
115 }
116 
117 /*
118  * AttributeTypeAndValue ::= SEQUENCE {
119  * type AttributeType,
120  * value AttributeValue }
121  *
122  * AttributeType ::= OBJECT IDENTIFIER
123  *
124  * AttributeValue ::= ANY DEFINED BY AttributeType
125  */
126 static int x509_get_attr_type_value( unsigned char **p,
127  const unsigned char *end,
128  x509_name *cur )
129 {
130  int ret;
131  size_t len;
132  x509_buf *oid;
133  x509_buf *val;
134 
135  if( ( ret = asn1_get_tag( p, end, &len,
136  ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
137  return( POLARSSL_ERR_X509_INVALID_NAME + ret );
138 
139  if( ( end - *p ) < 1 )
142 
143  oid = &cur->oid;
144  oid->tag = **p;
145 
146  if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
147  return( POLARSSL_ERR_X509_INVALID_NAME + ret );
148 
149  oid->p = *p;
150  *p += oid->len;
151 
152  if( ( end - *p ) < 1 )
155 
156  if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
157  **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
158  **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
161 
162  val = &cur->val;
163  val->tag = *(*p)++;
164 
165  if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
166  return( POLARSSL_ERR_X509_INVALID_NAME + ret );
167 
168  val->p = *p;
169  *p += val->len;
170 
171  cur->next = NULL;
172 
173  return( 0 );
174 }
175 
176 /*
177  * RelativeDistinguishedName ::=
178  * SET OF AttributeTypeAndValue
179  *
180  * AttributeTypeAndValue ::= SEQUENCE {
181  * type AttributeType,
182  * value AttributeValue }
183  *
184  * AttributeType ::= OBJECT IDENTIFIER
185  *
186  * AttributeValue ::= ANY DEFINED BY AttributeType
187  */
188 int x509_get_name( unsigned char **p, const unsigned char *end,
189  x509_name *cur )
190 {
191  int ret;
192  size_t len;
193  const unsigned char *end2;
194  x509_name *use;
195 
196  if( ( ret = asn1_get_tag( p, end, &len,
197  ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
198  return( POLARSSL_ERR_X509_INVALID_NAME + ret );
199 
200  end2 = end;
201  end = *p + len;
202  use = cur;
203 
204  do
205  {
206  if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
207  return( ret );
208 
209  if( *p != end )
210  {
211  use->next = (x509_name *) polarssl_malloc(
212  sizeof( x509_name ) );
213 
214  if( use->next == NULL )
216 
217  memset( use->next, 0, sizeof( x509_name ) );
218 
219  use = use->next;
220  }
221  }
222  while( *p != end );
223 
224  /*
225  * recurse until end of SEQUENCE is reached
226  */
227  if( *p == end2 )
228  return( 0 );
229 
230  cur->next = (x509_name *) polarssl_malloc(
231  sizeof( x509_name ) );
232 
233  if( cur->next == NULL )
235 
236  memset( cur->next, 0, sizeof( x509_name ) );
237 
238  return( x509_get_name( p, end2, cur->next ) );
239 }
240 
241 /*
242  * Time ::= CHOICE {
243  * utcTime UTCTime,
244  * generalTime GeneralizedTime }
245  */
246 int x509_get_time( unsigned char **p, const unsigned char *end,
247  x509_time *time )
248 {
249  int ret;
250  size_t len;
251  char date[64];
252  unsigned char tag;
253 
254  if( ( end - *p ) < 1 )
257 
258  tag = **p;
259 
260  if ( tag == ASN1_UTC_TIME )
261  {
262  (*p)++;
263  ret = asn1_get_len( p, end, &len );
264 
265  if( ret != 0 )
266  return( POLARSSL_ERR_X509_INVALID_DATE + ret );
267 
268  memset( date, 0, sizeof( date ) );
269  memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
270  len : sizeof( date ) - 1 );
271 
272  if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
273  &time->year, &time->mon, &time->day,
274  &time->hour, &time->min, &time->sec ) < 5 )
276 
277  time->year += 100 * ( time->year < 50 );
278  time->year += 1900;
279 
280  *p += len;
281 
282  return( 0 );
283  }
284  else if ( tag == ASN1_GENERALIZED_TIME )
285  {
286  (*p)++;
287  ret = asn1_get_len( p, end, &len );
288 
289  if( ret != 0 )
290  return( POLARSSL_ERR_X509_INVALID_DATE + ret );
291 
292  memset( date, 0, sizeof( date ) );
293  memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
294  len : sizeof( date ) - 1 );
295 
296  if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
297  &time->year, &time->mon, &time->day,
298  &time->hour, &time->min, &time->sec ) < 5 )
300 
301  *p += len;
302 
303  return( 0 );
304  }
305  else
308 }
309 
310 int x509_get_sig( unsigned char **p, const unsigned char *end, x509_buf *sig )
311 {
312  int ret;
313  size_t len;
314 
315  if( ( end - *p ) < 1 )
318 
319  sig->tag = **p;
320 
321  if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 )
322  return( POLARSSL_ERR_X509_INVALID_SIGNATURE + ret );
323 
324  sig->len = len;
325  sig->p = *p;
326 
327  *p += len;
328 
329  return( 0 );
330 }
331 
332 int x509_get_sig_alg( const x509_buf *sig_oid, md_type_t *md_alg,
333  pk_type_t *pk_alg )
334 {
335  int ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg );
336 
337  if( ret != 0 )
338  return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG + ret );
339 
340  return( 0 );
341 }
342 
343 /*
344  * X.509 Extensions (No parsing of extensions, pointer should
345  * be either manually updated or extensions should be parsed!
346  */
347 int x509_get_ext( unsigned char **p, const unsigned char *end,
348  x509_buf *ext, int tag )
349 {
350  int ret;
351  size_t len;
352 
353  if( *p == end )
354  return( 0 );
355 
356  ext->tag = **p;
357 
358  if( ( ret = asn1_get_tag( p, end, &ext->len,
359  ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
360  return( ret );
361 
362  ext->p = *p;
363  end = *p + ext->len;
364 
365  /*
366  * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
367  *
368  * Extension ::= SEQUENCE {
369  * extnID OBJECT IDENTIFIER,
370  * critical BOOLEAN DEFAULT FALSE,
371  * extnValue OCTET STRING }
372  */
373  if( ( ret = asn1_get_tag( p, end, &len,
374  ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
375  return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
376 
377  if( end != *p + len )
380 
381  return( 0 );
382 }
383 
384 #if defined(POLARSSL_FS_IO)
385 /*
386  * Load all data from a file into a given buffer.
387  */
388 int x509_load_file( const char *path, unsigned char **buf, size_t *n )
389 {
390  FILE *f;
391  long size;
392 
393  if( ( f = fopen( path, "rb" ) ) == NULL )
395 
396  fseek( f, 0, SEEK_END );
397  if( ( size = ftell( f ) ) == -1 )
398  {
399  fclose( f );
401  }
402  fseek( f, 0, SEEK_SET );
403 
404  *n = (size_t) size;
405 
406  if( *n + 1 == 0 ||
407  ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
408  {
409  fclose( f );
411  }
412 
413  if( fread( *buf, 1, *n, f ) != *n )
414  {
415  fclose( f );
416  polarssl_free( *buf );
418  }
419 
420  fclose( f );
421 
422  (*buf)[*n] = '\0';
423 
424  return( 0 );
425 }
426 #endif /* POLARSSL_FS_IO */
427 
428 #if defined _MSC_VER && !defined snprintf
429 #include <stdarg.h>
430 
431 #if !defined vsnprintf
432 #define vsnprintf _vsnprintf
433 #endif // vsnprintf
434 
435 /*
436  * Windows _snprintf and _vsnprintf are not compatible to linux versions.
437  * Result value is not size of buffer needed, but -1 if no fit is possible.
438  *
439  * This fuction tries to 'fix' this by at least suggesting enlarging the
440  * size by 20.
441  */
442 static int compat_snprintf(char *str, size_t size, const char *format, ...)
443 {
444  va_list ap;
445  int res = -1;
446 
447  va_start( ap, format );
448 
449  res = vsnprintf( str, size, format, ap );
450 
451  va_end( ap );
452 
453  // No quick fix possible
454  if ( res < 0 )
455  return( (int) size + 20 );
456 
457  return res;
458 }
459 
460 #define snprintf compat_snprintf
461 #endif
462 
463 #define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
464 
465 #define SAFE_SNPRINTF() \
466 { \
467  if( ret == -1 ) \
468  return( -1 ); \
469  \
470  if ( (unsigned int) ret > n ) { \
471  p[n - 1] = '\0'; \
472  return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
473  } \
474  \
475  n -= (unsigned int) ret; \
476  p += (unsigned int) ret; \
477 }
478 
479 /*
480  * Store the name in printable form into buf; no more
481  * than size characters will be written
482  */
483 int x509_dn_gets( char *buf, size_t size, const x509_name *dn )
484 {
485  int ret;
486  size_t i, n;
487  unsigned char c;
488  const x509_name *name;
489  const char *short_name = NULL;
490  char s[128], *p;
491 
492  memset( s, 0, sizeof( s ) );
493 
494  name = dn;
495  p = buf;
496  n = size;
497 
498  while( name != NULL )
499  {
500  if( !name->oid.p )
501  {
502  name = name->next;
503  continue;
504  }
505 
506  if( name != dn )
507  {
508  ret = snprintf( p, n, ", " );
509  SAFE_SNPRINTF();
510  }
511 
512  ret = oid_get_attr_short_name( &name->oid, &short_name );
513 
514  if( ret == 0 )
515  ret = snprintf( p, n, "%s=", short_name );
516  else
517  ret = snprintf( p, n, "\?\?=" );
518  SAFE_SNPRINTF();
519 
520  for( i = 0; i < name->val.len; i++ )
521  {
522  if( i >= sizeof( s ) - 1 )
523  break;
524 
525  c = name->val.p[i];
526  if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
527  s[i] = '?';
528  else s[i] = c;
529  }
530  s[i] = '\0';
531  ret = snprintf( p, n, "%s", s );
532  SAFE_SNPRINTF();
533  name = name->next;
534  }
535 
536  return( (int) ( size - n ) );
537 }
538 
539 /*
540  * Store the serial in printable form into buf; no more
541  * than size characters will be written
542  */
543 int x509_serial_gets( char *buf, size_t size, const x509_buf *serial )
544 {
545  int ret;
546  size_t i, n, nr;
547  char *p;
548 
549  p = buf;
550  n = size;
551 
552  nr = ( serial->len <= 32 )
553  ? serial->len : 28;
554 
555  for( i = 0; i < nr; i++ )
556  {
557  if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
558  continue;
559 
560  ret = snprintf( p, n, "%02X%s",
561  serial->p[i], ( i < nr - 1 ) ? ":" : "" );
562  SAFE_SNPRINTF();
563  }
564 
565  if( nr != serial->len )
566  {
567  ret = snprintf( p, n, "...." );
568  SAFE_SNPRINTF();
569  }
570 
571  return( (int) ( size - n ) );
572 }
573 
574 /*
575  * Helper for writing "RSA key size", "EC key size", etc
576  */
577 int x509_key_size_helper( char *buf, size_t size, const char *name )
578 {
579  char *p = buf;
580  size_t n = size;
581  int ret;
582 
583  if( strlen( name ) + sizeof( " key size" ) > size )
584  return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;
585 
586  ret = snprintf( p, n, "%s key size", name );
587  SAFE_SNPRINTF();
588 
589  return( 0 );
590 }
591 
592 /*
593  * Return an informational string describing the given OID
594  */
595 const char *x509_oid_get_description( x509_buf *oid )
596 {
597  const char *desc = NULL;
598  int ret;
599 
600  ret = oid_get_extended_key_usage( oid, &desc );
601 
602  if( ret != 0 )
603  return( NULL );
604 
605  return( desc );
606 }
607 
608 /* Return the x.y.z.... style numeric string for the given OID */
609 int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
610 {
611  return oid_get_numeric_string( buf, size, oid );
612 }
613 
614 /*
615  * Return 0 if the x509_time is still valid, or 1 otherwise.
616  */
617 #if defined(POLARSSL_HAVE_TIME)
618 int x509_time_expired( const x509_time *to )
619 {
620  int year, mon, day;
621  int hour, min, sec;
622 
623 #if defined(_WIN32)
624  SYSTEMTIME st;
625 
626  GetLocalTime(&st);
627 
628  year = st.wYear;
629  mon = st.wMonth;
630  day = st.wDay;
631  hour = st.wHour;
632  min = st.wMinute;
633  sec = st.wSecond;
634 #else
635  struct tm *lt;
636  time_t tt;
637 
638  tt = time( NULL );
639  lt = localtime( &tt );
640 
641  year = lt->tm_year + 1900;
642  mon = lt->tm_mon + 1;
643  day = lt->tm_mday;
644  hour = lt->tm_hour;
645  min = lt->tm_min;
646  sec = lt->tm_sec;
647 #endif
648 
649  if( year > to->year )
650  return( 1 );
651 
652  if( year == to->year &&
653  mon > to->mon )
654  return( 1 );
655 
656  if( year == to->year &&
657  mon == to->mon &&
658  day > to->day )
659  return( 1 );
660 
661  if( year == to->year &&
662  mon == to->mon &&
663  day == to->day &&
664  hour > to->hour )
665  return( 1 );
666 
667  if( year == to->year &&
668  mon == to->mon &&
669  day == to->day &&
670  hour == to->hour &&
671  min > to->min )
672  return( 1 );
673 
674  if( year == to->year &&
675  mon == to->mon &&
676  day == to->day &&
677  hour == to->hour &&
678  min == to->min &&
679  sec > to->sec )
680  return( 1 );
681 
682  return( 0 );
683 }
684 #else /* POLARSSL_HAVE_TIME */
685 int x509_time_expired( const x509_time *to )
686 {
687  ((void) to);
688  return( 0 );
689 }
690 #endif /* POLARSSL_HAVE_TIME */
691 
692 #if defined(POLARSSL_SELF_TEST)
693 
694 #include "polarssl/x509_crt.h"
695 #include "polarssl/certs.h"
696 
697 /*
698  * Checkup routine
699  */
700 int x509_self_test( int verbose )
701 {
702 #if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
703  int ret;
704  int flags;
705  x509_crt cacert;
706  x509_crt clicert;
707 
708  if( verbose != 0 )
709  printf( " X.509 certificate load: " );
710 
711  x509_crt_init( &clicert );
712 
713  ret = x509_crt_parse( &clicert, (const unsigned char *) test_cli_crt,
714  strlen( test_cli_crt ) );
715  if( ret != 0 )
716  {
717  if( verbose != 0 )
718  printf( "failed\n" );
719 
720  return( ret );
721  }
722 
723  x509_crt_init( &cacert );
724 
725  ret = x509_crt_parse( &cacert, (const unsigned char *) test_ca_crt,
726  strlen( test_ca_crt ) );
727  if( ret != 0 )
728  {
729  if( verbose != 0 )
730  printf( "failed\n" );
731 
732  return( ret );
733  }
734 
735  if( verbose != 0 )
736  printf( "passed\n X.509 signature verify: ");
737 
738  ret = x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL );
739  if( ret != 0 )
740  {
741  if( verbose != 0 )
742  printf( "failed\n" );
743 
744  printf("ret = %d, &flags = %04x\n", ret, flags);
745 
746  return( ret );
747  }
748 
749  if( verbose != 0 )
750  printf( "passed\n\n");
751 
752  x509_crt_free( &cacert );
753  x509_crt_free( &clicert );
754 
755  return( 0 );
756 #else
757  ((void) verbose);
759 #endif
760 }
761 
762 #endif
763 
764 #endif /* POLARSSL_X509_USE_C */