PolarSSL v1.3.1
x509_crt.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_CRT_PARSE_C)
40 
41 #include "polarssl/x509_crt.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 #if !defined(_WIN32)
65 #include <sys/types.h>
66 #include <sys/stat.h>
67 #include <dirent.h>
68 #endif
69 #endif
70 
71 /*
72  * Version ::= INTEGER { v1(0), v2(1), v3(2) }
73  */
74 static int x509_get_version( unsigned char **p,
75  const unsigned char *end,
76  int *ver )
77 {
78  int ret;
79  size_t len;
80 
81  if( ( ret = asn1_get_tag( p, end, &len,
83  {
85  {
86  *ver = 0;
87  return( 0 );
88  }
89 
90  return( ret );
91  }
92 
93  end = *p + len;
94 
95  if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
96  return( POLARSSL_ERR_X509_INVALID_VERSION + ret );
97 
98  if( *p != end )
101 
102  return( 0 );
103 }
104 
105 /*
106  * Validity ::= SEQUENCE {
107  * notBefore Time,
108  * notAfter Time }
109  */
110 static int x509_get_dates( unsigned char **p,
111  const unsigned char *end,
112  x509_time *from,
113  x509_time *to )
114 {
115  int ret;
116  size_t len;
117 
118  if( ( ret = asn1_get_tag( p, end, &len,
119  ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
120  return( POLARSSL_ERR_X509_INVALID_DATE + ret );
121 
122  end = *p + len;
123 
124  if( ( ret = x509_get_time( p, end, from ) ) != 0 )
125  return( ret );
126 
127  if( ( ret = x509_get_time( p, end, to ) ) != 0 )
128  return( ret );
129 
130  if( *p != end )
133 
134  return( 0 );
135 }
136 
137 /*
138  * X.509 v2/v3 unique identifier (not parsed)
139  */
140 static int x509_get_uid( unsigned char **p,
141  const unsigned char *end,
142  x509_buf *uid, int n )
143 {
144  int ret;
145 
146  if( *p == end )
147  return( 0 );
148 
149  uid->tag = **p;
150 
151  if( ( ret = asn1_get_tag( p, end, &uid->len,
152  ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
153  {
155  return( 0 );
156 
157  return( ret );
158  }
159 
160  uid->p = *p;
161  *p += uid->len;
162 
163  return( 0 );
164 }
165 
166 static int x509_get_basic_constraints( unsigned char **p,
167  const unsigned char *end,
168  int *ca_istrue,
169  int *max_pathlen )
170 {
171  int ret;
172  size_t len;
173 
174  /*
175  * BasicConstraints ::= SEQUENCE {
176  * cA BOOLEAN DEFAULT FALSE,
177  * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
178  */
179  *ca_istrue = 0; /* DEFAULT FALSE */
180  *max_pathlen = 0; /* endless */
181 
182  if( ( ret = asn1_get_tag( p, end, &len,
183  ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
184  return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
185 
186  if( *p == end )
187  return 0;
188 
189  if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
190  {
192  ret = asn1_get_int( p, end, ca_istrue );
193 
194  if( ret != 0 )
195  return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
196 
197  if( *ca_istrue != 0 )
198  *ca_istrue = 1;
199  }
200 
201  if( *p == end )
202  return 0;
203 
204  if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
205  return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
206 
207  if( *p != end )
210 
211  (*max_pathlen)++;
212 
213  return 0;
214 }
215 
216 static int x509_get_ns_cert_type( unsigned char **p,
217  const unsigned char *end,
218  unsigned char *ns_cert_type)
219 {
220  int ret;
221  x509_bitstring bs = { 0, 0, NULL };
222 
223  if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
224  return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
225 
226  if( bs.len != 1 )
229 
230  /* Get actual bitstring */
231  *ns_cert_type = *bs.p;
232  return 0;
233 }
234 
235 static int x509_get_key_usage( unsigned char **p,
236  const unsigned char *end,
237  unsigned char *key_usage)
238 {
239  int ret;
240  x509_bitstring bs = { 0, 0, NULL };
241 
242  if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
243  return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
244 
245  if( bs.len < 1 )
248 
249  /* Get actual bitstring */
250  *key_usage = *bs.p;
251  return 0;
252 }
253 
254 /*
255  * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
256  *
257  * KeyPurposeId ::= OBJECT IDENTIFIER
258  */
259 static int x509_get_ext_key_usage( unsigned char **p,
260  const unsigned char *end,
261  x509_sequence *ext_key_usage)
262 {
263  int ret;
264 
265  if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
266  return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
267 
268  /* Sequence length must be >= 1 */
269  if( ext_key_usage->buf.p == NULL )
272 
273  return 0;
274 }
275 
276 /*
277  * SubjectAltName ::= GeneralNames
278  *
279  * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
280  *
281  * GeneralName ::= CHOICE {
282  * otherName [0] OtherName,
283  * rfc822Name [1] IA5String,
284  * dNSName [2] IA5String,
285  * x400Address [3] ORAddress,
286  * directoryName [4] Name,
287  * ediPartyName [5] EDIPartyName,
288  * uniformResourceIdentifier [6] IA5String,
289  * iPAddress [7] OCTET STRING,
290  * registeredID [8] OBJECT IDENTIFIER }
291  *
292  * OtherName ::= SEQUENCE {
293  * type-id OBJECT IDENTIFIER,
294  * value [0] EXPLICIT ANY DEFINED BY type-id }
295  *
296  * EDIPartyName ::= SEQUENCE {
297  * nameAssigner [0] DirectoryString OPTIONAL,
298  * partyName [1] DirectoryString }
299  *
300  * NOTE: PolarSSL only parses and uses dNSName at this point.
301  */
302 static int x509_get_subject_alt_name( unsigned char **p,
303  const unsigned char *end,
304  x509_sequence *subject_alt_name )
305 {
306  int ret;
307  size_t len, tag_len;
308  asn1_buf *buf;
309  unsigned char tag;
310  asn1_sequence *cur = subject_alt_name;
311 
312  /* Get main sequence tag */
313  if( ( ret = asn1_get_tag( p, end, &len,
314  ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
315  return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
316 
317  if( *p + len != end )
320 
321  while( *p < end )
322  {
323  if( ( end - *p ) < 1 )
326 
327  tag = **p;
328  (*p)++;
329  if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 )
330  return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
331 
332  if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC )
335 
336  if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) )
337  {
338  *p += tag_len;
339  continue;
340  }
341 
342  buf = &(cur->buf);
343  buf->tag = tag;
344  buf->p = *p;
345  buf->len = tag_len;
346  *p += buf->len;
347 
348  /* Allocate and assign next pointer */
349  if (*p < end)
350  {
352  sizeof( asn1_sequence ) );
353 
354  if( cur->next == NULL )
357 
358  memset( cur->next, 0, sizeof( asn1_sequence ) );
359  cur = cur->next;
360  }
361  }
362 
363  /* Set final sequence entry's next pointer to NULL */
364  cur->next = NULL;
365 
366  if( *p != end )
369 
370  return( 0 );
371 }
372 
373 /*
374  * X.509 v3 extensions
375  *
376  * TODO: Perform all of the basic constraints tests required by the RFC
377  * TODO: Set values for undetected extensions to a sane default?
378  *
379  */
380 static int x509_get_crt_ext( unsigned char **p,
381  const unsigned char *end,
382  x509_crt *crt )
383 {
384  int ret;
385  size_t len;
386  unsigned char *end_ext_data, *end_ext_octet;
387 
388  if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
389  {
391  return( 0 );
392 
393  return( ret );
394  }
395 
396  while( *p < end )
397  {
398  /*
399  * Extension ::= SEQUENCE {
400  * extnID OBJECT IDENTIFIER,
401  * critical BOOLEAN DEFAULT FALSE,
402  * extnValue OCTET STRING }
403  */
404  x509_buf extn_oid = {0, 0, NULL};
405  int is_critical = 0; /* DEFAULT FALSE */
406  int ext_type = 0;
407 
408  if( ( ret = asn1_get_tag( p, end, &len,
409  ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
410  return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
411 
412  end_ext_data = *p + len;
413 
414  /* Get extension ID */
415  extn_oid.tag = **p;
416 
417  if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
418  return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
419 
420  extn_oid.p = *p;
421  *p += extn_oid.len;
422 
423  if( ( end - *p ) < 1 )
426 
427  /* Get optional critical */
428  if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
430  return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
431 
432  /* Data should be octet string type */
433  if( ( ret = asn1_get_tag( p, end_ext_data, &len,
434  ASN1_OCTET_STRING ) ) != 0 )
435  return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
436 
437  end_ext_octet = *p + len;
438 
439  if( end_ext_octet != end_ext_data )
442 
443  /*
444  * Detect supported extensions
445  */
446  ret = oid_get_x509_ext_type( &extn_oid, &ext_type );
447 
448  if( ret != 0 )
449  {
450  /* No parser found, skip extension */
451  *p = end_ext_octet;
452 
453 #if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
454  if( is_critical )
455  {
456  /* Data is marked as critical: fail */
459  }
460 #endif
461  continue;
462  }
463 
464  crt->ext_types |= ext_type;
465 
466  switch( ext_type )
467  {
469  /* Parse basic constraints */
470  if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
471  &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
472  return ( ret );
473  break;
474 
475  case EXT_KEY_USAGE:
476  /* Parse key usage */
477  if( ( ret = x509_get_key_usage( p, end_ext_octet,
478  &crt->key_usage ) ) != 0 )
479  return ( ret );
480  break;
481 
483  /* Parse extended key usage */
484  if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
485  &crt->ext_key_usage ) ) != 0 )
486  return ( ret );
487  break;
488 
490  /* Parse subject alt name */
491  if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
492  &crt->subject_alt_names ) ) != 0 )
493  return ( ret );
494  break;
495 
496  case EXT_NS_CERT_TYPE:
497  /* Parse netscape certificate type */
498  if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
499  &crt->ns_cert_type ) ) != 0 )
500  return ( ret );
501  break;
502 
503  default:
505  }
506  }
507 
508  if( *p != end )
511 
512  return( 0 );
513 }
514 
515 /*
516  * Parse and fill a single X.509 certificate in DER format
517  */
518 static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf,
519  size_t buflen )
520 {
521  int ret;
522  size_t len;
523  unsigned char *p, *end, *crt_end;
524 
525  /*
526  * Check for valid input
527  */
528  if( crt == NULL || buf == NULL )
530 
531  p = (unsigned char *) polarssl_malloc( len = buflen );
532 
533  if( p == NULL )
535 
536  memcpy( p, buf, buflen );
537 
538  buflen = 0;
539 
540  crt->raw.p = p;
541  crt->raw.len = len;
542  end = p + len;
543 
544  /*
545  * Certificate ::= SEQUENCE {
546  * tbsCertificate TBSCertificate,
547  * signatureAlgorithm AlgorithmIdentifier,
548  * signatureValue BIT STRING }
549  */
550  if( ( ret = asn1_get_tag( &p, end, &len,
551  ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
552  {
553  x509_crt_free( crt );
555  }
556 
557  if( len > (size_t) ( end - p ) )
558  {
559  x509_crt_free( crt );
562  }
563  crt_end = p + len;
564 
565  /*
566  * TBSCertificate ::= SEQUENCE {
567  */
568  crt->tbs.p = p;
569 
570  if( ( ret = asn1_get_tag( &p, end, &len,
571  ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
572  {
573  x509_crt_free( crt );
574  return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
575  }
576 
577  end = p + len;
578  crt->tbs.len = end - crt->tbs.p;
579 
580  /*
581  * Version ::= INTEGER { v1(0), v2(1), v3(2) }
582  *
583  * CertificateSerialNumber ::= INTEGER
584  *
585  * signature AlgorithmIdentifier
586  */
587  if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
588  ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
589  ( ret = x509_get_alg_null( &p, end, &crt->sig_oid1 ) ) != 0 )
590  {
591  x509_crt_free( crt );
592  return( ret );
593  }
594 
595  crt->version++;
596 
597  if( crt->version > 3 )
598  {
599  x509_crt_free( crt );
601  }
602 
603  if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_md,
604  &crt->sig_pk ) ) != 0 )
605  {
606  x509_crt_free( crt );
607  return( ret );
608  }
609 
610  /*
611  * issuer Name
612  */
613  crt->issuer_raw.p = p;
614 
615  if( ( ret = asn1_get_tag( &p, end, &len,
616  ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
617  {
618  x509_crt_free( crt );
619  return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
620  }
621 
622  if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
623  {
624  x509_crt_free( crt );
625  return( ret );
626  }
627 
628  crt->issuer_raw.len = p - crt->issuer_raw.p;
629 
630  /*
631  * Validity ::= SEQUENCE {
632  * notBefore Time,
633  * notAfter Time }
634  *
635  */
636  if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
637  &crt->valid_to ) ) != 0 )
638  {
639  x509_crt_free( crt );
640  return( ret );
641  }
642 
643  /*
644  * subject Name
645  */
646  crt->subject_raw.p = p;
647 
648  if( ( ret = asn1_get_tag( &p, end, &len,
649  ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
650  {
651  x509_crt_free( crt );
652  return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
653  }
654 
655  if( len && ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
656  {
657  x509_crt_free( crt );
658  return( ret );
659  }
660 
661  crt->subject_raw.len = p - crt->subject_raw.p;
662 
663  /*
664  * SubjectPublicKeyInfo
665  */
666  if( ( ret = pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 )
667  {
668  x509_crt_free( crt );
669  return( ret );
670  }
671 
672  /*
673  * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
674  * -- If present, version shall be v2 or v3
675  * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
676  * -- If present, version shall be v2 or v3
677  * extensions [3] EXPLICIT Extensions OPTIONAL
678  * -- If present, version shall be v3
679  */
680  if( crt->version == 2 || crt->version == 3 )
681  {
682  ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
683  if( ret != 0 )
684  {
685  x509_crt_free( crt );
686  return( ret );
687  }
688  }
689 
690  if( crt->version == 2 || crt->version == 3 )
691  {
692  ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
693  if( ret != 0 )
694  {
695  x509_crt_free( crt );
696  return( ret );
697  }
698  }
699 
700 #if !defined(POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3)
701  if( crt->version == 3 )
702  {
703 #endif
704  ret = x509_get_crt_ext( &p, end, crt);
705  if( ret != 0 )
706  {
707  x509_crt_free( crt );
708  return( ret );
709  }
710 #if !defined(POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3)
711  }
712 #endif
713 
714  if( p != end )
715  {
716  x509_crt_free( crt );
719  }
720 
721  end = crt_end;
722 
723  /*
724  * }
725  * -- end of TBSCertificate
726  *
727  * signatureAlgorithm AlgorithmIdentifier,
728  * signatureValue BIT STRING
729  */
730  if( ( ret = x509_get_alg_null( &p, end, &crt->sig_oid2 ) ) != 0 )
731  {
732  x509_crt_free( crt );
733  return( ret );
734  }
735 
736  if( crt->sig_oid1.len != crt->sig_oid2.len ||
737  memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
738  {
739  x509_crt_free( crt );
741  }
742 
743  if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
744  {
745  x509_crt_free( crt );
746  return( ret );
747  }
748 
749  if( p != end )
750  {
751  x509_crt_free( crt );
754  }
755 
756  return( 0 );
757 }
758 
759 /*
760  * Parse one X.509 certificate in DER format from a buffer and add them to a
761  * chained list
762  */
763 int x509_crt_parse_der( x509_crt *chain, const unsigned char *buf,
764  size_t buflen )
765 {
766  int ret;
767  x509_crt *crt = chain, *prev = NULL;
768 
769  /*
770  * Check for valid input
771  */
772  if( crt == NULL || buf == NULL )
774 
775  while( crt->version != 0 && crt->next != NULL )
776  {
777  prev = crt;
778  crt = crt->next;
779  }
780 
781  /*
782  * Add new certificate on the end of the chain if needed.
783  */
784  if ( crt->version != 0 && crt->next == NULL)
785  {
786  crt->next = (x509_crt *) polarssl_malloc( sizeof( x509_crt ) );
787 
788  if( crt->next == NULL )
790 
791  prev = crt;
792  crt = crt->next;
793  x509_crt_init( crt );
794  }
795 
796  if( ( ret = x509_crt_parse_der_core( crt, buf, buflen ) ) != 0 )
797  {
798  if( prev )
799  prev->next = NULL;
800 
801  if( crt != chain )
802  polarssl_free( crt );
803 
804  return( ret );
805  }
806 
807  return( 0 );
808 }
809 
810 /*
811  * Parse one or more PEM certificates from a buffer and add them to the chained list
812  */
813 int x509_crt_parse( x509_crt *chain, const unsigned char *buf, size_t buflen )
814 {
815  int success = 0, first_error = 0, total_failed = 0;
816  int buf_format = X509_FORMAT_DER;
817 
818  /*
819  * Check for valid input
820  */
821  if( chain == NULL || buf == NULL )
823 
824  /*
825  * Determine buffer content. Buffer contains either one DER certificate or
826  * one or more PEM certificates.
827  */
828 #if defined(POLARSSL_PEM_PARSE_C)
829  if( strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
830  buf_format = X509_FORMAT_PEM;
831 #endif
832 
833  if( buf_format == X509_FORMAT_DER )
834  return x509_crt_parse_der( chain, buf, buflen );
835 
836 #if defined(POLARSSL_PEM_PARSE_C)
837  if( buf_format == X509_FORMAT_PEM )
838  {
839  int ret;
840  pem_context pem;
841 
842  while( buflen > 0 )
843  {
844  size_t use_len;
845  pem_init( &pem );
846 
847  ret = pem_read_buffer( &pem,
848  "-----BEGIN CERTIFICATE-----",
849  "-----END CERTIFICATE-----",
850  buf, NULL, 0, &use_len );
851 
852  if( ret == 0 )
853  {
854  /*
855  * Was PEM encoded
856  */
857  buflen -= use_len;
858  buf += use_len;
859  }
860  else if( ret == POLARSSL_ERR_PEM_BAD_INPUT_DATA )
861  {
862  return( ret );
863  }
865  {
866  pem_free( &pem );
867 
868  /*
869  * PEM header and footer were found
870  */
871  buflen -= use_len;
872  buf += use_len;
873 
874  if( first_error == 0 )
875  first_error = ret;
876 
877  continue;
878  }
879  else
880  break;
881 
882  ret = x509_crt_parse_der( chain, pem.buf, pem.buflen );
883 
884  pem_free( &pem );
885 
886  if( ret != 0 )
887  {
888  /*
889  * Quit parsing on a memory error
890  */
892  return( ret );
893 
894  if( first_error == 0 )
895  first_error = ret;
896 
897  total_failed++;
898  continue;
899  }
900 
901  success = 1;
902  }
903  }
904 #endif
905 
906  if( success )
907  return( total_failed );
908  else if( first_error )
909  return( first_error );
910  else
912 }
913 
914 #if defined(POLARSSL_FS_IO)
915 /*
916  * Load one or more certificates and add them to the chained list
917  */
918 int x509_crt_parse_file( x509_crt *chain, const char *path )
919 {
920  int ret;
921  size_t n;
922  unsigned char *buf;
923 
924  if ( ( ret = x509_load_file( path, &buf, &n ) ) != 0 )
925  return( ret );
926 
927  ret = x509_crt_parse( chain, buf, n );
928 
929  memset( buf, 0, n + 1 );
930  polarssl_free( buf );
931 
932  return( ret );
933 }
934 
935 int x509_crt_parse_path( x509_crt *chain, const char *path )
936 {
937  int ret = 0;
938 #if defined(_WIN32)
939  int w_ret;
940  WCHAR szDir[MAX_PATH];
941  char filename[MAX_PATH];
942  char *p;
943  int len = (int) strlen( path );
944 
945  WIN32_FIND_DATAW file_data;
946  HANDLE hFind;
947 
948  if( len > MAX_PATH - 3 )
950 
951  memset( szDir, 0, sizeof(szDir) );
952  memset( filename, 0, MAX_PATH );
953  memcpy( filename, path, len );
954  filename[len++] = '\\';
955  p = filename + len;
956  filename[len++] = '*';
957 
958  w_ret = MultiByteToWideChar( CP_ACP, 0, path, len, szDir, MAX_PATH - 3 );
959 
960  hFind = FindFirstFileW( szDir, &file_data );
961  if (hFind == INVALID_HANDLE_VALUE)
963 
964  len = MAX_PATH - len;
965  do
966  {
967  memset( p, 0, len );
968 
969  if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
970  continue;
971 
972  w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
973  lstrlenW(file_data.cFileName),
974  p, len - 1,
975  NULL, NULL );
976 
977  w_ret = x509_crt_parse_file( chain, filename );
978  if( w_ret < 0 )
979  ret++;
980  else
981  ret += w_ret;
982  }
983  while( FindNextFileW( hFind, &file_data ) != 0 );
984 
985  if (GetLastError() != ERROR_NO_MORE_FILES)
987 
988  FindClose( hFind );
989 #else /* _WIN32 */
990 #if defined(POLARSSL_HAVE_READDIR_R)
991  int t_ret, i;
992  struct stat sb;
993  struct dirent entry, *result = NULL;
994  char entry_name[255];
995  DIR *dir = opendir( path );
996 
997  if( dir == NULL)
999 
1000  while( ( t_ret = readdir_r( dir, &entry, &result ) ) == 0 )
1001  {
1002  if( result == NULL )
1003  break;
1004 
1005  snprintf( entry_name, sizeof(entry_name), "%s/%s", path, entry.d_name );
1006 
1007  i = stat( entry_name, &sb );
1008 
1009  if( i == -1 )
1010  {
1011  closedir( dir );
1013  }
1014 
1015  if( !S_ISREG( sb.st_mode ) )
1016  continue;
1017 
1018  // Ignore parse errors
1019  //
1020  t_ret = x509_crt_parse_file( chain, entry_name );
1021  if( t_ret < 0 )
1022  ret++;
1023  else
1024  ret += t_ret;
1025  }
1026  closedir( dir );
1027 #else /* POLARSSL_HAVE_READDIR_R */
1028  ((void) chain);
1029  ((void) path);
1031 #endif /* POLARSSL_HAVE_READDIR_R */
1032 #endif /* _WIN32 */
1033 
1034  return( ret );
1035 }
1036 #endif /* POLARSSL_FS_IO */
1037 
1038 #if defined _MSC_VER && !defined snprintf
1039 #include <stdarg.h>
1040 
1041 #if !defined vsnprintf
1042 #define vsnprintf _vsnprintf
1043 #endif // vsnprintf
1044 
1045 /*
1046  * Windows _snprintf and _vsnprintf are not compatible to linux versions.
1047  * Result value is not size of buffer needed, but -1 if no fit is possible.
1048  *
1049  * This fuction tries to 'fix' this by at least suggesting enlarging the
1050  * size by 20.
1051  */
1052 static int compat_snprintf(char *str, size_t size, const char *format, ...)
1053 {
1054  va_list ap;
1055  int res = -1;
1056 
1057  va_start( ap, format );
1058 
1059  res = vsnprintf( str, size, format, ap );
1060 
1061  va_end( ap );
1062 
1063  // No quick fix possible
1064  if ( res < 0 )
1065  return( (int) size + 20 );
1066 
1067  return res;
1068 }
1069 
1070 #define snprintf compat_snprintf
1071 #endif
1072 
1073 #define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
1074 
1075 #define SAFE_SNPRINTF() \
1076 { \
1077  if( ret == -1 ) \
1078  return( -1 ); \
1079  \
1080  if ( (unsigned int) ret > n ) { \
1081  p[n - 1] = '\0'; \
1082  return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
1083  } \
1084  \
1085  n -= (unsigned int) ret; \
1086  p += (unsigned int) ret; \
1087 }
1088 
1089 /*
1090  * Return an informational string about the certificate.
1091  */
1092 #define BEFORE_COLON 14
1093 #define BC "14"
1094 int x509_crt_info( char *buf, size_t size, const char *prefix,
1095  const x509_crt *crt )
1096 {
1097  int ret;
1098  size_t n;
1099  char *p;
1100  const char *desc = NULL;
1101  char key_size_str[BEFORE_COLON];
1102 
1103  p = buf;
1104  n = size;
1105 
1106  ret = snprintf( p, n, "%scert. version : %d\n",
1107  prefix, crt->version );
1108  SAFE_SNPRINTF();
1109  ret = snprintf( p, n, "%sserial number : ",
1110  prefix );
1111  SAFE_SNPRINTF();
1112 
1113  ret = x509_serial_gets( p, n, &crt->serial);
1114  SAFE_SNPRINTF();
1115 
1116  ret = snprintf( p, n, "\n%sissuer name : ", prefix );
1117  SAFE_SNPRINTF();
1118  ret = x509_dn_gets( p, n, &crt->issuer );
1119  SAFE_SNPRINTF();
1120 
1121  ret = snprintf( p, n, "\n%ssubject name : ", prefix );
1122  SAFE_SNPRINTF();
1123  ret = x509_dn_gets( p, n, &crt->subject );
1124  SAFE_SNPRINTF();
1125 
1126  ret = snprintf( p, n, "\n%sissued on : " \
1127  "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1128  crt->valid_from.year, crt->valid_from.mon,
1129  crt->valid_from.day, crt->valid_from.hour,
1130  crt->valid_from.min, crt->valid_from.sec );
1131  SAFE_SNPRINTF();
1132 
1133  ret = snprintf( p, n, "\n%sexpires on : " \
1134  "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1135  crt->valid_to.year, crt->valid_to.mon,
1136  crt->valid_to.day, crt->valid_to.hour,
1137  crt->valid_to.min, crt->valid_to.sec );
1138  SAFE_SNPRINTF();
1139 
1140  ret = snprintf( p, n, "\n%ssigned using : ", prefix );
1141  SAFE_SNPRINTF();
1142 
1143  ret = oid_get_sig_alg_desc( &crt->sig_oid1, &desc );
1144  if( ret != 0 )
1145  ret = snprintf( p, n, "???" );
1146  else
1147  ret = snprintf( p, n, "%s", desc );
1148  SAFE_SNPRINTF();
1149 
1150  if( ( ret = x509_key_size_helper( key_size_str, BEFORE_COLON,
1151  pk_get_name( &crt->pk ) ) ) != 0 )
1152  {
1153  return( ret );
1154  }
1155 
1156  ret = snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str,
1157  (int) pk_get_size( &crt->pk ) );
1158  SAFE_SNPRINTF();
1159 
1160  return( (int) ( size - n ) );
1161 }
1162 
1163 #if defined(POLARSSL_X509_CRL_PARSE_C)
1164 /*
1165  * Return 1 if the certificate is revoked, or 0 otherwise.
1166  */
1167 int x509_crt_revoked( const x509_crt *crt, const x509_crl *crl )
1168 {
1169  const x509_crl_entry *cur = &crl->entry;
1170 
1171  while( cur != NULL && cur->serial.len != 0 )
1172  {
1173  if( crt->serial.len == cur->serial.len &&
1174  memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
1175  {
1176  if( x509_time_expired( &cur->revocation_date ) )
1177  return( 1 );
1178  }
1179 
1180  cur = cur->next;
1181  }
1182 
1183  return( 0 );
1184 }
1185 
1186 /*
1187  * Check that the given certificate is valid accoring to the CRL.
1188  */
1189 static int x509_crt_verifycrl( x509_crt *crt, x509_crt *ca,
1190  x509_crl *crl_list)
1191 {
1192  int flags = 0;
1193  unsigned char hash[POLARSSL_MD_MAX_SIZE];
1194  const md_info_t *md_info;
1195 
1196  if( ca == NULL )
1197  return( flags );
1198 
1199  /*
1200  * TODO: What happens if no CRL is present?
1201  * Suggestion: Revocation state should be unknown if no CRL is present.
1202  * For backwards compatibility this is not yet implemented.
1203  */
1204 
1205  while( crl_list != NULL )
1206  {
1207  if( crl_list->version == 0 ||
1208  crl_list->issuer_raw.len != ca->subject_raw.len ||
1209  memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
1210  crl_list->issuer_raw.len ) != 0 )
1211  {
1212  crl_list = crl_list->next;
1213  continue;
1214  }
1215 
1216  /*
1217  * Check if CRL is correctly signed by the trusted CA
1218  */
1219  md_info = md_info_from_type( crl_list->sig_md );
1220  if( md_info == NULL )
1221  {
1222  /*
1223  * Cannot check 'unknown' hash
1224  */
1225  flags |= BADCRL_NOT_TRUSTED;
1226  break;
1227  }
1228 
1229  md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
1230 
1231  if( pk_can_do( &ca->pk, crl_list->sig_pk ) == 0 ||
1232  pk_verify( &ca->pk, crl_list->sig_md, hash, md_info->size,
1233  crl_list->sig.p, crl_list->sig.len ) != 0 )
1234  {
1235  flags |= BADCRL_NOT_TRUSTED;
1236  break;
1237  }
1238 
1239  /*
1240  * Check for validity of CRL (Do not drop out)
1241  */
1242  if( x509_time_expired( &crl_list->next_update ) )
1243  flags |= BADCRL_EXPIRED;
1244 
1245  /*
1246  * Check if certificate is revoked
1247  */
1248  if( x509_crt_revoked(crt, crl_list) )
1249  {
1250  flags |= BADCERT_REVOKED;
1251  break;
1252  }
1253 
1254  crl_list = crl_list->next;
1255  }
1256  return flags;
1257 }
1258 #endif /* POLARSSL_X509_CRL_PARSE_C */
1259 
1260 // Equal == 0, inequal == 1
1261 static int x509_name_cmp( const void *s1, const void *s2, size_t len )
1262 {
1263  size_t i;
1264  unsigned char diff;
1265  const unsigned char *n1 = s1, *n2 = s2;
1266 
1267  for( i = 0; i < len; i++ )
1268  {
1269  diff = n1[i] ^ n2[i];
1270 
1271  if( ( n1[i] >= 'a' || n1[i] <= 'z' ) && ( diff == 0 || diff == 32 ) )
1272  continue;
1273 
1274  if( ( n1[i] >= 'A' || n1[i] <= 'Z' ) && ( diff == 0 || diff == 32 ) )
1275  continue;
1276 
1277  return( 1 );
1278  }
1279 
1280  return( 0 );
1281 }
1282 
1283 static int x509_wildcard_verify( const char *cn, x509_buf *name )
1284 {
1285  size_t i;
1286  size_t cn_idx = 0;
1287 
1288  if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
1289  return( 0 );
1290 
1291  for( i = 0; i < strlen( cn ); ++i )
1292  {
1293  if( cn[i] == '.' )
1294  {
1295  cn_idx = i;
1296  break;
1297  }
1298  }
1299 
1300  if( cn_idx == 0 )
1301  return( 0 );
1302 
1303  if( strlen( cn ) - cn_idx == name->len - 1 &&
1304  x509_name_cmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
1305  {
1306  return( 1 );
1307  }
1308 
1309  return( 0 );
1310 }
1311 
1312 static int x509_crt_verify_top(
1313  x509_crt *child, x509_crt *trust_ca,
1314  x509_crl *ca_crl, int path_cnt, int *flags,
1315  int (*f_vrfy)(void *, x509_crt *, int, int *),
1316  void *p_vrfy )
1317 {
1318  int ret;
1319  int ca_flags = 0, check_path_cnt = path_cnt + 1;
1320  unsigned char hash[POLARSSL_MD_MAX_SIZE];
1321  const md_info_t *md_info;
1322 
1323  if( x509_time_expired( &child->valid_to ) )
1324  *flags |= BADCERT_EXPIRED;
1325 
1326  /*
1327  * Child is the top of the chain. Check against the trust_ca list.
1328  */
1329  *flags |= BADCERT_NOT_TRUSTED;
1330 
1331  md_info = md_info_from_type( child->sig_md );
1332  if( md_info == NULL )
1333  {
1334  /*
1335  * Cannot check 'unknown', no need to try any CA
1336  */
1337  trust_ca = NULL;
1338  }
1339  else
1340  md( md_info, child->tbs.p, child->tbs.len, hash );
1341 
1342  while( trust_ca != NULL )
1343  {
1344  if( trust_ca->version == 0 ||
1345  child->issuer_raw.len != trust_ca->subject_raw.len ||
1346  memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
1347  child->issuer_raw.len ) != 0 )
1348  {
1349  trust_ca = trust_ca->next;
1350  continue;
1351  }
1352 
1353  /*
1354  * Reduce path_len to check against if top of the chain is
1355  * the same as the trusted CA
1356  */
1357  if( child->subject_raw.len == trust_ca->subject_raw.len &&
1358  memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
1359  child->issuer_raw.len ) == 0 )
1360  {
1361  check_path_cnt--;
1362  }
1363 
1364  if( trust_ca->max_pathlen > 0 &&
1365  trust_ca->max_pathlen < check_path_cnt )
1366  {
1367  trust_ca = trust_ca->next;
1368  continue;
1369  }
1370 
1371  if( pk_can_do( &trust_ca->pk, child->sig_pk ) == 0 ||
1372  pk_verify( &trust_ca->pk, child->sig_md, hash, md_info->size,
1373  child->sig.p, child->sig.len ) != 0 )
1374  {
1375  trust_ca = trust_ca->next;
1376  continue;
1377  }
1378 
1379  /*
1380  * Top of chain is signed by a trusted CA
1381  */
1382  *flags &= ~BADCERT_NOT_TRUSTED;
1383  break;
1384  }
1385 
1386  /*
1387  * If top of chain is not the same as the trusted CA send a verify request
1388  * to the callback for any issues with validity and CRL presence for the
1389  * trusted CA certificate.
1390  */
1391  if( trust_ca != NULL &&
1392  ( child->subject_raw.len != trust_ca->subject_raw.len ||
1393  memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
1394  child->issuer_raw.len ) != 0 ) )
1395  {
1396 #if defined(POLARSSL_X509_CRL_PARSE_C)
1397  /* Check trusted CA's CRL for the chain's top crt */
1398  *flags |= x509_crt_verifycrl( child, trust_ca, ca_crl );
1399 #else
1400  ((void) ca_crl);
1401 #endif
1402 
1403  if( x509_time_expired( &trust_ca->valid_to ) )
1404  ca_flags |= BADCERT_EXPIRED;
1405 
1406  if( NULL != f_vrfy )
1407  {
1408  if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
1409  return( ret );
1410  }
1411  }
1412 
1413  /* Call callback on top cert */
1414  if( NULL != f_vrfy )
1415  {
1416  if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
1417  return( ret );
1418  }
1419 
1420  *flags |= ca_flags;
1421 
1422  return( 0 );
1423 }
1424 
1425 static int x509_crt_verify_child(
1426  x509_crt *child, x509_crt *parent, x509_crt *trust_ca,
1427  x509_crl *ca_crl, int path_cnt, int *flags,
1428  int (*f_vrfy)(void *, x509_crt *, int, int *),
1429  void *p_vrfy )
1430 {
1431  int ret;
1432  int parent_flags = 0;
1433  unsigned char hash[POLARSSL_MD_MAX_SIZE];
1434  x509_crt *grandparent;
1435  const md_info_t *md_info;
1436 
1437  if( x509_time_expired( &child->valid_to ) )
1438  *flags |= BADCERT_EXPIRED;
1439 
1440  md_info = md_info_from_type( child->sig_md );
1441  if( md_info == NULL )
1442  {
1443  /*
1444  * Cannot check 'unknown' hash
1445  */
1446  *flags |= BADCERT_NOT_TRUSTED;
1447  }
1448  else
1449  {
1450  md( md_info, child->tbs.p, child->tbs.len, hash );
1451 
1452  if( pk_can_do( &parent->pk, child->sig_pk ) == 0 ||
1453  pk_verify( &parent->pk, child->sig_md, hash, md_info->size,
1454  child->sig.p, child->sig.len ) != 0 )
1455  {
1456  *flags |= BADCERT_NOT_TRUSTED;
1457  }
1458  }
1459 
1460 #if defined(POLARSSL_X509_CRL_PARSE_C)
1461  /* Check trusted CA's CRL for the given crt */
1462  *flags |= x509_crt_verifycrl(child, parent, ca_crl);
1463 #endif
1464 
1465  grandparent = parent->next;
1466 
1467  while( grandparent != NULL )
1468  {
1469  if( grandparent->version == 0 ||
1470  grandparent->ca_istrue == 0 ||
1471  parent->issuer_raw.len != grandparent->subject_raw.len ||
1472  memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
1473  parent->issuer_raw.len ) != 0 )
1474  {
1475  grandparent = grandparent->next;
1476  continue;
1477  }
1478  break;
1479  }
1480 
1481  if( grandparent != NULL )
1482  {
1483  /*
1484  * Part of the chain
1485  */
1486  ret = x509_crt_verify_child( parent, grandparent, trust_ca, ca_crl, path_cnt + 1, &parent_flags, f_vrfy, p_vrfy );
1487  if( ret != 0 )
1488  return( ret );
1489  }
1490  else
1491  {
1492  ret = x509_crt_verify_top( parent, trust_ca, ca_crl, path_cnt + 1, &parent_flags, f_vrfy, p_vrfy );
1493  if( ret != 0 )
1494  return( ret );
1495  }
1496 
1497  /* child is verified to be a child of the parent, call verify callback */
1498  if( NULL != f_vrfy )
1499  if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
1500  return( ret );
1501 
1502  *flags |= parent_flags;
1503 
1504  return( 0 );
1505 }
1506 
1507 /*
1508  * Verify the certificate validity
1509  */
1510 int x509_crt_verify( x509_crt *crt,
1511  x509_crt *trust_ca,
1512  x509_crl *ca_crl,
1513  const char *cn, int *flags,
1514  int (*f_vrfy)(void *, x509_crt *, int, int *),
1515  void *p_vrfy )
1516 {
1517  size_t cn_len;
1518  int ret;
1519  int pathlen = 0;
1520  x509_crt *parent;
1521  x509_name *name;
1522  x509_sequence *cur = NULL;
1523 
1524  *flags = 0;
1525 
1526  if( cn != NULL )
1527  {
1528  name = &crt->subject;
1529  cn_len = strlen( cn );
1530 
1531  if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
1532  {
1533  cur = &crt->subject_alt_names;
1534 
1535  while( cur != NULL )
1536  {
1537  if( cur->buf.len == cn_len &&
1538  x509_name_cmp( cn, cur->buf.p, cn_len ) == 0 )
1539  break;
1540 
1541  if( cur->buf.len > 2 &&
1542  memcmp( cur->buf.p, "*.", 2 ) == 0 &&
1543  x509_wildcard_verify( cn, &cur->buf ) )
1544  break;
1545 
1546  cur = cur->next;
1547  }
1548 
1549  if( cur == NULL )
1550  *flags |= BADCERT_CN_MISMATCH;
1551  }
1552  else
1553  {
1554  while( name != NULL )
1555  {
1556  if( OID_CMP( OID_AT_CN, &name->oid ) )
1557  {
1558  if( name->val.len == cn_len &&
1559  x509_name_cmp( name->val.p, cn, cn_len ) == 0 )
1560  break;
1561 
1562  if( name->val.len > 2 &&
1563  memcmp( name->val.p, "*.", 2 ) == 0 &&
1564  x509_wildcard_verify( cn, &name->val ) )
1565  break;
1566  }
1567 
1568  name = name->next;
1569  }
1570 
1571  if( name == NULL )
1572  *flags |= BADCERT_CN_MISMATCH;
1573  }
1574  }
1575 
1576  /*
1577  * Iterate upwards in the given cert chain, to find our crt parent.
1578  * Ignore any upper cert with CA != TRUE.
1579  */
1580  parent = crt->next;
1581 
1582  while( parent != NULL && parent->version != 0 )
1583  {
1584  if( parent->ca_istrue == 0 ||
1585  crt->issuer_raw.len != parent->subject_raw.len ||
1586  memcmp( crt->issuer_raw.p, parent->subject_raw.p,
1587  crt->issuer_raw.len ) != 0 )
1588  {
1589  parent = parent->next;
1590  continue;
1591  }
1592  break;
1593  }
1594 
1595  if( parent != NULL )
1596  {
1597  /*
1598  * Part of the chain
1599  */
1600  ret = x509_crt_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
1601  if( ret != 0 )
1602  return( ret );
1603  }
1604  else
1605  {
1606  ret = x509_crt_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
1607  if( ret != 0 )
1608  return( ret );
1609  }
1610 
1611  if( *flags != 0 )
1613 
1614  return( 0 );
1615 }
1616 
1617 /*
1618  * Initialize a certificate chain
1619  */
1620 void x509_crt_init( x509_crt *crt )
1621 {
1622  memset( crt, 0, sizeof(x509_crt) );
1623 }
1624 
1625 /*
1626  * Unallocate all certificate data
1627  */
1628 void x509_crt_free( x509_crt *crt )
1629 {
1630  x509_crt *cert_cur = crt;
1631  x509_crt *cert_prv;
1632  x509_name *name_cur;
1633  x509_name *name_prv;
1634  x509_sequence *seq_cur;
1635  x509_sequence *seq_prv;
1636 
1637  if( crt == NULL )
1638  return;
1639 
1640  do
1641  {
1642  pk_free( &cert_cur->pk );
1643 
1644  name_cur = cert_cur->issuer.next;
1645  while( name_cur != NULL )
1646  {
1647  name_prv = name_cur;
1648  name_cur = name_cur->next;
1649  memset( name_prv, 0, sizeof( x509_name ) );
1650  polarssl_free( name_prv );
1651  }
1652 
1653  name_cur = cert_cur->subject.next;
1654  while( name_cur != NULL )
1655  {
1656  name_prv = name_cur;
1657  name_cur = name_cur->next;
1658  memset( name_prv, 0, sizeof( x509_name ) );
1659  polarssl_free( name_prv );
1660  }
1661 
1662  seq_cur = cert_cur->ext_key_usage.next;
1663  while( seq_cur != NULL )
1664  {
1665  seq_prv = seq_cur;
1666  seq_cur = seq_cur->next;
1667  memset( seq_prv, 0, sizeof( x509_sequence ) );
1668  polarssl_free( seq_prv );
1669  }
1670 
1671  seq_cur = cert_cur->subject_alt_names.next;
1672  while( seq_cur != NULL )
1673  {
1674  seq_prv = seq_cur;
1675  seq_cur = seq_cur->next;
1676  memset( seq_prv, 0, sizeof( x509_sequence ) );
1677  polarssl_free( seq_prv );
1678  }
1679 
1680  if( cert_cur->raw.p != NULL )
1681  {
1682  memset( cert_cur->raw.p, 0, cert_cur->raw.len );
1683  polarssl_free( cert_cur->raw.p );
1684  }
1685 
1686  cert_cur = cert_cur->next;
1687  }
1688  while( cert_cur != NULL );
1689 
1690  cert_cur = crt;
1691  do
1692  {
1693  cert_prv = cert_cur;
1694  cert_cur = cert_cur->next;
1695 
1696  memset( cert_prv, 0, sizeof( x509_crt ) );
1697  if( cert_prv != crt )
1698  polarssl_free( cert_prv );
1699  }
1700  while( cert_cur != NULL );
1701 }
1702 
1703 #endif
int md(const md_info_t *md_info, const unsigned char *input, size_t ilen, unsigned char *output)
Output = message_digest( input buffer )
x509_buf sig
Definition: x509_crl.h:89
int x509_time_expired(const x509_time *time)
Check a given x509_time against the system time and check if it is valid.
int asn1_get_sequence_of(unsigned char **p, const unsigned char *end, asn1_sequence *cur, int tag)
Parses and splits an ASN.1 &quot;SEQUENCE OF &lt;tag&gt;&quot; Updated the pointer to immediately behind the full seq...
x509_sequence subject_alt_names
Optional list of Subject Alternative Names (Only dNSName supported).
Definition: x509_crt.h:76
#define X509_FORMAT_DER
Definition: x509.h:134
Memory allocation layer.
#define ASN1_OID
Definition: asn1.h:76
#define EXT_KEY_USAGE
Definition: x509.h:114
void *(* polarssl_malloc)(size_t len)
int sec
Time.
Definition: x509.h:175
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:55
int version
Definition: x509_crl.h:74
asn1_buf buf
Buffer containing the given ASN.1 item.
Definition: asn1.h:140
int x509_get_serial(unsigned char **p, const unsigned char *end, x509_buf *serial)
x509_buf raw
The raw certificate data (DER).
Definition: x509_crt.h:55
x509_time next_update
Definition: x509_crl.h:82
#define POLARSSL_ERR_ASN1_LENGTH_MISMATCH
Actual length differs from expected length.
Definition: asn1.h:53
int ext_types
Bit string containing detected and parsed extensions.
Definition: x509_crt.h:78
Certificate revocation list entry.
Definition: x509_crl.h:51
size_t pk_get_size(const pk_context *ctx)
Get the size in bits of the underlying key.
#define POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT
Format not recognized as DER or PEM.
Definition: x509.h:62
#define EXT_BASIC_CONSTRAINTS
Definition: x509.h:120
unsigned char ns_cert_type
Optional Netscape certificate type extension value: See the values below.
Definition: x509_crt.h:86
x509_buf issuer_raw
The raw issuer data (DER).
Definition: x509_crt.h:62
#define POLARSSL_ERR_X509_INVALID_FORMAT
The CRT/CRL/CSR format is invalid, e.g.
Definition: x509.h:50
int x509_key_size_helper(char *buf, size_t size, const char *name)
struct _x509_crl * next
Definition: x509_crl.h:93
int asn1_get_int(unsigned char **p, const unsigned char *end, int *val)
Retrieve an integer ASN.1 tag and its value.
size_t len
ASN1 length, e.g.
Definition: asn1.h:129
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:172
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:78
x509_buf sig_oid2
Signature algorithm.
Definition: x509_crt.h:88
int oid_get_x509_ext_type(const asn1_buf *oid, int *ext_type)
Translate an X.509 extension OID into local values.
void x509_crt_free(x509_crt *crt)
Unallocate all certificate data.
Configuration options (set of defines)
#define OID_CMP(oid_str, oid_buf)
Compares two asn1_buf structures for the same OID.
Definition: asn1.h:100
x509_buf tbs
The raw certificate body (DER).
Definition: x509_crt.h:56
x509_buf serial
Unique id for certificate issued by a specific CA.
Definition: x509_crt.h:59
md_type_t sig_md
Internal representation of the MD algorithm of the signature algorithm, e.g.
Definition: x509_crt.h:90
int ca_istrue
Optional Basic Constraint extension value: 1 if this certificate belongs to a CA, 0 otherwise...
Definition: x509_crt.h:79
#define ASN1_CONSTRUCTED
Definition: asn1.h:88
int x509_crt_parse_der(x509_crt *chain, const unsigned char *buf, size_t buflen)
Parse a single DER formatted certificate and add it to the chained list.
int max_pathlen
Optional Basic Constraint extension value: The maximum path length to the root certificate.
Definition: x509_crt.h:80
int x509_get_sig(unsigned char **p, const unsigned char *end, x509_buf *sig)
const char * pk_get_name(const pk_context *ctx)
Access the type name.
#define BADCRL_NOT_TRUSTED
CRL is not correctly signed by the trusted CA.
Definition: x509.h:76
#define POLARSSL_ERR_ASN1_INVALID_LENGTH
Error when trying to determine the length or invalid length.
Definition: asn1.h:52
Container for ASN1 bit strings.
Definition: asn1.h:127
#define POLARSSL_ERR_X509_UNKNOWN_VERSION
CRT/CRL/CSR has an unsupported version number.
Definition: x509.h:58
Object Identifier (OID) database.
x509_buf serial
Definition: x509_crl.h:55
#define OID_AT_CN
id-at-commonName AttributeType:= {id-at 3}
Definition: oid.h:106
struct _x509_crt * next
Next certificate in the CA-chain.
Definition: x509_crt.h:93
x509_crl_entry entry
The CRL entries containing the certificate revocation times for this CA.
Definition: x509_crl.h:84
asn1_buf val
The named value.
Definition: asn1.h:151
int hour
Definition: x509.h:175
int mon
Definition: x509.h:174
Container for a sequence of ASN.1 items.
Definition: asn1.h:138
const md_info_t * md_info_from_type(md_type_t md_type)
Returns the message digest information associated with the given digest type.
int x509_get_time(unsigned char **p, const unsigned char *end, x509_time *time)
#define BADCERT_EXPIRED
The certificate validity has expired.
Definition: x509.h:72
unsigned char * p
Raw ASN1 data for the bit string.
Definition: asn1.h:131
#define POLARSSL_ERR_X509_CERT_VERIFY_FAILED
Certificate verification failed, e.g.
Definition: x509.h:61
Container for an X.509 certificate.
Definition: x509_crt.h:53
Privacy Enhanced Mail (PEM) decoding.
x509_time valid_from
Start time of certificate validity.
Definition: x509_crt.h:68
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:150
int pk_verify(pk_context *ctx, md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len)
Verify signature.
x509_sequence ext_key_usage
Optional list of extended key usage OIDs.
Definition: x509_crt.h:84
void x509_crt_init(x509_crt *crt)
Initialize a certificate (chain)
void(* polarssl_free)(void *ptr)
unsigned char * p
ASN1 data, e.g.
Definition: asn1.h:120
int oid_get_sig_alg_desc(const asn1_buf *oid, const char **desc)
Translate SignatureAlgorithm OID into description.
x509_name subject
The parsed subject data (named information object).
Definition: x509_crt.h:66
#define EXT_NS_CERT_TYPE
Definition: x509.h:128
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 pk_can_do(pk_context *ctx, pk_type_t type)
Tell if a context can do the operation given by type.
x509_buf tbs
The raw certificate body (DER).
Definition: x509_crl.h:72
int asn1_get_bool(unsigned char **p, const unsigned char *end, int *val)
Retrieve a boolean ASN.1 tag and its value.
x509_time valid_to
End time of certificate validity.
Definition: x509_crt.h:69
struct _x509_crl_entry * next
Definition: x509_crl.h:61
md_type_t sig_md
Internal representation of the MD algorithm of the signature algorithm, e.g.
Definition: x509_crl.h:90
X.509 certificate parsing and writing.
int day
Date.
Definition: x509.h:174
int x509_get_sig_alg(const x509_buf *sig_oid, md_type_t *md_alg, pk_type_t *pk_alg)
x509_buf sig_oid1
Signature algorithm, e.g.
Definition: x509_crt.h:60
int tag
ASN1 type, e.g.
Definition: asn1.h:118
#define POLARSSL_ERR_ASN1_OUT_OF_DATA
Out of data when parsing an ASN1 data structure.
Definition: asn1.h:50
#define EXT_EXTENDED_KEY_USAGE
Definition: x509.h:123
int pk_parse_subpubkey(unsigned char **p, const unsigned char *end, pk_context *pk)
Parse a SubjectPublicKeyInfo DER structure.
int x509_load_file(const char *path, unsigned char **buf, size_t *n)
#define POLARSSL_ERR_ASN1_MALLOC_FAILED
Memory allocation failed.
Definition: asn1.h:55
#define ASN1_CONTEXT_SPECIFIC
Definition: asn1.h:89
#define BADCERT_NOT_TRUSTED
The certificate is not correctly signed by the trusted CA.
Definition: x509.h:75
#define POLARSSL_ERR_X509_FILE_IO_ERROR
Read/write of file failed.
Definition: x509.h:65
int x509_crt_revoked(const x509_crt *crt, const x509_crl *crl)
Verify the certificate revocation status.
Container for a sequence or list of &#39;named&#39; ASN.1 data items.
Definition: asn1.h:148
Type-length-value structure that allows for ASN1 using DER.
Definition: asn1.h:116
pk_type_t sig_pk
&lt; Internal representation of the Public Key algorithm of the signature algorithm, e...
Definition: x509_crl.h:91
size_t len
ASN1 length, e.g.
Definition: asn1.h:119
x509_name issuer
The parsed issuer data (named information object).
Definition: x509_crt.h:65
#define X509_FORMAT_PEM
Definition: x509.h:135
void pk_free(pk_context *ctx)
Free a pk_context.
#define POLARSSL_MD_MAX_SIZE
Definition: md.h:66
int year
Definition: x509.h:174
#define BADCERT_REVOKED
The certificate has been revoked (is on a CRL).
Definition: x509.h:73
#define BADCRL_EXPIRED
CRL is expired.
Definition: x509.h:77
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:48
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)
#define POLARSSL_ERR_X509_INVALID_VERSION
The CRT/CRL/CSR version element is invalid.
Definition: x509.h:51
Certificate revocation list structure.
Definition: x509_crl.h:69
int asn1_get_bitstring(unsigned char **p, const unsigned char *end, asn1_bitstring *bs)
Retrieve a bitstring ASN.1 tag and its value.
pk_context pk
Container for the public key context.
Definition: x509_crt.h:71
int min
Definition: x509.h:175
struct _asn1_named_data * next
The next entry in the sequence.
Definition: asn1.h:152
int size
Output length of the digest function.
Definition: md.h:81
x509_buf issuer_id
Optional X.509 v2/v3 issuer unique identifier.
Definition: x509_crt.h:73
#define POLARSSL_ERR_X509_INVALID_EXTENSIONS
The extension tag or value is invalid.
Definition: x509.h:57
#define ASN1_OCTET_STRING
Definition: asn1.h:74
int x509_crt_parse_path(x509_crt *chain, const char *path)
Load one or more certificate files from a path and add them to the chained list.
x509_buf v3_ext
Optional X.509 v3 extensions.
Definition: x509_crt.h:75
#define POLARSSL_ERR_X509_BAD_INPUT_DATA
Input invalid.
Definition: x509.h:63
x509_buf subject_id
Optional X.509 v2/v3 subject unique identifier.
Definition: x509_crt.h:74
#define BADCERT_CN_MISMATCH
The certificate Common Name (CN) does not match with the expected CN.
Definition: x509.h:74
int version
The X.509 version.
Definition: x509_crt.h:58
#define POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT
No PEM header or footer found.
Definition: pem.h:38
pk_type_t sig_pk
&lt; Internal representation of the Public Key algorithm of the signature algorithm, e...
Definition: x509_crt.h:91
x509_time revocation_date
Definition: x509_crl.h:57
x509_buf issuer_raw
The raw issuer data (DER).
Definition: x509_crl.h:77
int x509_crt_info(char *buf, size_t size, const char *prefix, const x509_crt *crt)
Returns an informational string about the certificate.
#define POLARSSL_ERR_X509_MALLOC_FAILED
Allocation of memory failed.
Definition: x509.h:64
#define POLARSSL_ERR_PEM_BAD_INPUT_DATA
Bad input parameters to function.
Definition: pem.h:46
unsigned char key_usage
Optional key usage extension value: See the values below.
Definition: x509_crt.h:82
x509_buf subject_raw
The raw subject data (DER).
Definition: x509_crt.h:63
Message digest information.
Definition: md.h:73
#define POLARSSL_ERR_ASN1_UNEXPECTED_TAG
ASN1 tag was of an unexpected value.
Definition: asn1.h:51
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 POLARSSL_ERR_X509_SIG_MISMATCH
Signature algorithms do not match.
Definition: x509.h:60
struct _asn1_sequence * next
The next entry in the sequence.
Definition: asn1.h:141
int x509_crt_parse_file(x509_crt *chain, const char *path)
Load one or more certificates and add them to the chained list.
x509_buf sig
Signature: hash of the tbs part signed with the private key.
Definition: x509_crt.h:89
#define EXT_SUBJECT_ALT_NAME
Definition: x509.h:117