PolarSSL v1.3.9
x509.c
Go to the documentation of this file.
1 /*
2  * X.509 common functions for parsing and verification
3  *
4  * Copyright (C) 2006-2014, 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/rfc5280.txt (Certificates and CRLs)
29  * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
30  * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
31  *
32  * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
33  * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
34  */
35 
36 #if !defined(POLARSSL_CONFIG_FILE)
37 #include "polarssl/config.h"
38 #else
39 #include POLARSSL_CONFIG_FILE
40 #endif
41 
42 #if defined(POLARSSL_X509_USE_C)
43 
44 #include "polarssl/x509.h"
45 #include "polarssl/asn1.h"
46 #include "polarssl/oid.h"
47 #if defined(POLARSSL_PEM_PARSE_C)
48 #include "polarssl/pem.h"
49 #endif
50 
51 #if defined(POLARSSL_PLATFORM_C)
52 #include "polarssl/platform.h"
53 #else
54 #define polarssl_printf printf
55 #define polarssl_malloc malloc
56 #define polarssl_free free
57 #endif
58 
59 #include <string.h>
60 #include <stdlib.h>
61 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
62 #include <windows.h>
63 #else
64 #include <time.h>
65 #endif
66 
67 #if defined(EFIX64) || defined(EFI32)
68 #include <stdio.h>
69 #endif
70 
71 #if defined(POLARSSL_FS_IO)
72 #include <stdio.h>
73 #if !defined(_WIN32)
74 #include <sys/types.h>
75 #include <sys/stat.h>
76 #include <dirent.h>
77 #endif
78 #endif
79 
80 /*
81  * CertificateSerialNumber ::= INTEGER
82  */
83 int x509_get_serial( unsigned char **p, const unsigned char *end,
84  x509_buf *serial )
85 {
86  int ret;
87 
88  if( ( end - *p ) < 1 )
91 
92  if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
93  **p != ASN1_INTEGER )
96 
97  serial->tag = *(*p)++;
98 
99  if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
100  return( POLARSSL_ERR_X509_INVALID_SERIAL + ret );
101 
102  serial->p = *p;
103  *p += serial->len;
104 
105  return( 0 );
106 }
107 
108 /* Get an algorithm identifier without parameters (eg for signatures)
109  *
110  * AlgorithmIdentifier ::= SEQUENCE {
111  * algorithm OBJECT IDENTIFIER,
112  * parameters ANY DEFINED BY algorithm OPTIONAL }
113  */
114 int x509_get_alg_null( unsigned char **p, const unsigned char *end,
115  x509_buf *alg )
116 {
117  int ret;
118 
119  if( ( ret = asn1_get_alg_null( p, end, alg ) ) != 0 )
120  return( POLARSSL_ERR_X509_INVALID_ALG + ret );
121 
122  return( 0 );
123 }
124 
125 /*
126  * Parse an algorithm identifier with (optional) paramaters
127  */
128 int x509_get_alg( unsigned char **p, const unsigned char *end,
129  x509_buf *alg, x509_buf *params )
130 {
131  int ret;
132 
133  if( ( ret = asn1_get_alg( p, end, alg, params ) ) != 0 )
134  return( POLARSSL_ERR_X509_INVALID_ALG + ret );
135 
136  return( 0 );
137 }
138 
139 #if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
140 /*
141  * HashAlgorithm ::= AlgorithmIdentifier
142  *
143  * AlgorithmIdentifier ::= SEQUENCE {
144  * algorithm OBJECT IDENTIFIER,
145  * parameters ANY DEFINED BY algorithm OPTIONAL }
146  *
147  * For HashAlgorithm, parameters MUST be NULL or absent.
148  */
149 static int x509_get_hash_alg( const x509_buf *alg, md_type_t *md_alg )
150 {
151  int ret;
152  unsigned char *p;
153  const unsigned char *end;
154  x509_buf md_oid;
155  size_t len;
156 
157  /* Make sure we got a SEQUENCE and setup bounds */
158  if( alg->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
161 
162  p = (unsigned char *) alg->p;
163  end = p + alg->len;
164 
165  if( p >= end )
168 
169  /* Parse md_oid */
170  md_oid.tag = *p;
171 
172  if( ( ret = asn1_get_tag( &p, end, &md_oid.len, ASN1_OID ) ) != 0 )
173  return( POLARSSL_ERR_X509_INVALID_ALG + ret );
174 
175  md_oid.p = p;
176  p += md_oid.len;
177 
178  /* Get md_alg from md_oid */
179  if( ( ret = oid_get_md_alg( &md_oid, md_alg ) ) != 0 )
180  return( POLARSSL_ERR_X509_INVALID_ALG + ret );
181 
182  /* Make sure params is absent of NULL */
183  if( p == end )
184  return( 0 );
185 
186  if( ( ret = asn1_get_tag( &p, end, &len, ASN1_NULL ) ) != 0 || len != 0 )
187  return( POLARSSL_ERR_X509_INVALID_ALG + ret );
188 
189  if( p != end )
192 
193  return( 0 );
194 }
195 
196 /*
197  * RSASSA-PSS-params ::= SEQUENCE {
198  * hashAlgorithm [0] HashAlgorithm DEFAULT sha1Identifier,
199  * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier,
200  * saltLength [2] INTEGER DEFAULT 20,
201  * trailerField [3] INTEGER DEFAULT 1 }
202  * -- Note that the tags in this Sequence are explicit.
203  *
204  * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value
205  * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other
206  * option. Enfore this at parsing time.
207  */
208 int x509_get_rsassa_pss_params( const x509_buf *params,
209  md_type_t *md_alg, md_type_t *mgf_md,
210  int *salt_len )
211 {
212  int ret;
213  unsigned char *p;
214  const unsigned char *end, *end2;
215  size_t len;
216  x509_buf alg_id, alg_params;
217 
218  /* First set everything to defaults */
219  *md_alg = POLARSSL_MD_SHA1;
220  *mgf_md = POLARSSL_MD_SHA1;
221  *salt_len = 20;
222 
223  /* Make sure params is a SEQUENCE and setup bounds */
224  if( params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
227 
228  p = (unsigned char *) params->p;
229  end = p + params->len;
230 
231  if( p == end )
232  return( 0 );
233 
234  /*
235  * HashAlgorithm
236  */
237  if( ( ret = asn1_get_tag( &p, end, &len,
238  ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) == 0 )
239  {
240  end2 = p + len;
241 
242  /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */
243  if( ( ret = x509_get_alg_null( &p, end2, &alg_id ) ) != 0 )
244  return( ret );
245 
246  if( ( ret = oid_get_md_alg( &alg_id, md_alg ) ) != 0 )
247  return( POLARSSL_ERR_X509_INVALID_ALG + ret );
248 
249  if( p != end2 )
252  }
253  else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
254  return( POLARSSL_ERR_X509_INVALID_ALG + ret );
255 
256  if( p == end )
257  return( 0 );
258 
259  /*
260  * MaskGenAlgorithm
261  */
262  if( ( ret = asn1_get_tag( &p, end, &len,
263  ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 )
264  {
265  end2 = p + len;
266 
267  /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */
268  if( ( ret = x509_get_alg( &p, end2, &alg_id, &alg_params ) ) != 0 )
269  return( ret );
270 
271  /* Only MFG1 is recognised for now */
272  if( ! OID_CMP( OID_MGF1, &alg_id ) )
275 
276  /* Parse HashAlgorithm */
277  if( ( ret = x509_get_hash_alg( &alg_params, mgf_md ) ) != 0 )
278  return( ret );
279 
280  if( p != end2 )
283  }
284  else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
285  return( POLARSSL_ERR_X509_INVALID_ALG + ret );
286 
287  if( p == end )
288  return( 0 );
289 
290  /*
291  * salt_len
292  */
293  if( ( ret = asn1_get_tag( &p, end, &len,
294  ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 2 ) ) == 0 )
295  {
296  end2 = p + len;
297 
298  if( ( ret = asn1_get_int( &p, end2, salt_len ) ) != 0 )
299  return( POLARSSL_ERR_X509_INVALID_ALG + ret );
300 
301  if( p != end2 )
304  }
305  else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
306  return( POLARSSL_ERR_X509_INVALID_ALG + ret );
307 
308  if( p == end )
309  return( 0 );
310 
311  /*
312  * trailer_field (if present, must be 1)
313  */
314  if( ( ret = asn1_get_tag( &p, end, &len,
315  ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) ) == 0 )
316  {
317  int trailer_field;
318 
319  end2 = p + len;
320 
321  if( ( ret = asn1_get_int( &p, end2, &trailer_field ) ) != 0 )
322  return( POLARSSL_ERR_X509_INVALID_ALG + ret );
323 
324  if( p != end2 )
327 
328  if( trailer_field != 1 )
330  }
331  else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
332  return( POLARSSL_ERR_X509_INVALID_ALG + ret );
333 
334  if( p != end )
337 
338  return( 0 );
339 }
340 #endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */
341 
342 /*
343  * AttributeTypeAndValue ::= SEQUENCE {
344  * type AttributeType,
345  * value AttributeValue }
346  *
347  * AttributeType ::= OBJECT IDENTIFIER
348  *
349  * AttributeValue ::= ANY DEFINED BY AttributeType
350  */
351 static int x509_get_attr_type_value( unsigned char **p,
352  const unsigned char *end,
353  x509_name *cur )
354 {
355  int ret;
356  size_t len;
357  x509_buf *oid;
358  x509_buf *val;
359 
360  if( ( ret = asn1_get_tag( p, end, &len,
361  ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
362  return( POLARSSL_ERR_X509_INVALID_NAME + ret );
363 
364  if( ( end - *p ) < 1 )
367 
368  oid = &cur->oid;
369  oid->tag = **p;
370 
371  if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
372  return( POLARSSL_ERR_X509_INVALID_NAME + ret );
373 
374  oid->p = *p;
375  *p += oid->len;
376 
377  if( ( end - *p ) < 1 )
380 
381  if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
382  **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
383  **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
386 
387  val = &cur->val;
388  val->tag = *(*p)++;
389 
390  if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
391  return( POLARSSL_ERR_X509_INVALID_NAME + ret );
392 
393  val->p = *p;
394  *p += val->len;
395 
396  cur->next = NULL;
397 
398  return( 0 );
399 }
400 
401 /*
402  * RelativeDistinguishedName ::=
403  * SET OF AttributeTypeAndValue
404  *
405  * AttributeTypeAndValue ::= SEQUENCE {
406  * type AttributeType,
407  * value AttributeValue }
408  *
409  * AttributeType ::= OBJECT IDENTIFIER
410  *
411  * AttributeValue ::= ANY DEFINED BY AttributeType
412  *
413  * We restrict RelativeDistinguishedName to be a set of 1 element. This is
414  * the most common case, and our x509_name structure currently can't handle
415  * more than that.
416  */
417 int x509_get_name( unsigned char **p, const unsigned char *end,
418  x509_name *cur )
419 {
420  int ret;
421  size_t set_len;
422  const unsigned char *end_set;
423 
424  /*
425  * parse first SET, restricted to 1 element
426  */
427  if( ( ret = asn1_get_tag( p, end, &set_len,
428  ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
429  return( POLARSSL_ERR_X509_INVALID_NAME + ret );
430 
431  end_set = *p + set_len;
432 
433  if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 )
434  return( ret );
435 
436  if( *p != end_set )
438 
439  /*
440  * recurse until end of SEQUENCE is reached
441  */
442  if( *p == end )
443  return( 0 );
444 
445  cur->next = (x509_name *) polarssl_malloc( sizeof( x509_name ) );
446 
447  if( cur->next == NULL )
449 
450  memset( cur->next, 0, sizeof( x509_name ) );
451 
452  return( x509_get_name( p, end, cur->next ) );
453 }
454 
455 /*
456  * Time ::= CHOICE {
457  * utcTime UTCTime,
458  * generalTime GeneralizedTime }
459  */
460 int x509_get_time( unsigned char **p, const unsigned char *end,
461  x509_time *time )
462 {
463  int ret;
464  size_t len;
465  char date[64];
466  unsigned char tag;
467 
468  if( ( end - *p ) < 1 )
471 
472  tag = **p;
473 
474  if( tag == ASN1_UTC_TIME )
475  {
476  (*p)++;
477  ret = asn1_get_len( p, end, &len );
478 
479  if( ret != 0 )
480  return( POLARSSL_ERR_X509_INVALID_DATE + ret );
481 
482  memset( date, 0, sizeof( date ) );
483  memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
484  len : sizeof( date ) - 1 );
485 
486  if( sscanf( date, "%2d%2d%2d%2d%2d%2dZ",
487  &time->year, &time->mon, &time->day,
488  &time->hour, &time->min, &time->sec ) < 5 )
490 
491  time->year += 100 * ( time->year < 50 );
492  time->year += 1900;
493 
494  *p += len;
495 
496  return( 0 );
497  }
498  else if( tag == ASN1_GENERALIZED_TIME )
499  {
500  (*p)++;
501  ret = asn1_get_len( p, end, &len );
502 
503  if( ret != 0 )
504  return( POLARSSL_ERR_X509_INVALID_DATE + ret );
505 
506  memset( date, 0, sizeof( date ) );
507  memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
508  len : sizeof( date ) - 1 );
509 
510  if( sscanf( date, "%4d%2d%2d%2d%2d%2dZ",
511  &time->year, &time->mon, &time->day,
512  &time->hour, &time->min, &time->sec ) < 5 )
514 
515  *p += len;
516 
517  return( 0 );
518  }
519  else
522 }
523 
524 int x509_get_sig( unsigned char **p, const unsigned char *end, x509_buf *sig )
525 {
526  int ret;
527  size_t len;
528 
529  if( ( end - *p ) < 1 )
532 
533  sig->tag = **p;
534 
535  if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 )
536  return( POLARSSL_ERR_X509_INVALID_SIGNATURE + ret );
537 
538  sig->len = len;
539  sig->p = *p;
540 
541  *p += len;
542 
543  return( 0 );
544 }
545 
546 /*
547  * Get signature algorithm from alg OID and optional parameters
548  */
549 int x509_get_sig_alg( const x509_buf *sig_oid, const x509_buf *sig_params,
550  md_type_t *md_alg, pk_type_t *pk_alg,
551  void **sig_opts )
552 {
553  int ret;
554 
555  if( *sig_opts != NULL )
557 
558  if( ( ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 )
559  return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG + ret );
560 
561 #if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
562  if( *pk_alg == POLARSSL_PK_RSASSA_PSS )
563  {
564  pk_rsassa_pss_options *pss_opts;
565 
566  pss_opts = polarssl_malloc( sizeof( pk_rsassa_pss_options ) );
567  if( pss_opts == NULL )
569 
570  ret = x509_get_rsassa_pss_params( sig_params,
571  md_alg,
572  &pss_opts->mgf1_hash_id,
573  &pss_opts->expected_salt_len );
574  if( ret != 0 )
575  {
576  polarssl_free( pss_opts );
577  return( ret );
578  }
579 
580  *sig_opts = (void *) pss_opts;
581  }
582  else
583 #endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */
584  {
585  /* Make sure parameters are absent or NULL */
586  if( ( sig_params->tag != ASN1_NULL && sig_params->tag != 0 ) ||
587  sig_params->len != 0 )
589  }
590 
591  return( 0 );
592 }
593 
594 /*
595  * X.509 Extensions (No parsing of extensions, pointer should
596  * be either manually updated or extensions should be parsed!
597  */
598 int x509_get_ext( unsigned char **p, const unsigned char *end,
599  x509_buf *ext, int tag )
600 {
601  int ret;
602  size_t len;
603 
604  if( *p == end )
605  return( 0 );
606 
607  ext->tag = **p;
608 
609  if( ( ret = asn1_get_tag( p, end, &ext->len,
610  ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
611  return( ret );
612 
613  ext->p = *p;
614  end = *p + ext->len;
615 
616  /*
617  * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
618  *
619  * Extension ::= SEQUENCE {
620  * extnID OBJECT IDENTIFIER,
621  * critical BOOLEAN DEFAULT FALSE,
622  * extnValue OCTET STRING }
623  */
624  if( ( ret = asn1_get_tag( p, end, &len,
625  ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
626  return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
627 
628  if( end != *p + len )
631 
632  return( 0 );
633 }
634 
635 #if defined(POLARSSL_FS_IO)
636 /*
637  * Load all data from a file into a given buffer.
638  */
639 int x509_load_file( const char *path, unsigned char **buf, size_t *n )
640 {
641  FILE *f;
642  long size;
643 
644  if( ( f = fopen( path, "rb" ) ) == NULL )
646 
647  fseek( f, 0, SEEK_END );
648  if( ( size = ftell( f ) ) == -1 )
649  {
650  fclose( f );
652  }
653  fseek( f, 0, SEEK_SET );
654 
655  *n = (size_t) size;
656 
657  if( *n + 1 == 0 ||
658  ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
659  {
660  fclose( f );
662  }
663 
664  if( fread( *buf, 1, *n, f ) != *n )
665  {
666  fclose( f );
667  polarssl_free( *buf );
669  }
670 
671  fclose( f );
672 
673  (*buf)[*n] = '\0';
674 
675  return( 0 );
676 }
677 #endif /* POLARSSL_FS_IO */
678 
679 #if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \
680  !defined(EFI32)
681 #include <stdarg.h>
682 
683 #if !defined vsnprintf
684 #define vsnprintf _vsnprintf
685 #endif // vsnprintf
686 
687 /*
688  * Windows _snprintf and _vsnprintf are not compatible to linux versions.
689  * Result value is not size of buffer needed, but -1 if no fit is possible.
690  *
691  * This fuction tries to 'fix' this by at least suggesting enlarging the
692  * size by 20.
693  */
694 static int compat_snprintf( char *str, size_t size, const char *format, ... )
695 {
696  va_list ap;
697  int res = -1;
698 
699  va_start( ap, format );
700 
701  res = vsnprintf( str, size, format, ap );
702 
703  va_end( ap );
704 
705  // No quick fix possible
706  if( res < 0 )
707  return( (int) size + 20 );
708 
709  return( res );
710 }
711 
712 #define snprintf compat_snprintf
713 #endif /* _MSC_VER && !snprintf && !EFIX64 && !EFI32 */
714 
715 #define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
716 
717 #define SAFE_SNPRINTF() \
718 { \
719  if( ret == -1 ) \
720  return( -1 ); \
721  \
722  if( (unsigned int) ret > n ) { \
723  p[n - 1] = '\0'; \
724  return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); \
725  } \
726  \
727  n -= (unsigned int) ret; \
728  p += (unsigned int) ret; \
729 }
730 
731 /*
732  * Store the name in printable form into buf; no more
733  * than size characters will be written
734  */
735 int x509_dn_gets( char *buf, size_t size, const x509_name *dn )
736 {
737  int ret;
738  size_t i, n;
739  unsigned char c;
740  const x509_name *name;
741  const char *short_name = NULL;
742  char s[X509_MAX_DN_NAME_SIZE], *p;
743 
744  memset( s, 0, sizeof( s ) );
745 
746  name = dn;
747  p = buf;
748  n = size;
749 
750  while( name != NULL )
751  {
752  if( !name->oid.p )
753  {
754  name = name->next;
755  continue;
756  }
757 
758  if( name != dn )
759  {
760  ret = snprintf( p, n, ", " );
761  SAFE_SNPRINTF();
762  }
763 
764  ret = oid_get_attr_short_name( &name->oid, &short_name );
765 
766  if( ret == 0 )
767  ret = snprintf( p, n, "%s=", short_name );
768  else
769  ret = snprintf( p, n, "\?\?=" );
770  SAFE_SNPRINTF();
771 
772  for( i = 0; i < name->val.len; i++ )
773  {
774  if( i >= sizeof( s ) - 1 )
775  break;
776 
777  c = name->val.p[i];
778  if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
779  s[i] = '?';
780  else s[i] = c;
781  }
782  s[i] = '\0';
783  ret = snprintf( p, n, "%s", s );
784  SAFE_SNPRINTF();
785  name = name->next;
786  }
787 
788  return( (int) ( size - n ) );
789 }
790 
791 /*
792  * Store the serial in printable form into buf; no more
793  * than size characters will be written
794  */
795 int x509_serial_gets( char *buf, size_t size, const x509_buf *serial )
796 {
797  int ret;
798  size_t i, n, nr;
799  char *p;
800 
801  p = buf;
802  n = size;
803 
804  nr = ( serial->len <= 32 )
805  ? serial->len : 28;
806 
807  for( i = 0; i < nr; i++ )
808  {
809  if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
810  continue;
811 
812  ret = snprintf( p, n, "%02X%s",
813  serial->p[i], ( i < nr - 1 ) ? ":" : "" );
814  SAFE_SNPRINTF();
815  }
816 
817  if( nr != serial->len )
818  {
819  ret = snprintf( p, n, "...." );
820  SAFE_SNPRINTF();
821  }
822 
823  return( (int) ( size - n ) );
824 }
825 
826 /*
827  * Helper for writing signature algorithms
828  */
829 int x509_sig_alg_gets( char *buf, size_t size, const x509_buf *sig_oid,
830  pk_type_t pk_alg, md_type_t md_alg,
831  const void *sig_opts )
832 {
833  int ret;
834  char *p = buf;
835  size_t n = size;
836  const char *desc = NULL;
837 
838  ret = oid_get_sig_alg_desc( sig_oid, &desc );
839  if( ret != 0 )
840  ret = snprintf( p, n, "???" );
841  else
842  ret = snprintf( p, n, "%s", desc );
843  SAFE_SNPRINTF();
844 
845 #if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
846  if( pk_alg == POLARSSL_PK_RSASSA_PSS )
847  {
848  const pk_rsassa_pss_options *pss_opts;
849  const md_info_t *md_info, *mgf_md_info;
850 
851  pss_opts = (const pk_rsassa_pss_options *) sig_opts;
852 
853  md_info = md_info_from_type( md_alg );
854  mgf_md_info = md_info_from_type( pss_opts->mgf1_hash_id );
855 
856  ret = snprintf( p, n, " (%s, MGF1-%s, 0x%02X)",
857  md_info ? md_info->name : "???",
858  mgf_md_info ? mgf_md_info->name : "???",
859  pss_opts->expected_salt_len );
860  SAFE_SNPRINTF();
861  }
862 #else
863  ((void) pk_alg);
864  ((void) md_alg);
865  ((void) sig_opts);
866 #endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */
867 
868  return( (int)( size - n ) );
869 }
870 
871 /*
872  * Helper for writing "RSA key size", "EC key size", etc
873  */
874 int x509_key_size_helper( char *buf, size_t size, const char *name )
875 {
876  char *p = buf;
877  size_t n = size;
878  int ret;
879 
880  if( strlen( name ) + sizeof( " key size" ) > size )
881  return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL );
882 
883  ret = snprintf( p, n, "%s key size", name );
884  SAFE_SNPRINTF();
885 
886  return( 0 );
887 }
888 
889 /*
890  * Return an informational string describing the given OID
891  */
892 const char *x509_oid_get_description( x509_buf *oid )
893 {
894  const char *desc = NULL;
895  int ret;
896 
897  ret = oid_get_extended_key_usage( oid, &desc );
898 
899  if( ret != 0 )
900  return( NULL );
901 
902  return( desc );
903 }
904 
905 /* Return the x.y.z.... style numeric string for the given OID */
906 int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
907 {
908  return oid_get_numeric_string( buf, size, oid );
909 }
910 
911 /*
912  * Return 0 if the x509_time is still valid, or 1 otherwise.
913  */
914 #if defined(POLARSSL_HAVE_TIME)
915 
916 static void x509_get_current_time( x509_time *now )
917 {
918 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
919  SYSTEMTIME st;
920 
921  GetSystemTime( &st );
922 
923  now->year = st.wYear;
924  now->mon = st.wMonth;
925  now->day = st.wDay;
926  now->hour = st.wHour;
927  now->min = st.wMinute;
928  now->sec = st.wSecond;
929 #else
930  struct tm lt;
931  time_t tt;
932 
933  tt = time( NULL );
934  gmtime_r( &tt, &lt );
935 
936  now->year = lt.tm_year + 1900;
937  now->mon = lt.tm_mon + 1;
938  now->day = lt.tm_mday;
939  now->hour = lt.tm_hour;
940  now->min = lt.tm_min;
941  now->sec = lt.tm_sec;
942 #endif /* _WIN32 && !EFIX64 && !EFI32 */
943 }
944 
945 /*
946  * Return 0 if before <= after, 1 otherwise
947  */
948 static int x509_check_time( const x509_time *before, const x509_time *after )
949 {
950  if( before->year > after->year )
951  return( 1 );
952 
953  if( before->year == after->year &&
954  before->mon > after->mon )
955  return( 1 );
956 
957  if( before->year == after->year &&
958  before->mon == after->mon &&
959  before->day > after->day )
960  return( 1 );
961 
962  if( before->year == after->year &&
963  before->mon == after->mon &&
964  before->day == after->day &&
965  before->hour > after->hour )
966  return( 1 );
967 
968  if( before->year == after->year &&
969  before->mon == after->mon &&
970  before->day == after->day &&
971  before->hour == after->hour &&
972  before->min > after->min )
973  return( 1 );
974 
975  if( before->year == after->year &&
976  before->mon == after->mon &&
977  before->day == after->day &&
978  before->hour == after->hour &&
979  before->min == after->min &&
980  before->sec > after->sec )
981  return( 1 );
982 
983  return( 0 );
984 }
985 
986 int x509_time_expired( const x509_time *to )
987 {
988  x509_time now;
989 
990  x509_get_current_time( &now );
991 
992  return( x509_check_time( &now, to ) );
993 }
994 
995 int x509_time_future( const x509_time *from )
996 {
997  x509_time now;
998 
999  x509_get_current_time( &now );
1000 
1001  return( x509_check_time( from, &now ) );
1002 }
1003 
1004 #else /* POLARSSL_HAVE_TIME */
1005 
1006 int x509_time_expired( const x509_time *to )
1007 {
1008  ((void) to);
1009  return( 0 );
1010 }
1011 
1012 int x509_time_future( const x509_time *from )
1013 {
1014  ((void) from);
1015  return( 0 );
1016 }
1017 #endif /* POLARSSL_HAVE_TIME */
1018 
1019 #if defined(POLARSSL_SELF_TEST)
1020 
1021 #include "polarssl/x509_crt.h"
1022 #include "polarssl/certs.h"
1023 
1024 /*
1025  * Checkup routine
1026  */
1027 int x509_self_test( int verbose )
1028 {
1029 #if defined(POLARSSL_CERTS_C) && defined(POLARSSL_SHA1_C)
1030  int ret;
1031  int flags;
1032  x509_crt cacert;
1033  x509_crt clicert;
1034 
1035  if( verbose != 0 )
1036  polarssl_printf( " X.509 certificate load: " );
1037 
1038  x509_crt_init( &clicert );
1039 
1040  ret = x509_crt_parse( &clicert, (const unsigned char *) test_cli_crt,
1041  strlen( test_cli_crt ) );
1042  if( ret != 0 )
1043  {
1044  if( verbose != 0 )
1045  polarssl_printf( "failed\n" );
1046 
1047  return( ret );
1048  }
1049 
1050  x509_crt_init( &cacert );
1051 
1052  ret = x509_crt_parse( &cacert, (const unsigned char *) test_ca_crt,
1053  strlen( test_ca_crt ) );
1054  if( ret != 0 )
1055  {
1056  if( verbose != 0 )
1057  polarssl_printf( "failed\n" );
1058 
1059  return( ret );
1060  }
1061 
1062  if( verbose != 0 )
1063  polarssl_printf( "passed\n X.509 signature verify: ");
1064 
1065  ret = x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL );
1066  if( ret != 0 )
1067  {
1068  if( verbose != 0 )
1069  polarssl_printf( "failed\n" );
1070 
1071  polarssl_printf( "ret = %d, &flags = %04x\n", ret, flags );
1072 
1073  return( ret );
1074  }
1075 
1076  if( verbose != 0 )
1077  polarssl_printf( "passed\n\n");
1078 
1079  x509_crt_free( &cacert );
1080  x509_crt_free( &clicert );
1081 
1082  return( 0 );
1083 #else
1084  ((void) verbose);
1086 #endif /* POLARSSL_CERTS_C && POLARSSL_SHA1_C */
1087 }
1088 
1089 #endif /* POLARSSL_SELF_TEST */
1090 
1091 #endif /* POLARSSL_X509_USE_C */
int x509_time_expired(const x509_time *time)
Check a given x509_time against the system time and check if it is not expired.
#define ASN1_NULL
Definition: asn1.h:79
#define ASN1_PRINTABLE_STRING
Definition: asn1.h:84
#define ASN1_UTC_TIME
Definition: asn1.h:87
#define polarssl_printf
#define ASN1_OID
Definition: asn1.h:80
#define ASN1_GENERALIZED_TIME
Definition: asn1.h:88
#define X509_MAX_DN_NAME_SIZE
Maximum value size of a DN entry.
Definition: x509.h:146
int sec
Time.
Definition: x509.h:186
int x509_get_name(unsigned char **p, const unsigned char *end, x509_name *cur)
#define POLARSSL_ERR_X509_INVALID_DATE
The date tag or value is invalid.
Definition: x509.h:59
int x509_get_serial(unsigned char **p, const unsigned char *end, x509_buf *serial)
#define POLARSSL_ERR_ASN1_LENGTH_MISMATCH
Actual length differs from expected length.
Definition: asn1.h:57
int oid_get_numeric_string(char *buf, size_t size, const asn1_buf *oid)
Translate an ASN.1 OID into its numeric representation (e.g.
#define polarssl_malloc
#define polarssl_free
int x509_get_sig_alg(const x509_buf *sig_oid, const x509_buf *sig_params, md_type_t *md_alg, pk_type_t *pk_alg, void **sig_opts)
Options for RSASSA-PSS signature verification.
Definition: pk.h:109
int x509_key_size_helper(char *buf, size_t size, const char *name)
int asn1_get_int(unsigned char **p, const unsigned char *end, int *val)
Retrieve an integer ASN.1 tag and its value.
const char * x509_oid_get_description(x509_buf *oid)
Give an known OID, return its descriptive string.
int x509_get_alg_null(unsigned char **p, const unsigned char *end, x509_buf *alg)
Container for date and time (precision in seconds).
Definition: x509.h:183
int x509_crt_parse(x509_crt *chain, const unsigned char *buf, size_t buflen)
Parse one or more certificates and add them to the chained list.
#define ASN1_SEQUENCE
Definition: asn1.h:82
void x509_crt_free(x509_crt *crt)
Unallocate all certificate data.
Configuration options (set of defines)
#define POLARSSL_ERR_X509_UNKNOWN_SIG_ALG
Signature algorithm (oid) is unsupported.
Definition: x509.h:63
#define OID_CMP(oid_str, oid_buf)
Compares an asn1_buf structure to a reference OID.
Definition: asn1.h:108
int oid_get_md_alg(const asn1_buf *oid, md_type_t *md_alg)
Translate hash algorithm OID into md_type.
#define ASN1_CONSTRUCTED
Definition: asn1.h:92
PolarSSL Platform abstraction layer.
#define POLARSSL_ERR_X509_INVALID_SIGNATURE
The signature tag or value invalid.
Definition: x509.h:60
int x509_get_sig(unsigned char **p, const unsigned char *end, x509_buf *sig)
int expected_salt_len
Definition: pk.h:112
Object Identifier (OID) database.
int x509_get_alg(unsigned char **p, const unsigned char *end, x509_buf *alg, x509_buf *params)
md_type_t
Definition: md.h:51
#define ASN1_SET
Definition: asn1.h:83
asn1_buf val
The named value.
Definition: asn1.h:159
int hour
Definition: x509.h:186
#define ASN1_PRIMITIVE
Definition: asn1.h:91
int mon
Definition: x509.h:185
const md_info_t * md_info_from_type(md_type_t md_type)
Returns the message digest information associated with the given digest type.
const char * test_ca_crt
int x509_get_time(unsigned char **p, const unsigned char *end, x509_time *time)
md_type_t mgf1_hash_id
Definition: pk.h:111
Generic ASN.1 parsing.
Container for an X.509 certificate.
Definition: x509_crt.h:57
#define ASN1_BMP_STRING
Definition: asn1.h:90
#define POLARSSL_ERR_OID_NOT_FOUND
OID is not found.
Definition: oid.h:50
Privacy Enhanced Mail (PEM) decoding.
int x509_dn_gets(char *buf, size_t size, const x509_name *dn)
Store the certificate DN in printable form into buf; no more than size characters will be written...
asn1_buf oid
The object identifier.
Definition: asn1.h:158
int asn1_get_alg_null(unsigned char **p, const unsigned char *end, asn1_buf *alg)
Retrieve an AlgorithmIdentifier ASN.1 sequence with NULL or no params.
int asn1_get_alg(unsigned char **p, const unsigned char *end, asn1_buf *alg, asn1_buf *params)
Retrieve an AlgorithmIdentifier ASN.1 sequence.
void x509_crt_init(x509_crt *crt)
Initialize a certificate (chain)
#define ASN1_INTEGER
Definition: asn1.h:76
unsigned char * p
ASN1 data, e.g.
Definition: asn1.h:128
int oid_get_sig_alg_desc(const asn1_buf *oid, const char **desc)
Translate SignatureAlgorithm OID into description.
int x509_crt_verify(x509_crt *crt, x509_crt *trust_ca, x509_crl *ca_crl, const char *cn, int *flags, int(*f_vrfy)(void *, x509_crt *, int, int *), void *p_vrfy)
Verify the certificate signature.
int x509_oid_get_numeric_string(char *buf, size_t size, x509_buf *oid)
Give an OID, return a string version of its OID number.
X.509 certificate parsing and writing.
int day
Date.
Definition: x509.h:185
pk_type_t
Public key types.
Definition: pk.h:95
#define POLARSSL_ERR_X509_INVALID_ALG
The algorithm tag or value is invalid.
Definition: x509.h:57
int tag
ASN1 type, e.g.
Definition: asn1.h:126
#define POLARSSL_ERR_ASN1_OUT_OF_DATA
Out of data when parsing an ASN1 data structure.
Definition: asn1.h:54
int x509_sig_alg_gets(char *buf, size_t size, const x509_buf *sig_oid, pk_type_t pk_alg, md_type_t md_alg, const void *sig_opts)
X.509 generic defines and structures.
int x509_load_file(const char *path, unsigned char **buf, size_t *n)
int x509_get_rsassa_pss_params(const x509_buf *params, md_type_t *md_alg, md_type_t *mgf_md, int *salt_len)
#define ASN1_CONTEXT_SPECIFIC
Definition: asn1.h:93
#define POLARSSL_ERR_X509_FILE_IO_ERROR
Read/write of file failed.
Definition: x509.h:69
const char * test_cli_crt
Container for a sequence or list of &#39;named&#39; ASN.1 data items.
Definition: asn1.h:156
Type-length-value structure that allows for ASN1 using DER.
Definition: asn1.h:124
#define ASN1_UNIVERSAL_STRING
Definition: asn1.h:89
int asn1_get_bitstring_null(unsigned char **p, const unsigned char *end, size_t *len)
Retrieve a bitstring ASN.1 tag without unused bits and its value.
size_t len
ASN1 length, e.g.
Definition: asn1.h:127
#define POLARSSL_ERR_X509_INVALID_NAME
The name tag or value is invalid.
Definition: x509.h:58
Sample certificates and DHM parameters for testing.
#define ASN1_IA5_STRING
Definition: asn1.h:86
const char * name
Name of the message digest.
Definition: md.h:79
int year
Definition: x509.h:185
#define ASN1_UTF8_STRING
Definition: asn1.h:81
int asn1_get_len(unsigned char **p, const unsigned char *end, size_t *len)
Get the length of an ASN.1 element.
#define POLARSSL_ERR_X509_FEATURE_UNAVAILABLE
Unavailable feature, e.g.
Definition: x509.h:52
int asn1_get_tag(unsigned char **p, const unsigned char *end, size_t *len, int tag)
Get the tag and length of the tag.
int x509_get_ext(unsigned char **p, const unsigned char *end, x509_buf *ext, int tag)
int min
Definition: x509.h:186
struct _asn1_named_data * next
The next entry in the sequence.
Definition: asn1.h:160
#define POLARSSL_ERR_X509_INVALID_EXTENSIONS
The extension tag or value is invalid.
Definition: x509.h:61
int x509_time_future(const x509_time *time)
Check a given x509_time against the system time and check if it is not from the future.
#define POLARSSL_ERR_X509_BAD_INPUT_DATA
Input invalid.
Definition: x509.h:67
int oid_get_sig_alg(const asn1_buf *oid, md_type_t *md_alg, pk_type_t *pk_alg)
Translate SignatureAlgorithm OID into md_type and pk_type.
int x509_self_test(int verbose)
Checkup routine.
#define ASN1_T61_STRING
Definition: asn1.h:85
#define POLARSSL_ERR_X509_MALLOC_FAILED
Allocation of memory failed.
Definition: x509.h:68
int oid_get_attr_short_name(const asn1_buf *oid, const char **short_name)
Translate an X.509 attribute type OID into the short name (e.g.
#define POLARSSL_ERR_X509_INVALID_SERIAL
The serial tag or value is invalid.
Definition: x509.h:56
Message digest information.
Definition: md.h:74
int oid_get_extended_key_usage(const asn1_buf *oid, const char **desc)
Translate Extended Key Usage OID into description.
#define POLARSSL_ERR_ASN1_UNEXPECTED_TAG
ASN1 tag was of an unexpected value.
Definition: asn1.h:55
int x509_serial_gets(char *buf, size_t size, const x509_buf *serial)
Store the certificate serial in printable form into buf; no more than size characters will be written...
#define OID_MGF1
id-mgf1 ::= { pkcs-1 8 }
Definition: oid.h:212