PolarSSL v1.3.8
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 int x509_get_name( unsigned char **p, const unsigned char *end,
414  x509_name *cur )
415 {
416  int ret;
417  size_t len;
418  const unsigned char *end2;
419  x509_name *use;
420 
421  if( ( ret = asn1_get_tag( p, end, &len,
422  ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
423  return( POLARSSL_ERR_X509_INVALID_NAME + ret );
424 
425  end2 = end;
426  end = *p + len;
427  use = cur;
428 
429  do
430  {
431  if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
432  return( ret );
433 
434  if( *p != end )
435  {
436  use->next = (x509_name *) polarssl_malloc(
437  sizeof( x509_name ) );
438 
439  if( use->next == NULL )
441 
442  memset( use->next, 0, sizeof( x509_name ) );
443 
444  use = use->next;
445  }
446  }
447  while( *p != end );
448 
449  /*
450  * recurse until end of SEQUENCE is reached
451  */
452  if( *p == end2 )
453  return( 0 );
454 
455  cur->next = (x509_name *) polarssl_malloc(
456  sizeof( x509_name ) );
457 
458  if( cur->next == NULL )
460 
461  memset( cur->next, 0, sizeof( x509_name ) );
462 
463  return( x509_get_name( p, end2, cur->next ) );
464 }
465 
466 /*
467  * Time ::= CHOICE {
468  * utcTime UTCTime,
469  * generalTime GeneralizedTime }
470  */
471 int x509_get_time( unsigned char **p, const unsigned char *end,
472  x509_time *time )
473 {
474  int ret;
475  size_t len;
476  char date[64];
477  unsigned char tag;
478 
479  if( ( end - *p ) < 1 )
482 
483  tag = **p;
484 
485  if( tag == ASN1_UTC_TIME )
486  {
487  (*p)++;
488  ret = asn1_get_len( p, end, &len );
489 
490  if( ret != 0 )
491  return( POLARSSL_ERR_X509_INVALID_DATE + ret );
492 
493  memset( date, 0, sizeof( date ) );
494  memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
495  len : sizeof( date ) - 1 );
496 
497  if( sscanf( date, "%2d%2d%2d%2d%2d%2dZ",
498  &time->year, &time->mon, &time->day,
499  &time->hour, &time->min, &time->sec ) < 5 )
501 
502  time->year += 100 * ( time->year < 50 );
503  time->year += 1900;
504 
505  *p += len;
506 
507  return( 0 );
508  }
509  else if( tag == ASN1_GENERALIZED_TIME )
510  {
511  (*p)++;
512  ret = asn1_get_len( p, end, &len );
513 
514  if( ret != 0 )
515  return( POLARSSL_ERR_X509_INVALID_DATE + ret );
516 
517  memset( date, 0, sizeof( date ) );
518  memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
519  len : sizeof( date ) - 1 );
520 
521  if( sscanf( date, "%4d%2d%2d%2d%2d%2dZ",
522  &time->year, &time->mon, &time->day,
523  &time->hour, &time->min, &time->sec ) < 5 )
525 
526  *p += len;
527 
528  return( 0 );
529  }
530  else
533 }
534 
535 int x509_get_sig( unsigned char **p, const unsigned char *end, x509_buf *sig )
536 {
537  int ret;
538  size_t len;
539 
540  if( ( end - *p ) < 1 )
543 
544  sig->tag = **p;
545 
546  if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 )
547  return( POLARSSL_ERR_X509_INVALID_SIGNATURE + ret );
548 
549  sig->len = len;
550  sig->p = *p;
551 
552  *p += len;
553 
554  return( 0 );
555 }
556 
557 /*
558  * Get signature algorithm from alg OID and optional parameters
559  */
560 int x509_get_sig_alg( const x509_buf *sig_oid, const x509_buf *sig_params,
561  md_type_t *md_alg, pk_type_t *pk_alg,
562  void **sig_opts )
563 {
564  int ret;
565 
566  if( *sig_opts != NULL )
568 
569  if( ( ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 )
570  return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG + ret );
571 
572 #if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
573  if( *pk_alg == POLARSSL_PK_RSASSA_PSS )
574  {
575  pk_rsassa_pss_options *pss_opts;
576 
577  pss_opts = polarssl_malloc( sizeof( pk_rsassa_pss_options ) );
578  if( pss_opts == NULL )
580 
581  ret = x509_get_rsassa_pss_params( sig_params,
582  md_alg,
583  &pss_opts->mgf1_hash_id,
584  &pss_opts->expected_salt_len );
585  if( ret != 0 )
586  {
587  polarssl_free( pss_opts );
588  return( ret );
589  }
590 
591  *sig_opts = (void *) pss_opts;
592  }
593  else
594 #endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */
595  {
596  /* Make sure parameters are absent or NULL */
597  if( ( sig_params->tag != ASN1_NULL && sig_params->tag != 0 ) ||
598  sig_params->len != 0 )
600  }
601 
602  return( 0 );
603 }
604 
605 /*
606  * X.509 Extensions (No parsing of extensions, pointer should
607  * be either manually updated or extensions should be parsed!
608  */
609 int x509_get_ext( unsigned char **p, const unsigned char *end,
610  x509_buf *ext, int tag )
611 {
612  int ret;
613  size_t len;
614 
615  if( *p == end )
616  return( 0 );
617 
618  ext->tag = **p;
619 
620  if( ( ret = asn1_get_tag( p, end, &ext->len,
621  ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
622  return( ret );
623 
624  ext->p = *p;
625  end = *p + ext->len;
626 
627  /*
628  * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
629  *
630  * Extension ::= SEQUENCE {
631  * extnID OBJECT IDENTIFIER,
632  * critical BOOLEAN DEFAULT FALSE,
633  * extnValue OCTET STRING }
634  */
635  if( ( ret = asn1_get_tag( p, end, &len,
636  ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
637  return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
638 
639  if( end != *p + len )
642 
643  return( 0 );
644 }
645 
646 #if defined(POLARSSL_FS_IO)
647 /*
648  * Load all data from a file into a given buffer.
649  */
650 int x509_load_file( const char *path, unsigned char **buf, size_t *n )
651 {
652  FILE *f;
653  long size;
654 
655  if( ( f = fopen( path, "rb" ) ) == NULL )
657 
658  fseek( f, 0, SEEK_END );
659  if( ( size = ftell( f ) ) == -1 )
660  {
661  fclose( f );
663  }
664  fseek( f, 0, SEEK_SET );
665 
666  *n = (size_t) size;
667 
668  if( *n + 1 == 0 ||
669  ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
670  {
671  fclose( f );
673  }
674 
675  if( fread( *buf, 1, *n, f ) != *n )
676  {
677  fclose( f );
678  polarssl_free( *buf );
680  }
681 
682  fclose( f );
683 
684  (*buf)[*n] = '\0';
685 
686  return( 0 );
687 }
688 #endif /* POLARSSL_FS_IO */
689 
690 #if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \
691  !defined(EFI32)
692 #include <stdarg.h>
693 
694 #if !defined vsnprintf
695 #define vsnprintf _vsnprintf
696 #endif // vsnprintf
697 
698 /*
699  * Windows _snprintf and _vsnprintf are not compatible to linux versions.
700  * Result value is not size of buffer needed, but -1 if no fit is possible.
701  *
702  * This fuction tries to 'fix' this by at least suggesting enlarging the
703  * size by 20.
704  */
705 static int compat_snprintf( char *str, size_t size, const char *format, ... )
706 {
707  va_list ap;
708  int res = -1;
709 
710  va_start( ap, format );
711 
712  res = vsnprintf( str, size, format, ap );
713 
714  va_end( ap );
715 
716  // No quick fix possible
717  if( res < 0 )
718  return( (int) size + 20 );
719 
720  return( res );
721 }
722 
723 #define snprintf compat_snprintf
724 #endif /* _MSC_VER && !snprintf && !EFIX64 && !EFI32 */
725 
726 #define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
727 
728 #define SAFE_SNPRINTF() \
729 { \
730  if( ret == -1 ) \
731  return( -1 ); \
732  \
733  if( (unsigned int) ret > n ) { \
734  p[n - 1] = '\0'; \
735  return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); \
736  } \
737  \
738  n -= (unsigned int) ret; \
739  p += (unsigned int) ret; \
740 }
741 
742 /*
743  * Store the name in printable form into buf; no more
744  * than size characters will be written
745  */
746 int x509_dn_gets( char *buf, size_t size, const x509_name *dn )
747 {
748  int ret;
749  size_t i, n;
750  unsigned char c;
751  const x509_name *name;
752  const char *short_name = NULL;
753  char s[128], *p;
754 
755  memset( s, 0, sizeof( s ) );
756 
757  name = dn;
758  p = buf;
759  n = size;
760 
761  while( name != NULL )
762  {
763  if( !name->oid.p )
764  {
765  name = name->next;
766  continue;
767  }
768 
769  if( name != dn )
770  {
771  ret = snprintf( p, n, ", " );
772  SAFE_SNPRINTF();
773  }
774 
775  ret = oid_get_attr_short_name( &name->oid, &short_name );
776 
777  if( ret == 0 )
778  ret = snprintf( p, n, "%s=", short_name );
779  else
780  ret = snprintf( p, n, "\?\?=" );
781  SAFE_SNPRINTF();
782 
783  for( i = 0; i < name->val.len; i++ )
784  {
785  if( i >= sizeof( s ) - 1 )
786  break;
787 
788  c = name->val.p[i];
789  if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
790  s[i] = '?';
791  else s[i] = c;
792  }
793  s[i] = '\0';
794  ret = snprintf( p, n, "%s", s );
795  SAFE_SNPRINTF();
796  name = name->next;
797  }
798 
799  return( (int) ( size - n ) );
800 }
801 
802 /*
803  * Store the serial in printable form into buf; no more
804  * than size characters will be written
805  */
806 int x509_serial_gets( char *buf, size_t size, const x509_buf *serial )
807 {
808  int ret;
809  size_t i, n, nr;
810  char *p;
811 
812  p = buf;
813  n = size;
814 
815  nr = ( serial->len <= 32 )
816  ? serial->len : 28;
817 
818  for( i = 0; i < nr; i++ )
819  {
820  if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
821  continue;
822 
823  ret = snprintf( p, n, "%02X%s",
824  serial->p[i], ( i < nr - 1 ) ? ":" : "" );
825  SAFE_SNPRINTF();
826  }
827 
828  if( nr != serial->len )
829  {
830  ret = snprintf( p, n, "...." );
831  SAFE_SNPRINTF();
832  }
833 
834  return( (int) ( size - n ) );
835 }
836 
837 /*
838  * Helper for writing signature algorithms
839  */
840 int x509_sig_alg_gets( char *buf, size_t size, const x509_buf *sig_oid,
841  pk_type_t pk_alg, md_type_t md_alg,
842  const void *sig_opts )
843 {
844  int ret;
845  char *p = buf;
846  size_t n = size;
847  const char *desc = NULL;
848 
849  ret = oid_get_sig_alg_desc( sig_oid, &desc );
850  if( ret != 0 )
851  ret = snprintf( p, n, "???" );
852  else
853  ret = snprintf( p, n, "%s", desc );
854  SAFE_SNPRINTF();
855 
856 #if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
857  if( pk_alg == POLARSSL_PK_RSASSA_PSS )
858  {
859  const pk_rsassa_pss_options *pss_opts;
860  const md_info_t *md_info, *mgf_md_info;
861 
862  pss_opts = (const pk_rsassa_pss_options *) sig_opts;
863 
864  md_info = md_info_from_type( md_alg );
865  mgf_md_info = md_info_from_type( pss_opts->mgf1_hash_id );
866 
867  ret = snprintf( p, n, " (%s, MGF1-%s, 0x%02X)",
868  md_info ? md_info->name : "???",
869  mgf_md_info ? mgf_md_info->name : "???",
870  pss_opts->expected_salt_len );
871  SAFE_SNPRINTF();
872  }
873 #else
874  ((void) pk_alg);
875  ((void) md_alg);
876  ((void) sig_opts);
877 #endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */
878 
879  return( (int) size - n );
880 }
881 
882 /*
883  * Helper for writing "RSA key size", "EC key size", etc
884  */
885 int x509_key_size_helper( char *buf, size_t size, const char *name )
886 {
887  char *p = buf;
888  size_t n = size;
889  int ret;
890 
891  if( strlen( name ) + sizeof( " key size" ) > size )
892  return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL );
893 
894  ret = snprintf( p, n, "%s key size", name );
895  SAFE_SNPRINTF();
896 
897  return( 0 );
898 }
899 
900 /*
901  * Return an informational string describing the given OID
902  */
903 const char *x509_oid_get_description( x509_buf *oid )
904 {
905  const char *desc = NULL;
906  int ret;
907 
908  ret = oid_get_extended_key_usage( oid, &desc );
909 
910  if( ret != 0 )
911  return( NULL );
912 
913  return( desc );
914 }
915 
916 /* Return the x.y.z.... style numeric string for the given OID */
917 int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
918 {
919  return oid_get_numeric_string( buf, size, oid );
920 }
921 
922 /*
923  * Return 0 if the x509_time is still valid, or 1 otherwise.
924  */
925 #if defined(POLARSSL_HAVE_TIME)
926 
927 static void x509_get_current_time( x509_time *now )
928 {
929 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
930  SYSTEMTIME st;
931 
932  GetSystemTime( &st );
933 
934  now->year = st.wYear;
935  now->mon = st.wMonth;
936  now->day = st.wDay;
937  now->hour = st.wHour;
938  now->min = st.wMinute;
939  now->sec = st.wSecond;
940 #else
941  struct tm lt;
942  time_t tt;
943 
944  tt = time( NULL );
945  gmtime_r( &tt, &lt );
946 
947  now->year = lt.tm_year + 1900;
948  now->mon = lt.tm_mon + 1;
949  now->day = lt.tm_mday;
950  now->hour = lt.tm_hour;
951  now->min = lt.tm_min;
952  now->sec = lt.tm_sec;
953 #endif /* _WIN32 && !EFIX64 && !EFI32 */
954 }
955 
956 /*
957  * Return 0 if before <= after, 1 otherwise
958  */
959 static int x509_check_time( const x509_time *before, const x509_time *after )
960 {
961  if( before->year > after->year )
962  return( 1 );
963 
964  if( before->year == after->year &&
965  before->mon > after->mon )
966  return( 1 );
967 
968  if( before->year == after->year &&
969  before->mon == after->mon &&
970  before->day > after->day )
971  return( 1 );
972 
973  if( before->year == after->year &&
974  before->mon == after->mon &&
975  before->day == after->day &&
976  before->hour > after->hour )
977  return( 1 );
978 
979  if( before->year == after->year &&
980  before->mon == after->mon &&
981  before->day == after->day &&
982  before->hour == after->hour &&
983  before->min > after->min )
984  return( 1 );
985 
986  if( before->year == after->year &&
987  before->mon == after->mon &&
988  before->day == after->day &&
989  before->hour == after->hour &&
990  before->min == after->min &&
991  before->sec > after->sec )
992  return( 1 );
993 
994  return( 0 );
995 }
996 
997 int x509_time_expired( const x509_time *to )
998 {
999  x509_time now;
1000 
1001  x509_get_current_time( &now );
1002 
1003  return( x509_check_time( &now, to ) );
1004 }
1005 
1006 int x509_time_future( const x509_time *from )
1007 {
1008  x509_time now;
1009 
1010  x509_get_current_time( &now );
1011 
1012  return( x509_check_time( from, &now ) );
1013 }
1014 
1015 #else /* POLARSSL_HAVE_TIME */
1016 
1017 int x509_time_expired( const x509_time *to )
1018 {
1019  ((void) to);
1020  return( 0 );
1021 }
1022 
1023 int x509_time_future( const x509_time *from )
1024 {
1025  ((void) from);
1026  return( 0 );
1027 }
1028 #endif /* POLARSSL_HAVE_TIME */
1029 
1030 #if defined(POLARSSL_SELF_TEST)
1031 
1032 #include "polarssl/x509_crt.h"
1033 #include "polarssl/certs.h"
1034 
1035 /*
1036  * Checkup routine
1037  */
1038 int x509_self_test( int verbose )
1039 {
1040 #if defined(POLARSSL_CERTS_C) && defined(POLARSSL_SHA1_C)
1041  int ret;
1042  int flags;
1043  x509_crt cacert;
1044  x509_crt clicert;
1045 
1046  if( verbose != 0 )
1047  polarssl_printf( " X.509 certificate load: " );
1048 
1049  x509_crt_init( &clicert );
1050 
1051  ret = x509_crt_parse( &clicert, (const unsigned char *) test_cli_crt,
1052  strlen( test_cli_crt ) );
1053  if( ret != 0 )
1054  {
1055  if( verbose != 0 )
1056  polarssl_printf( "failed\n" );
1057 
1058  return( ret );
1059  }
1060 
1061  x509_crt_init( &cacert );
1062 
1063  ret = x509_crt_parse( &cacert, (const unsigned char *) test_ca_crt,
1064  strlen( test_ca_crt ) );
1065  if( ret != 0 )
1066  {
1067  if( verbose != 0 )
1068  polarssl_printf( "failed\n" );
1069 
1070  return( ret );
1071  }
1072 
1073  if( verbose != 0 )
1074  polarssl_printf( "passed\n X.509 signature verify: ");
1075 
1076  ret = x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL );
1077  if( ret != 0 )
1078  {
1079  if( verbose != 0 )
1080  polarssl_printf( "failed\n" );
1081 
1082  polarssl_printf( "ret = %d, &flags = %04x\n", ret, flags );
1083 
1084  return( ret );
1085  }
1086 
1087  if( verbose != 0 )
1088  polarssl_printf( "passed\n\n");
1089 
1090  x509_crt_free( &cacert );
1091  x509_crt_free( &clicert );
1092 
1093  return( 0 );
1094 #else
1095  ((void) verbose);
1097 #endif /* POLARSSL_CERTS_C && POLARSSL_SHA1_C */
1098 }
1099 
1100 #endif /* POLARSSL_SELF_TEST */
1101 
1102 #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
int sec
Time.
Definition: x509.h:184
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:181
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:184
#define ASN1_PRIMITIVE
Definition: asn1.h:91
int mon
Definition: x509.h:183
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:183
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:183
#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:184
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