blob: 49cda666cdb9edc87b22c37e3bce09700813cdcf [file] [log] [blame]
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001/*
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 */
74static 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,
82 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
83 {
84 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
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 )
Paul Bakker51876562013-09-17 14:36:05 +020096 return( POLARSSL_ERR_X509_INVALID_VERSION + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +020097
98 if( *p != end )
Paul Bakker51876562013-09-17 14:36:05 +020099 return( POLARSSL_ERR_X509_INVALID_VERSION +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200100 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
101
102 return( 0 );
103}
104
105/*
106 * Validity ::= SEQUENCE {
107 * notBefore Time,
108 * notAfter Time }
109 */
110static 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 )
Paul Bakker51876562013-09-17 14:36:05 +0200120 return( POLARSSL_ERR_X509_INVALID_DATE + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200121
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 )
Paul Bakker51876562013-09-17 14:36:05 +0200131 return( POLARSSL_ERR_X509_INVALID_DATE +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200132 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
133
134 return( 0 );
135}
136
137/*
138 * X.509 v2/v3 unique identifier (not parsed)
139 */
140static 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 {
154 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
155 return( 0 );
156
157 return( ret );
158 }
159
160 uid->p = *p;
161 *p += uid->len;
162
163 return( 0 );
164}
165
166static 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 )
Paul Bakker51876562013-09-17 14:36:05 +0200184 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200185
186 if( *p == end )
187 return 0;
188
189 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
190 {
191 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
192 ret = asn1_get_int( p, end, ca_istrue );
193
194 if( ret != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200195 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200196
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 )
Paul Bakker51876562013-09-17 14:36:05 +0200205 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200206
207 if( *p != end )
Paul Bakker51876562013-09-17 14:36:05 +0200208 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200209 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
210
211 (*max_pathlen)++;
212
213 return 0;
214}
215
216static 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 )
Paul Bakker51876562013-09-17 14:36:05 +0200224 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200225
226 if( bs.len != 1 )
Paul Bakker51876562013-09-17 14:36:05 +0200227 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200228 POLARSSL_ERR_ASN1_INVALID_LENGTH );
229
230 /* Get actual bitstring */
231 *ns_cert_type = *bs.p;
232 return 0;
233}
234
235static 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 )
Paul Bakker51876562013-09-17 14:36:05 +0200243 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200244
245 if( bs.len < 1 )
Paul Bakker51876562013-09-17 14:36:05 +0200246 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200247 POLARSSL_ERR_ASN1_INVALID_LENGTH );
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 */
259static 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 )
Paul Bakker51876562013-09-17 14:36:05 +0200266 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200267
268 /* Sequence length must be >= 1 */
269 if( ext_key_usage->buf.p == NULL )
Paul Bakker51876562013-09-17 14:36:05 +0200270 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200271 POLARSSL_ERR_ASN1_INVALID_LENGTH );
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 */
302static 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 )
Paul Bakker51876562013-09-17 14:36:05 +0200315 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200316
317 if( *p + len != end )
Paul Bakker51876562013-09-17 14:36:05 +0200318 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200319 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
320
321 while( *p < end )
322 {
323 if( ( end - *p ) < 1 )
Paul Bakker51876562013-09-17 14:36:05 +0200324 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200325 POLARSSL_ERR_ASN1_OUT_OF_DATA );
326
327 tag = **p;
328 (*p)++;
329 if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200330 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200331
332 if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC )
Paul Bakker51876562013-09-17 14:36:05 +0200333 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200334 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
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 {
351 cur->next = (asn1_sequence *) polarssl_malloc(
352 sizeof( asn1_sequence ) );
353
354 if( cur->next == NULL )
Paul Bakker51876562013-09-17 14:36:05 +0200355 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200356 POLARSSL_ERR_ASN1_MALLOC_FAILED );
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 )
Paul Bakker51876562013-09-17 14:36:05 +0200367 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200368 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
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 */
380static int x509_get_crt_ext( unsigned char **p,
381 const unsigned char *end,
Paul Bakkerc559c7a2013-09-18 14:13:26 +0200382 x509_crt *crt )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200383{
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 {
390 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
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 )
Paul Bakker51876562013-09-17 14:36:05 +0200410 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200411
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 )
Paul Bakker51876562013-09-17 14:36:05 +0200418 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200419
420 extn_oid.p = *p;
421 *p += extn_oid.len;
422
423 if( ( end - *p ) < 1 )
Paul Bakker51876562013-09-17 14:36:05 +0200424 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200425 POLARSSL_ERR_ASN1_OUT_OF_DATA );
426
427 /* Get optional critical */
428 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
429 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
Paul Bakker51876562013-09-17 14:36:05 +0200430 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200431
432 /* Data should be octet string type */
433 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
434 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker51876562013-09-17 14:36:05 +0200435 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200436
437 end_ext_octet = *p + len;
438
439 if( end_ext_octet != end_ext_data )
Paul Bakker51876562013-09-17 14:36:05 +0200440 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200441 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
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 */
Paul Bakker51876562013-09-17 14:36:05 +0200457 return ( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200458 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
459 }
460#endif
461 continue;
462 }
463
464 crt->ext_types |= ext_type;
465
466 switch( ext_type )
467 {
468 case EXT_BASIC_CONSTRAINTS:
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
482 case EXT_EXTENDED_KEY_USAGE:
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
489 case EXT_SUBJECT_ALT_NAME:
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:
504 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
505 }
506 }
507
508 if( *p != end )
Paul Bakker51876562013-09-17 14:36:05 +0200509 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200510 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
511
512 return( 0 );
513}
514
515/*
516 * Parse and fill a single X.509 certificate in DER format
517 */
Paul Bakkerc559c7a2013-09-18 14:13:26 +0200518static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf,
Paul Bakkerddf26b42013-09-18 13:46:23 +0200519 size_t buflen )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200520{
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 )
Paul Bakker51876562013-09-17 14:36:05 +0200529 return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200530
531 p = (unsigned char *) polarssl_malloc( len = buflen );
532
533 if( p == NULL )
534 return( POLARSSL_ERR_X509_MALLOC_FAILED );
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 );
Paul Bakker51876562013-09-17 14:36:05 +0200554 return( POLARSSL_ERR_X509_INVALID_FORMAT );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200555 }
556
557 if( len > (size_t) ( end - p ) )
558 {
559 x509_crt_free( crt );
Paul Bakker51876562013-09-17 14:36:05 +0200560 return( POLARSSL_ERR_X509_INVALID_FORMAT +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200561 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
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 );
Paul Bakker51876562013-09-17 14:36:05 +0200574 return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200575 }
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 );
Paul Bakker51876562013-09-17 14:36:05 +0200600 return( POLARSSL_ERR_X509_UNKNOWN_VERSION );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200601 }
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 );
Paul Bakker51876562013-09-17 14:36:05 +0200619 return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200620 }
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 );
Paul Bakker51876562013-09-17 14:36:05 +0200652 return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200653 }
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 */
Paul Bakkerda771152013-09-16 22:45:03 +0200666 if( ( ret = pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200667 {
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( crt->version == 3 )
701 {
702 ret = x509_get_crt_ext( &p, end, crt);
703 if( ret != 0 )
704 {
705 x509_crt_free( crt );
706 return( ret );
707 }
708 }
709
710 if( p != end )
711 {
712 x509_crt_free( crt );
Paul Bakker51876562013-09-17 14:36:05 +0200713 return( POLARSSL_ERR_X509_INVALID_FORMAT +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200714 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
715 }
716
717 end = crt_end;
718
719 /*
720 * }
721 * -- end of TBSCertificate
722 *
723 * signatureAlgorithm AlgorithmIdentifier,
724 * signatureValue BIT STRING
725 */
726 if( ( ret = x509_get_alg_null( &p, end, &crt->sig_oid2 ) ) != 0 )
727 {
728 x509_crt_free( crt );
729 return( ret );
730 }
731
732 if( crt->sig_oid1.len != crt->sig_oid2.len ||
733 memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
734 {
735 x509_crt_free( crt );
Paul Bakker51876562013-09-17 14:36:05 +0200736 return( POLARSSL_ERR_X509_SIG_MISMATCH );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200737 }
738
739 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
740 {
741 x509_crt_free( crt );
742 return( ret );
743 }
744
745 if( p != end )
746 {
747 x509_crt_free( crt );
Paul Bakker51876562013-09-17 14:36:05 +0200748 return( POLARSSL_ERR_X509_INVALID_FORMAT +
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200749 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
750 }
751
752 return( 0 );
753}
754
755/*
756 * Parse one X.509 certificate in DER format from a buffer and add them to a
757 * chained list
758 */
Paul Bakkerc559c7a2013-09-18 14:13:26 +0200759int x509_crt_parse_der( x509_crt *chain, const unsigned char *buf,
Paul Bakkerddf26b42013-09-18 13:46:23 +0200760 size_t buflen )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200761{
762 int ret;
Paul Bakkerc559c7a2013-09-18 14:13:26 +0200763 x509_crt *crt = chain, *prev = NULL;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200764
765 /*
766 * Check for valid input
767 */
768 if( crt == NULL || buf == NULL )
Paul Bakker51876562013-09-17 14:36:05 +0200769 return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200770
771 while( crt->version != 0 && crt->next != NULL )
772 {
773 prev = crt;
774 crt = crt->next;
775 }
776
777 /*
778 * Add new certificate on the end of the chain if needed.
779 */
780 if ( crt->version != 0 && crt->next == NULL)
781 {
Paul Bakkerc559c7a2013-09-18 14:13:26 +0200782 crt->next = (x509_crt *) polarssl_malloc( sizeof( x509_crt ) );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200783
784 if( crt->next == NULL )
785 return( POLARSSL_ERR_X509_MALLOC_FAILED );
786
787 prev = crt;
788 crt = crt->next;
Paul Bakker369d2eb2013-09-18 11:58:25 +0200789 x509_crt_init( crt );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200790 }
791
Paul Bakkerddf26b42013-09-18 13:46:23 +0200792 if( ( ret = x509_crt_parse_der_core( crt, buf, buflen ) ) != 0 )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200793 {
794 if( prev )
795 prev->next = NULL;
796
797 if( crt != chain )
798 polarssl_free( crt );
799
800 return( ret );
801 }
802
803 return( 0 );
804}
805
806/*
807 * Parse one or more PEM certificates from a buffer and add them to the chained list
808 */
Paul Bakkerc559c7a2013-09-18 14:13:26 +0200809int x509_crt_parse( x509_crt *chain, const unsigned char *buf, size_t buflen )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200810{
811 int success = 0, first_error = 0, total_failed = 0;
812 int buf_format = X509_FORMAT_DER;
813
814 /*
815 * Check for valid input
816 */
817 if( chain == NULL || buf == NULL )
Paul Bakker51876562013-09-17 14:36:05 +0200818 return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200819
820 /*
821 * Determine buffer content. Buffer contains either one DER certificate or
822 * one or more PEM certificates.
823 */
824#if defined(POLARSSL_PEM_PARSE_C)
825 if( strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
826 buf_format = X509_FORMAT_PEM;
827#endif
828
829 if( buf_format == X509_FORMAT_DER )
Paul Bakkerddf26b42013-09-18 13:46:23 +0200830 return x509_crt_parse_der( chain, buf, buflen );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200831
832#if defined(POLARSSL_PEM_PARSE_C)
833 if( buf_format == X509_FORMAT_PEM )
834 {
835 int ret;
836 pem_context pem;
837
838 while( buflen > 0 )
839 {
840 size_t use_len;
841 pem_init( &pem );
842
843 ret = pem_read_buffer( &pem,
844 "-----BEGIN CERTIFICATE-----",
845 "-----END CERTIFICATE-----",
846 buf, NULL, 0, &use_len );
847
848 if( ret == 0 )
849 {
850 /*
851 * Was PEM encoded
852 */
853 buflen -= use_len;
854 buf += use_len;
855 }
856 else if( ret == POLARSSL_ERR_PEM_BAD_INPUT_DATA )
857 {
858 return( ret );
859 }
860 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
861 {
862 pem_free( &pem );
863
864 /*
865 * PEM header and footer were found
866 */
867 buflen -= use_len;
868 buf += use_len;
869
870 if( first_error == 0 )
871 first_error = ret;
872
873 continue;
874 }
875 else
876 break;
877
Paul Bakkerddf26b42013-09-18 13:46:23 +0200878 ret = x509_crt_parse_der( chain, pem.buf, pem.buflen );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200879
880 pem_free( &pem );
881
882 if( ret != 0 )
883 {
884 /*
885 * Quit parsing on a memory error
886 */
887 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
888 return( ret );
889
890 if( first_error == 0 )
891 first_error = ret;
892
893 total_failed++;
894 continue;
895 }
896
897 success = 1;
898 }
899 }
900#endif
901
902 if( success )
903 return( total_failed );
904 else if( first_error )
905 return( first_error );
906 else
907 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
908}
909
910#if defined(POLARSSL_FS_IO)
911/*
912 * Load one or more certificates and add them to the chained list
913 */
Paul Bakkerc559c7a2013-09-18 14:13:26 +0200914int x509_crt_parse_file( x509_crt *chain, const char *path )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200915{
916 int ret;
917 size_t n;
918 unsigned char *buf;
919
920 if ( ( ret = x509_load_file( path, &buf, &n ) ) != 0 )
921 return( ret );
922
Paul Bakkerddf26b42013-09-18 13:46:23 +0200923 ret = x509_crt_parse( chain, buf, n );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200924
925 memset( buf, 0, n + 1 );
926 polarssl_free( buf );
927
928 return( ret );
929}
930
Paul Bakkerc559c7a2013-09-18 14:13:26 +0200931int x509_crt_parse_path( x509_crt *chain, const char *path )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200932{
933 int ret = 0;
934#if defined(_WIN32)
935 int w_ret;
936 WCHAR szDir[MAX_PATH];
937 char filename[MAX_PATH];
938 char *p;
939 int len = strlen( path );
940
941 WIN32_FIND_DATAW file_data;
942 HANDLE hFind;
943
944 if( len > MAX_PATH - 3 )
945 return( POLARSSL_ERR_X509_INVALID_INPUT );
946
947 memset( szDir, 0, sizeof(szDir) );
948 memset( filename, 0, MAX_PATH );
949 memcpy( filename, path, len );
950 filename[len++] = '\\';
951 p = filename + len;
952 filename[len++] = '*';
953
954 w_ret = MultiByteToWideChar( CP_ACP, 0, path, len, szDir, MAX_PATH - 3 );
955
956 hFind = FindFirstFileW( szDir, &file_data );
957 if (hFind == INVALID_HANDLE_VALUE)
958 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
959
960 len = MAX_PATH - len;
961 do
962 {
963 memset( p, 0, len );
964
965 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
966 continue;
967
968 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
969 lstrlenW(file_data.cFileName),
970 p, len - 1,
971 NULL, NULL );
972
Paul Bakkerddf26b42013-09-18 13:46:23 +0200973 w_ret = x509_crt_parse_file( chain, filename );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200974 if( w_ret < 0 )
975 ret++;
976 else
977 ret += w_ret;
978 }
979 while( FindNextFileW( hFind, &file_data ) != 0 );
980
981 if (GetLastError() != ERROR_NO_MORE_FILES)
982 ret = POLARSSL_ERR_X509_FILE_IO_ERROR;
983
984cleanup:
985 FindClose( hFind );
986#else
987 int t_ret, i;
988 struct stat sb;
989 struct dirent entry, *result = NULL;
990 char entry_name[255];
991 DIR *dir = opendir( path );
992
993 if( dir == NULL)
994 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
995
996 while( ( t_ret = readdir_r( dir, &entry, &result ) ) == 0 )
997 {
998 if( result == NULL )
999 break;
1000
1001 snprintf( entry_name, sizeof(entry_name), "%s/%s", path, entry.d_name );
1002
1003 i = stat( entry_name, &sb );
1004
1005 if( i == -1 )
1006 {
1007 closedir( dir );
1008 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1009 }
1010
1011 if( !S_ISREG( sb.st_mode ) )
1012 continue;
1013
1014 // Ignore parse errors
1015 //
Paul Bakkerddf26b42013-09-18 13:46:23 +02001016 t_ret = x509_crt_parse_file( chain, entry_name );
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001017 if( t_ret < 0 )
1018 ret++;
1019 else
1020 ret += t_ret;
1021 }
1022 closedir( dir );
1023#endif
1024
1025 return( ret );
1026}
1027#endif /* POLARSSL_FS_IO */
1028
1029#if defined _MSC_VER && !defined snprintf
1030#include <stdarg.h>
1031
1032#if !defined vsnprintf
1033#define vsnprintf _vsnprintf
1034#endif // vsnprintf
1035
1036/*
1037 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
1038 * Result value is not size of buffer needed, but -1 if no fit is possible.
1039 *
1040 * This fuction tries to 'fix' this by at least suggesting enlarging the
1041 * size by 20.
1042 */
1043static int compat_snprintf(char *str, size_t size, const char *format, ...)
1044{
1045 va_list ap;
1046 int res = -1;
1047
1048 va_start( ap, format );
1049
1050 res = vsnprintf( str, size, format, ap );
1051
1052 va_end( ap );
1053
1054 // No quick fix possible
1055 if ( res < 0 )
1056 return( (int) size + 20 );
1057
1058 return res;
1059}
1060
1061#define snprintf compat_snprintf
1062#endif
1063
1064#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
1065
1066#define SAFE_SNPRINTF() \
1067{ \
1068 if( ret == -1 ) \
1069 return( -1 ); \
1070 \
1071 if ( (unsigned int) ret > n ) { \
1072 p[n - 1] = '\0'; \
1073 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
1074 } \
1075 \
1076 n -= (unsigned int) ret; \
1077 p += (unsigned int) ret; \
1078}
1079
1080/*
1081 * Return an informational string about the certificate.
1082 */
1083#define BEFORE_COLON 14
1084#define BC "14"
Paul Bakkerddf26b42013-09-18 13:46:23 +02001085int x509_crt_info( char *buf, size_t size, const char *prefix,
Paul Bakkerc559c7a2013-09-18 14:13:26 +02001086 const x509_crt *crt )
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001087{
1088 int ret;
1089 size_t n;
1090 char *p;
1091 const char *desc = NULL;
1092 char key_size_str[BEFORE_COLON];
1093
1094 p = buf;
1095 n = size;
1096
1097 ret = snprintf( p, n, "%scert. version : %d\n",
1098 prefix, crt->version );
1099 SAFE_SNPRINTF();
1100 ret = snprintf( p, n, "%sserial number : ",
1101 prefix );
1102 SAFE_SNPRINTF();
1103
Paul Bakker86d0c192013-09-18 11:11:02 +02001104 ret = x509_serial_gets( p, n, &crt->serial);
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001105 SAFE_SNPRINTF();
1106
1107 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
1108 SAFE_SNPRINTF();
Paul Bakker86d0c192013-09-18 11:11:02 +02001109 ret = x509_dn_gets( p, n, &crt->issuer );
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001110 SAFE_SNPRINTF();
1111
1112 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
1113 SAFE_SNPRINTF();
Paul Bakker86d0c192013-09-18 11:11:02 +02001114 ret = x509_dn_gets( p, n, &crt->subject );
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001115 SAFE_SNPRINTF();
1116
1117 ret = snprintf( p, n, "\n%sissued on : " \
1118 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1119 crt->valid_from.year, crt->valid_from.mon,
1120 crt->valid_from.day, crt->valid_from.hour,
1121 crt->valid_from.min, crt->valid_from.sec );
1122 SAFE_SNPRINTF();
1123
1124 ret = snprintf( p, n, "\n%sexpires on : " \
1125 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1126 crt->valid_to.year, crt->valid_to.mon,
1127 crt->valid_to.day, crt->valid_to.hour,
1128 crt->valid_to.min, crt->valid_to.sec );
1129 SAFE_SNPRINTF();
1130
1131 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
1132 SAFE_SNPRINTF();
1133
1134 ret = oid_get_sig_alg_desc( &crt->sig_oid1, &desc );
1135 if( ret != 0 )
1136 ret = snprintf( p, n, "???" );
1137 else
1138 ret = snprintf( p, n, "%s", desc );
1139 SAFE_SNPRINTF();
1140
1141 if( ( ret = x509_key_size_helper( key_size_str, BEFORE_COLON,
1142 pk_get_name( &crt->pk ) ) ) != 0 )
1143 {
1144 return( ret );
1145 }
1146
1147 ret = snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str,
1148 (int) pk_get_size( &crt->pk ) );
1149 SAFE_SNPRINTF();
1150
1151 return( (int) ( size - n ) );
1152}
1153
1154#if defined(POLARSSL_X509_CRL_PARSE_C)
1155/*
1156 * Return 1 if the certificate is revoked, or 0 otherwise.
1157 */
Paul Bakkerc559c7a2013-09-18 14:13:26 +02001158int x509_crt_revoked( const x509_crt *crt, const x509_crl *crl )
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001159{
1160 const x509_crl_entry *cur = &crl->entry;
1161
1162 while( cur != NULL && cur->serial.len != 0 )
1163 {
1164 if( crt->serial.len == cur->serial.len &&
1165 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
1166 {
Paul Bakker86d0c192013-09-18 11:11:02 +02001167 if( x509_time_expired( &cur->revocation_date ) )
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001168 return( 1 );
1169 }
1170
1171 cur = cur->next;
1172 }
1173
1174 return( 0 );
1175}
1176
1177/*
1178 * Check that the given certificate is valid accoring to the CRL.
1179 */
Paul Bakkerc559c7a2013-09-18 14:13:26 +02001180static int x509_crt_verifycrl( x509_crt *crt, x509_crt *ca,
Paul Bakkerddf26b42013-09-18 13:46:23 +02001181 x509_crl *crl_list)
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001182{
1183 int flags = 0;
1184 unsigned char hash[POLARSSL_MD_MAX_SIZE];
1185 const md_info_t *md_info;
1186
1187 if( ca == NULL )
1188 return( flags );
1189
1190 /*
1191 * TODO: What happens if no CRL is present?
1192 * Suggestion: Revocation state should be unknown if no CRL is present.
1193 * For backwards compatibility this is not yet implemented.
1194 */
1195
1196 while( crl_list != NULL )
1197 {
1198 if( crl_list->version == 0 ||
1199 crl_list->issuer_raw.len != ca->subject_raw.len ||
1200 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
1201 crl_list->issuer_raw.len ) != 0 )
1202 {
1203 crl_list = crl_list->next;
1204 continue;
1205 }
1206
1207 /*
1208 * Check if CRL is correctly signed by the trusted CA
1209 */
1210 md_info = md_info_from_type( crl_list->sig_md );
1211 if( md_info == NULL )
1212 {
1213 /*
1214 * Cannot check 'unknown' hash
1215 */
1216 flags |= BADCRL_NOT_TRUSTED;
1217 break;
1218 }
1219
1220 md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
1221
1222 if( pk_can_do( &ca->pk, crl_list->sig_pk ) == 0 ||
1223 pk_verify( &ca->pk, crl_list->sig_md, hash, md_info->size,
1224 crl_list->sig.p, crl_list->sig.len ) != 0 )
1225 {
1226 flags |= BADCRL_NOT_TRUSTED;
1227 break;
1228 }
1229
1230 /*
1231 * Check for validity of CRL (Do not drop out)
1232 */
Paul Bakker86d0c192013-09-18 11:11:02 +02001233 if( x509_time_expired( &crl_list->next_update ) )
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001234 flags |= BADCRL_EXPIRED;
1235
1236 /*
1237 * Check if certificate is revoked
1238 */
Paul Bakkerddf26b42013-09-18 13:46:23 +02001239 if( x509_crt_revoked(crt, crl_list) )
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001240 {
1241 flags |= BADCERT_REVOKED;
1242 break;
1243 }
1244
1245 crl_list = crl_list->next;
1246 }
1247 return flags;
1248}
1249#endif /* POLARSSL_X509_CRL_PARSE_C */
1250
1251// Equal == 0, inequal == 1
1252static int x509_name_cmp( const void *s1, const void *s2, size_t len )
1253{
1254 size_t i;
1255 unsigned char diff;
1256 const unsigned char *n1 = s1, *n2 = s2;
1257
1258 for( i = 0; i < len; i++ )
1259 {
1260 diff = n1[i] ^ n2[i];
1261
1262 if( ( n1[i] >= 'a' || n1[i] <= 'z' ) && ( diff == 0 || diff == 32 ) )
1263 continue;
1264
1265 if( ( n1[i] >= 'A' || n1[i] <= 'Z' ) && ( diff == 0 || diff == 32 ) )
1266 continue;
1267
1268 return( 1 );
1269 }
1270
1271 return( 0 );
1272}
1273
1274static int x509_wildcard_verify( const char *cn, x509_buf *name )
1275{
1276 size_t i;
1277 size_t cn_idx = 0;
1278
1279 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
1280 return( 0 );
1281
1282 for( i = 0; i < strlen( cn ); ++i )
1283 {
1284 if( cn[i] == '.' )
1285 {
1286 cn_idx = i;
1287 break;
1288 }
1289 }
1290
1291 if( cn_idx == 0 )
1292 return( 0 );
1293
1294 if( strlen( cn ) - cn_idx == name->len - 1 &&
1295 x509_name_cmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
1296 {
1297 return( 1 );
1298 }
1299
1300 return( 0 );
1301}
1302
Paul Bakkerddf26b42013-09-18 13:46:23 +02001303static int x509_crt_verify_top(
Paul Bakkerc559c7a2013-09-18 14:13:26 +02001304 x509_crt *child, x509_crt *trust_ca,
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001305 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakkerc559c7a2013-09-18 14:13:26 +02001306 int (*f_vrfy)(void *, x509_crt *, int, int *),
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001307 void *p_vrfy )
1308{
1309 int ret;
1310 int ca_flags = 0, check_path_cnt = path_cnt + 1;
1311 unsigned char hash[POLARSSL_MD_MAX_SIZE];
1312 const md_info_t *md_info;
1313
Paul Bakker86d0c192013-09-18 11:11:02 +02001314 if( x509_time_expired( &child->valid_to ) )
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001315 *flags |= BADCERT_EXPIRED;
1316
1317 /*
1318 * Child is the top of the chain. Check against the trust_ca list.
1319 */
1320 *flags |= BADCERT_NOT_TRUSTED;
1321
1322 md_info = md_info_from_type( child->sig_md );
1323 if( md_info == NULL )
1324 {
1325 /*
1326 * Cannot check 'unknown', no need to try any CA
1327 */
1328 trust_ca = NULL;
1329 }
1330 else
1331 md( md_info, child->tbs.p, child->tbs.len, hash );
1332
1333 while( trust_ca != NULL )
1334 {
1335 if( trust_ca->version == 0 ||
1336 child->issuer_raw.len != trust_ca->subject_raw.len ||
1337 memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
1338 child->issuer_raw.len ) != 0 )
1339 {
1340 trust_ca = trust_ca->next;
1341 continue;
1342 }
1343
1344 /*
1345 * Reduce path_len to check against if top of the chain is
1346 * the same as the trusted CA
1347 */
1348 if( child->subject_raw.len == trust_ca->subject_raw.len &&
1349 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
1350 child->issuer_raw.len ) == 0 )
1351 {
1352 check_path_cnt--;
1353 }
1354
1355 if( trust_ca->max_pathlen > 0 &&
1356 trust_ca->max_pathlen < check_path_cnt )
1357 {
1358 trust_ca = trust_ca->next;
1359 continue;
1360 }
1361
1362 if( pk_can_do( &trust_ca->pk, child->sig_pk ) == 0 ||
1363 pk_verify( &trust_ca->pk, child->sig_md, hash, md_info->size,
1364 child->sig.p, child->sig.len ) != 0 )
1365 {
1366 trust_ca = trust_ca->next;
1367 continue;
1368 }
1369
1370 /*
1371 * Top of chain is signed by a trusted CA
1372 */
1373 *flags &= ~BADCERT_NOT_TRUSTED;
1374 break;
1375 }
1376
1377 /*
1378 * If top of chain is not the same as the trusted CA send a verify request
1379 * to the callback for any issues with validity and CRL presence for the
1380 * trusted CA certificate.
1381 */
1382 if( trust_ca != NULL &&
1383 ( child->subject_raw.len != trust_ca->subject_raw.len ||
1384 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
1385 child->issuer_raw.len ) != 0 ) )
1386 {
1387#if defined(POLARSSL_X509_CRL_PARSE_C)
1388 /* Check trusted CA's CRL for the chain's top crt */
Paul Bakkerddf26b42013-09-18 13:46:23 +02001389 *flags |= x509_crt_verifycrl( child, trust_ca, ca_crl );
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001390#endif
1391
Paul Bakker86d0c192013-09-18 11:11:02 +02001392 if( x509_time_expired( &trust_ca->valid_to ) )
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001393 ca_flags |= BADCERT_EXPIRED;
1394
1395 if( NULL != f_vrfy )
1396 {
1397 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
1398 return( ret );
1399 }
1400 }
1401
1402 /* Call callback on top cert */
1403 if( NULL != f_vrfy )
1404 {
1405 if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
1406 return( ret );
1407 }
1408
1409 *flags |= ca_flags;
1410
1411 return( 0 );
1412}
1413
Paul Bakkerddf26b42013-09-18 13:46:23 +02001414static int x509_crt_verify_child(
Paul Bakkerc559c7a2013-09-18 14:13:26 +02001415 x509_crt *child, x509_crt *parent, x509_crt *trust_ca,
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001416 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakkerc559c7a2013-09-18 14:13:26 +02001417 int (*f_vrfy)(void *, x509_crt *, int, int *),
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001418 void *p_vrfy )
1419{
1420 int ret;
1421 int parent_flags = 0;
1422 unsigned char hash[POLARSSL_MD_MAX_SIZE];
Paul Bakkerc559c7a2013-09-18 14:13:26 +02001423 x509_crt *grandparent;
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001424 const md_info_t *md_info;
1425
Paul Bakker86d0c192013-09-18 11:11:02 +02001426 if( x509_time_expired( &child->valid_to ) )
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001427 *flags |= BADCERT_EXPIRED;
1428
1429 md_info = md_info_from_type( child->sig_md );
1430 if( md_info == NULL )
1431 {
1432 /*
1433 * Cannot check 'unknown' hash
1434 */
1435 *flags |= BADCERT_NOT_TRUSTED;
1436 }
1437 else
1438 {
1439 md( md_info, child->tbs.p, child->tbs.len, hash );
1440
1441 if( pk_can_do( &parent->pk, child->sig_pk ) == 0 ||
1442 pk_verify( &parent->pk, child->sig_md, hash, md_info->size,
1443 child->sig.p, child->sig.len ) != 0 )
1444 {
1445 *flags |= BADCERT_NOT_TRUSTED;
1446 }
1447 }
1448
1449#if defined(POLARSSL_X509_CRL_PARSE_C)
1450 /* Check trusted CA's CRL for the given crt */
Paul Bakkerddf26b42013-09-18 13:46:23 +02001451 *flags |= x509_crt_verifycrl(child, parent, ca_crl);
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001452#endif
1453
1454 grandparent = parent->next;
1455
1456 while( grandparent != NULL )
1457 {
1458 if( grandparent->version == 0 ||
1459 grandparent->ca_istrue == 0 ||
1460 parent->issuer_raw.len != grandparent->subject_raw.len ||
1461 memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
1462 parent->issuer_raw.len ) != 0 )
1463 {
1464 grandparent = grandparent->next;
1465 continue;
1466 }
1467 break;
1468 }
1469
1470 if( grandparent != NULL )
1471 {
1472 /*
1473 * Part of the chain
1474 */
Paul Bakkerddf26b42013-09-18 13:46:23 +02001475 ret = x509_crt_verify_child( parent, grandparent, trust_ca, ca_crl, path_cnt + 1, &parent_flags, f_vrfy, p_vrfy );
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001476 if( ret != 0 )
1477 return( ret );
1478 }
1479 else
1480 {
Paul Bakkerddf26b42013-09-18 13:46:23 +02001481 ret = x509_crt_verify_top( parent, trust_ca, ca_crl, path_cnt + 1, &parent_flags, f_vrfy, p_vrfy );
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001482 if( ret != 0 )
1483 return( ret );
1484 }
1485
1486 /* child is verified to be a child of the parent, call verify callback */
1487 if( NULL != f_vrfy )
1488 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
1489 return( ret );
1490
1491 *flags |= parent_flags;
1492
1493 return( 0 );
1494}
1495
1496/*
1497 * Verify the certificate validity
1498 */
Paul Bakkerc559c7a2013-09-18 14:13:26 +02001499int x509_crt_verify( x509_crt *crt,
1500 x509_crt *trust_ca,
Paul Bakkerddf26b42013-09-18 13:46:23 +02001501 x509_crl *ca_crl,
1502 const char *cn, int *flags,
Paul Bakkerc559c7a2013-09-18 14:13:26 +02001503 int (*f_vrfy)(void *, x509_crt *, int, int *),
Paul Bakkerddf26b42013-09-18 13:46:23 +02001504 void *p_vrfy )
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001505{
1506 size_t cn_len;
1507 int ret;
1508 int pathlen = 0;
Paul Bakkerc559c7a2013-09-18 14:13:26 +02001509 x509_crt *parent;
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001510 x509_name *name;
1511 x509_sequence *cur = NULL;
1512
1513 *flags = 0;
1514
1515 if( cn != NULL )
1516 {
1517 name = &crt->subject;
1518 cn_len = strlen( cn );
1519
1520 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
1521 {
1522 cur = &crt->subject_alt_names;
1523
1524 while( cur != NULL )
1525 {
1526 if( cur->buf.len == cn_len &&
1527 x509_name_cmp( cn, cur->buf.p, cn_len ) == 0 )
1528 break;
1529
1530 if( cur->buf.len > 2 &&
1531 memcmp( cur->buf.p, "*.", 2 ) == 0 &&
1532 x509_wildcard_verify( cn, &cur->buf ) )
1533 break;
1534
1535 cur = cur->next;
1536 }
1537
1538 if( cur == NULL )
1539 *flags |= BADCERT_CN_MISMATCH;
1540 }
1541 else
1542 {
1543 while( name != NULL )
1544 {
1545 if( OID_CMP( OID_AT_CN, &name->oid ) )
1546 {
1547 if( name->val.len == cn_len &&
1548 x509_name_cmp( name->val.p, cn, cn_len ) == 0 )
1549 break;
1550
1551 if( name->val.len > 2 &&
1552 memcmp( name->val.p, "*.", 2 ) == 0 &&
1553 x509_wildcard_verify( cn, &name->val ) )
1554 break;
1555 }
1556
1557 name = name->next;
1558 }
1559
1560 if( name == NULL )
1561 *flags |= BADCERT_CN_MISMATCH;
1562 }
1563 }
1564
1565 /*
1566 * Iterate upwards in the given cert chain, to find our crt parent.
1567 * Ignore any upper cert with CA != TRUE.
1568 */
1569 parent = crt->next;
1570
1571 while( parent != NULL && parent->version != 0 )
1572 {
1573 if( parent->ca_istrue == 0 ||
1574 crt->issuer_raw.len != parent->subject_raw.len ||
1575 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
1576 crt->issuer_raw.len ) != 0 )
1577 {
1578 parent = parent->next;
1579 continue;
1580 }
1581 break;
1582 }
1583
1584 if( parent != NULL )
1585 {
1586 /*
1587 * Part of the chain
1588 */
Paul Bakkerddf26b42013-09-18 13:46:23 +02001589 ret = x509_crt_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001590 if( ret != 0 )
1591 return( ret );
1592 }
1593 else
1594 {
Paul Bakkerddf26b42013-09-18 13:46:23 +02001595 ret = x509_crt_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001596 if( ret != 0 )
1597 return( ret );
1598 }
1599
1600 if( *flags != 0 )
1601 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
1602
1603 return( 0 );
1604}
1605
1606/*
Paul Bakker369d2eb2013-09-18 11:58:25 +02001607 * Initialize a certificate chain
1608 */
Paul Bakkerc559c7a2013-09-18 14:13:26 +02001609void x509_crt_init( x509_crt *crt )
Paul Bakker369d2eb2013-09-18 11:58:25 +02001610{
Paul Bakkerc559c7a2013-09-18 14:13:26 +02001611 memset( crt, 0, sizeof(x509_crt) );
Paul Bakker369d2eb2013-09-18 11:58:25 +02001612}
1613
1614/*
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001615 * Unallocate all certificate data
1616 */
Paul Bakkerc559c7a2013-09-18 14:13:26 +02001617void x509_crt_free( x509_crt *crt )
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001618{
Paul Bakkerc559c7a2013-09-18 14:13:26 +02001619 x509_crt *cert_cur = crt;
1620 x509_crt *cert_prv;
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001621 x509_name *name_cur;
1622 x509_name *name_prv;
1623 x509_sequence *seq_cur;
1624 x509_sequence *seq_prv;
1625
1626 if( crt == NULL )
1627 return;
1628
1629 do
1630 {
1631 pk_free( &cert_cur->pk );
1632
1633 name_cur = cert_cur->issuer.next;
1634 while( name_cur != NULL )
1635 {
1636 name_prv = name_cur;
1637 name_cur = name_cur->next;
1638 memset( name_prv, 0, sizeof( x509_name ) );
1639 polarssl_free( name_prv );
1640 }
1641
1642 name_cur = cert_cur->subject.next;
1643 while( name_cur != NULL )
1644 {
1645 name_prv = name_cur;
1646 name_cur = name_cur->next;
1647 memset( name_prv, 0, sizeof( x509_name ) );
1648 polarssl_free( name_prv );
1649 }
1650
1651 seq_cur = cert_cur->ext_key_usage.next;
1652 while( seq_cur != NULL )
1653 {
1654 seq_prv = seq_cur;
1655 seq_cur = seq_cur->next;
1656 memset( seq_prv, 0, sizeof( x509_sequence ) );
1657 polarssl_free( seq_prv );
1658 }
1659
1660 seq_cur = cert_cur->subject_alt_names.next;
1661 while( seq_cur != NULL )
1662 {
1663 seq_prv = seq_cur;
1664 seq_cur = seq_cur->next;
1665 memset( seq_prv, 0, sizeof( x509_sequence ) );
1666 polarssl_free( seq_prv );
1667 }
1668
1669 if( cert_cur->raw.p != NULL )
1670 {
1671 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
1672 polarssl_free( cert_cur->raw.p );
1673 }
1674
1675 cert_cur = cert_cur->next;
1676 }
1677 while( cert_cur != NULL );
1678
1679 cert_cur = crt;
1680 do
1681 {
1682 cert_prv = cert_cur;
1683 cert_cur = cert_cur->next;
1684
Paul Bakkerc559c7a2013-09-18 14:13:26 +02001685 memset( cert_prv, 0, sizeof( x509_crt ) );
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001686 if( cert_prv != crt )
1687 polarssl_free( cert_prv );
1688 }
1689 while( cert_cur != NULL );
1690}
1691
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001692#endif