blob: d97efff48dfb11237a039fdd39e2fc06ca2c74f2 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * X.509 certificate and private key decoding
3 *
Paul Bakker84f12b72010-07-18 10:13:04 +00004 * Copyright (C) 2006-2010, Brainspark B.V.
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
Paul Bakker84f12b72010-07-18 10:13:04 +00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakkerb96f1542010-07-18 20:36:00 +00008 *
Paul Bakker77b385e2009-07-28 17:23:11 +00009 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +000010 *
Paul Bakker5121ce52009-01-03 21:22:43 +000011 * 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 certificat format for PKI.
27 *
28 * http://www.ietf.org/rfc/rfc2459.txt
29 * http://www.ietf.org/rfc/rfc3279.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
Paul Bakker40e46942009-01-03 21:51:57 +000037#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000038
Paul Bakker40e46942009-01-03 21:51:57 +000039#if defined(POLARSSL_X509_PARSE_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000040
Paul Bakker40e46942009-01-03 21:51:57 +000041#include "polarssl/x509.h"
Paul Bakker96743fc2011-02-12 14:30:57 +000042#include "polarssl/pem.h"
Paul Bakker40e46942009-01-03 21:51:57 +000043#include "polarssl/des.h"
44#include "polarssl/md2.h"
45#include "polarssl/md4.h"
46#include "polarssl/md5.h"
47#include "polarssl/sha1.h"
Paul Bakker026c03b2009-03-28 17:53:03 +000048#include "polarssl/sha2.h"
49#include "polarssl/sha4.h"
Paul Bakker1b57b062011-01-06 15:48:19 +000050#include "polarssl/dhm.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000051
52#include <string.h>
53#include <stdlib.h>
Paul Bakker5121ce52009-01-03 21:22:43 +000054#include <time.h>
55
Paul Bakker335db3f2011-04-25 15:28:35 +000056#if defined(POLARSSL_FS_IO)
57#include <stdio.h>
58#endif
59
Paul Bakker5121ce52009-01-03 21:22:43 +000060/*
61 * ASN.1 DER decoding routines
62 */
63static int asn1_get_len( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +000064 const unsigned char *end,
Paul Bakker23986e52011-04-24 08:57:21 +000065 size_t *len )
Paul Bakker5121ce52009-01-03 21:22:43 +000066{
67 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +000068 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000069
70 if( ( **p & 0x80 ) == 0 )
71 *len = *(*p)++;
72 else
73 {
74 switch( **p & 0x7F )
75 {
76 case 1:
77 if( ( end - *p ) < 2 )
Paul Bakker40e46942009-01-03 21:51:57 +000078 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000079
80 *len = (*p)[1];
81 (*p) += 2;
82 break;
83
84 case 2:
85 if( ( end - *p ) < 3 )
Paul Bakker40e46942009-01-03 21:51:57 +000086 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000087
88 *len = ( (*p)[1] << 8 ) | (*p)[2];
89 (*p) += 3;
90 break;
91
Paul Bakkerc4909d92011-10-12 09:52:22 +000092 case 3:
93 if( ( end - *p ) < 4 )
94 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
95
96 *len = ( (*p)[1] << 16 ) | ( (*p)[2] << 8 ) | (*p)[3];
97 (*p) += 4;
98 break;
99
100 case 4:
101 if( ( end - *p ) < 5 )
102 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
103
104 *len = ( (*p)[1] << 24 ) | ( (*p)[2] << 16 ) | ( (*p)[3] << 8 ) | (*p)[4];
105 (*p) += 5;
106 break;
107
Paul Bakker5121ce52009-01-03 21:22:43 +0000108 default:
Paul Bakker40e46942009-01-03 21:51:57 +0000109 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000110 }
111 }
112
Paul Bakker23986e52011-04-24 08:57:21 +0000113 if( *len > (size_t) ( end - *p ) )
Paul Bakker40e46942009-01-03 21:51:57 +0000114 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000115
116 return( 0 );
117}
118
119static int asn1_get_tag( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000120 const unsigned char *end,
Paul Bakker23986e52011-04-24 08:57:21 +0000121 size_t *len, int tag )
Paul Bakker5121ce52009-01-03 21:22:43 +0000122{
123 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000124 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000125
126 if( **p != tag )
Paul Bakker40e46942009-01-03 21:51:57 +0000127 return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000128
129 (*p)++;
130
131 return( asn1_get_len( p, end, len ) );
132}
133
134static int asn1_get_bool( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000135 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000136 int *val )
137{
Paul Bakker23986e52011-04-24 08:57:21 +0000138 int ret;
139 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000140
141 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 )
142 return( ret );
143
144 if( len != 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000145 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000146
147 *val = ( **p != 0 ) ? 1 : 0;
148 (*p)++;
149
150 return( 0 );
151}
152
153static int asn1_get_int( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000154 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000155 int *val )
156{
Paul Bakker23986e52011-04-24 08:57:21 +0000157 int ret;
158 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000159
160 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
161 return( ret );
162
Paul Bakker27fdf462011-06-09 13:55:13 +0000163 if( len > sizeof( int ) || ( **p & 0x80 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000164 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000165
166 *val = 0;
167
168 while( len-- > 0 )
169 {
170 *val = ( *val << 8 ) | **p;
171 (*p)++;
172 }
173
174 return( 0 );
175}
176
177static int asn1_get_mpi( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000178 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000179 mpi *X )
180{
Paul Bakker23986e52011-04-24 08:57:21 +0000181 int ret;
182 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000183
184 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
185 return( ret );
186
187 ret = mpi_read_binary( X, *p, len );
188
189 *p += len;
190
191 return( ret );
192}
193
Paul Bakker74111d32011-01-15 16:57:55 +0000194static int asn1_get_bitstring( unsigned char **p, const unsigned char *end,
195 x509_bitstring *bs)
196{
197 int ret;
198
199 /* Certificate type is a single byte bitstring */
200 if( ( ret = asn1_get_tag( p, end, &bs->len, ASN1_BIT_STRING ) ) != 0 )
201 return( ret );
202
203 /* Check length, subtract one for actual bit string length */
204 if ( bs->len < 1 )
205 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
206 bs->len -= 1;
207
208 /* Get number of unused bits, ensure unused bits <= 7 */
209 bs->unused_bits = **p;
210 if( bs->unused_bits > 7 )
211 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
212 (*p)++;
213
214 /* Get actual bitstring */
215 bs->p = *p;
216 *p += bs->len;
217
218 if( *p != end )
219 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
220
221 return 0;
222}
223
224
225/*
226 * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
227 */
228static int asn1_get_sequence_of( unsigned char **p,
229 const unsigned char *end,
230 x509_sequence *cur,
231 int tag)
232{
Paul Bakker23986e52011-04-24 08:57:21 +0000233 int ret;
234 size_t len;
Paul Bakker74111d32011-01-15 16:57:55 +0000235 x509_buf *buf;
236
237 /* Get main sequence tag */
238 if( ( ret = asn1_get_tag( p, end, &len,
239 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
240 return( ret );
241
242 if( *p + len != end )
243 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
244
245 while( *p < end )
246 {
247 buf = &(cur->buf);
248 buf->tag = **p;
249
250 if( ( ret = asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
251 return( ret );
252
253 buf->p = *p;
254 *p += buf->len;
255
256 /* Allocate and assign next pointer */
257 if (*p < end)
258 {
259 cur->next = (x509_sequence *) malloc(
260 sizeof( x509_sequence ) );
261
262 if( cur->next == NULL )
263 return( 1 );
264
265 cur = cur->next;
266 }
267 }
268
269 /* Set final sequence entry's next pointer to NULL */
270 cur->next = NULL;
271
272 if( *p != end )
273 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
274
275 return( 0 );
276}
277
Paul Bakker5121ce52009-01-03 21:22:43 +0000278/*
279 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
280 */
281static int x509_get_version( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000282 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000283 int *ver )
284{
Paul Bakker23986e52011-04-24 08:57:21 +0000285 int ret;
286 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000287
288 if( ( ret = asn1_get_tag( p, end, &len,
289 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
290 {
Paul Bakker40e46942009-01-03 21:51:57 +0000291 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +0000292 {
293 *ver = 0;
294 return( 0 );
295 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000296
297 return( ret );
298 }
299
300 end = *p + len;
301
302 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000303 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000304
305 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000306 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION +
Paul Bakker40e46942009-01-03 21:51:57 +0000307 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000308
309 return( 0 );
310}
311
312/*
Paul Bakkerfae618f2011-10-12 11:53:52 +0000313 * Version ::= INTEGER { v1(0), v2(1) }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000314 */
315static int x509_crl_get_version( unsigned char **p,
316 const unsigned char *end,
317 int *ver )
318{
319 int ret;
320
321 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
322 {
323 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +0000324 {
325 *ver = 0;
326 return( 0 );
327 }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000328
329 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
330 }
331
332 return( 0 );
333}
334
335/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000336 * CertificateSerialNumber ::= INTEGER
337 */
338static int x509_get_serial( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000339 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000340 x509_buf *serial )
341{
342 int ret;
343
344 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000345 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000346 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000347
348 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
349 **p != ASN1_INTEGER )
Paul Bakker9d781402011-05-09 16:17:09 +0000350 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000351 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000352
353 serial->tag = *(*p)++;
354
355 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000356 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000357
358 serial->p = *p;
359 *p += serial->len;
360
361 return( 0 );
362}
363
364/*
365 * AlgorithmIdentifier ::= SEQUENCE {
366 * algorithm OBJECT IDENTIFIER,
367 * parameters ANY DEFINED BY algorithm OPTIONAL }
368 */
369static int x509_get_alg( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000370 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000371 x509_buf *alg )
372{
Paul Bakker23986e52011-04-24 08:57:21 +0000373 int ret;
374 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000375
376 if( ( ret = asn1_get_tag( p, end, &len,
377 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000378 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000379
380 end = *p + len;
381 alg->tag = **p;
382
383 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000384 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000385
386 alg->p = *p;
387 *p += alg->len;
388
389 if( *p == end )
390 return( 0 );
391
392 /*
393 * assume the algorithm parameters must be NULL
394 */
395 if( ( ret = asn1_get_tag( p, end, &len, ASN1_NULL ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000396 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000397
398 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000399 return( POLARSSL_ERR_X509_CERT_INVALID_ALG +
Paul Bakker40e46942009-01-03 21:51:57 +0000400 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000401
402 return( 0 );
403}
404
405/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000406 * AttributeTypeAndValue ::= SEQUENCE {
407 * type AttributeType,
408 * value AttributeValue }
409 *
410 * AttributeType ::= OBJECT IDENTIFIER
411 *
412 * AttributeValue ::= ANY DEFINED BY AttributeType
413 */
Paul Bakker400ff6f2011-02-20 10:40:16 +0000414static int x509_get_attr_type_value( unsigned char **p,
415 const unsigned char *end,
416 x509_name *cur )
Paul Bakker5121ce52009-01-03 21:22:43 +0000417{
Paul Bakker23986e52011-04-24 08:57:21 +0000418 int ret;
419 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000420 x509_buf *oid;
421 x509_buf *val;
422
423 if( ( ret = asn1_get_tag( p, end, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000424 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000425 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000426
Paul Bakker5121ce52009-01-03 21:22:43 +0000427 oid = &cur->oid;
428 oid->tag = **p;
429
430 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000431 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000432
433 oid->p = *p;
434 *p += oid->len;
435
436 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000437 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000438 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000439
440 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
441 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
442 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker9d781402011-05-09 16:17:09 +0000443 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000444 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000445
446 val = &cur->val;
447 val->tag = *(*p)++;
448
449 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000450 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000451
452 val->p = *p;
453 *p += val->len;
454
455 cur->next = NULL;
456
Paul Bakker400ff6f2011-02-20 10:40:16 +0000457 return( 0 );
458}
459
460/*
461 * RelativeDistinguishedName ::=
462 * SET OF AttributeTypeAndValue
463 *
464 * AttributeTypeAndValue ::= SEQUENCE {
465 * type AttributeType,
466 * value AttributeValue }
467 *
468 * AttributeType ::= OBJECT IDENTIFIER
469 *
470 * AttributeValue ::= ANY DEFINED BY AttributeType
471 */
472static int x509_get_name( unsigned char **p,
473 const unsigned char *end,
474 x509_name *cur )
475{
Paul Bakker23986e52011-04-24 08:57:21 +0000476 int ret;
477 size_t len;
Paul Bakker400ff6f2011-02-20 10:40:16 +0000478 const unsigned char *end2;
479 x509_name *use;
480
481 if( ( ret = asn1_get_tag( p, end, &len,
482 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000483 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000484
485 end2 = end;
486 end = *p + len;
487 use = cur;
488
489 do
490 {
491 if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
492 return( ret );
493
494 if( *p != end )
495 {
496 use->next = (x509_name *) malloc(
497 sizeof( x509_name ) );
498
499 if( use->next == NULL )
500 return( 1 );
501
502 memset( use->next, 0, sizeof( x509_name ) );
503
504 use = use->next;
505 }
506 }
507 while( *p != end );
Paul Bakker5121ce52009-01-03 21:22:43 +0000508
509 /*
510 * recurse until end of SEQUENCE is reached
511 */
512 if( *p == end2 )
513 return( 0 );
514
515 cur->next = (x509_name *) malloc(
516 sizeof( x509_name ) );
517
518 if( cur->next == NULL )
519 return( 1 );
520
521 return( x509_get_name( p, end2, cur->next ) );
522}
523
524/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000525 * Time ::= CHOICE {
526 * utcTime UTCTime,
527 * generalTime GeneralizedTime }
528 */
Paul Bakker91200182010-02-18 21:26:15 +0000529static int x509_get_time( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000530 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000531 x509_time *time )
532{
Paul Bakker23986e52011-04-24 08:57:21 +0000533 int ret;
534 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000535 char date[64];
Paul Bakker91200182010-02-18 21:26:15 +0000536 unsigned char tag;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000537
Paul Bakker91200182010-02-18 21:26:15 +0000538 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000539 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
540 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000541
Paul Bakker91200182010-02-18 21:26:15 +0000542 tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000543
Paul Bakker91200182010-02-18 21:26:15 +0000544 if ( tag == ASN1_UTC_TIME )
545 {
546 (*p)++;
547 ret = asn1_get_len( p, end, &len );
548
549 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000550 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000551
Paul Bakker91200182010-02-18 21:26:15 +0000552 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000553 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
554 len : sizeof( date ) - 1 );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000555
Paul Bakker91200182010-02-18 21:26:15 +0000556 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
557 &time->year, &time->mon, &time->day,
558 &time->hour, &time->min, &time->sec ) < 5 )
559 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000560
Paul Bakker400ff6f2011-02-20 10:40:16 +0000561 time->year += 100 * ( time->year < 50 );
Paul Bakker91200182010-02-18 21:26:15 +0000562 time->year += 1900;
563
564 *p += len;
565
566 return( 0 );
567 }
568 else if ( tag == ASN1_GENERALIZED_TIME )
569 {
570 (*p)++;
571 ret = asn1_get_len( p, end, &len );
572
573 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000574 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker91200182010-02-18 21:26:15 +0000575
576 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000577 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
578 len : sizeof( date ) - 1 );
Paul Bakker91200182010-02-18 21:26:15 +0000579
580 if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
581 &time->year, &time->mon, &time->day,
582 &time->hour, &time->min, &time->sec ) < 5 )
583 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
584
585 *p += len;
586
587 return( 0 );
588 }
589 else
Paul Bakker9d781402011-05-09 16:17:09 +0000590 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000591}
592
593
594/*
595 * Validity ::= SEQUENCE {
596 * notBefore Time,
597 * notAfter Time }
598 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000599static int x509_get_dates( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000600 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000601 x509_time *from,
602 x509_time *to )
603{
Paul Bakker23986e52011-04-24 08:57:21 +0000604 int ret;
605 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000606
607 if( ( ret = asn1_get_tag( p, end, &len,
608 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000609 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000610
611 end = *p + len;
612
Paul Bakker91200182010-02-18 21:26:15 +0000613 if( ( ret = x509_get_time( p, end, from ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000614 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000615
Paul Bakker91200182010-02-18 21:26:15 +0000616 if( ( ret = x509_get_time( p, end, to ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000617 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000618
619 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000620 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker40e46942009-01-03 21:51:57 +0000621 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000622
623 return( 0 );
624}
625
626/*
627 * SubjectPublicKeyInfo ::= SEQUENCE {
628 * algorithm AlgorithmIdentifier,
629 * subjectPublicKey BIT STRING }
630 */
631static int x509_get_pubkey( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000632 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000633 x509_buf *pk_alg_oid,
634 mpi *N, mpi *E )
635{
Paul Bakker23986e52011-04-24 08:57:21 +0000636 int ret, can_handle;
637 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000638 unsigned char *end2;
639
640 if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 )
641 return( ret );
642
643 /*
644 * only RSA public keys handled at this time
645 */
Paul Bakker400ff6f2011-02-20 10:40:16 +0000646 can_handle = 0;
647
648 if( pk_alg_oid->len == 9 &&
649 memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) == 0 )
650 can_handle = 1;
651
652 if( pk_alg_oid->len == 9 &&
653 memcmp( pk_alg_oid->p, OID_PKCS1, 8 ) == 0 )
654 {
655 if( pk_alg_oid->p[8] >= 2 && pk_alg_oid->p[8] <= 5 )
656 can_handle = 1;
657
658 if ( pk_alg_oid->p[8] >= 11 && pk_alg_oid->p[8] <= 14 )
659 can_handle = 1;
660 }
661
662 if( pk_alg_oid->len == 5 &&
663 memcmp( pk_alg_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
664 can_handle = 1;
665
666 if( can_handle == 0 )
Paul Bakkered56b222011-07-13 11:26:43 +0000667 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000668
669 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000670 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000671
672 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000673 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000674 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000675
676 end2 = *p + len;
677
678 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000679 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000680
681 /*
682 * RSAPublicKey ::= SEQUENCE {
683 * modulus INTEGER, -- n
684 * publicExponent INTEGER -- e
685 * }
686 */
687 if( ( ret = asn1_get_tag( p, end2, &len,
688 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000689 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000690
691 if( *p + len != end2 )
Paul Bakker9d781402011-05-09 16:17:09 +0000692 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000693 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000694
695 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
696 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000697 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000698
699 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000700 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000701 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000702
703 return( 0 );
704}
705
706static int x509_get_sig( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000707 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000708 x509_buf *sig )
709{
Paul Bakker23986e52011-04-24 08:57:21 +0000710 int ret;
711 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000712
713 sig->tag = **p;
714
715 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000716 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000717
Paul Bakker74111d32011-01-15 16:57:55 +0000718
Paul Bakker5121ce52009-01-03 21:22:43 +0000719 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000720 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000721
722 sig->len = len;
723 sig->p = *p;
724
725 *p += len;
726
727 return( 0 );
728}
729
730/*
731 * X.509 v2/v3 unique identifier (not parsed)
732 */
733static int x509_get_uid( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000734 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000735 x509_buf *uid, int n )
736{
737 int ret;
738
739 if( *p == end )
740 return( 0 );
741
742 uid->tag = **p;
743
744 if( ( ret = asn1_get_tag( p, end, &uid->len,
745 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
746 {
Paul Bakker40e46942009-01-03 21:51:57 +0000747 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000748 return( 0 );
749
750 return( ret );
751 }
752
753 uid->p = *p;
754 *p += uid->len;
755
756 return( 0 );
757}
758
759/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000760 * X.509 Extensions (No parsing of extensions, pointer should
761 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000762 */
763static int x509_get_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000764 const unsigned char *end,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000765 x509_buf *ext, int tag )
Paul Bakker5121ce52009-01-03 21:22:43 +0000766{
Paul Bakker23986e52011-04-24 08:57:21 +0000767 int ret;
768 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000769
770 if( *p == end )
771 return( 0 );
772
773 ext->tag = **p;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000774
Paul Bakker5121ce52009-01-03 21:22:43 +0000775 if( ( ret = asn1_get_tag( p, end, &ext->len,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000776 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000777 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000778
779 ext->p = *p;
780 end = *p + ext->len;
781
782 /*
783 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
784 *
785 * Extension ::= SEQUENCE {
786 * extnID OBJECT IDENTIFIER,
787 * critical BOOLEAN DEFAULT FALSE,
788 * extnValue OCTET STRING }
789 */
790 if( ( ret = asn1_get_tag( p, end, &len,
791 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000792 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000793
794 if( end != *p + len )
Paul Bakker9d781402011-05-09 16:17:09 +0000795 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +0000796 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000797
Paul Bakkerd98030e2009-05-02 15:13:40 +0000798 return( 0 );
799}
800
801/*
802 * X.509 CRL v2 extensions (no extensions parsed yet.)
803 */
804static int x509_get_crl_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000805 const unsigned char *end,
806 x509_buf *ext )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000807{
Paul Bakker23986e52011-04-24 08:57:21 +0000808 int ret;
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000809 size_t len = 0;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000810
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000811 /* Get explicit tag */
812 if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000813 {
814 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
815 return( 0 );
816
817 return( ret );
818 }
819
820 while( *p < end )
821 {
822 if( ( ret = asn1_get_tag( p, end, &len,
823 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000824 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000825
826 *p += len;
827 }
828
829 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000830 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerd98030e2009-05-02 15:13:40 +0000831 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
832
833 return( 0 );
834}
835
Paul Bakkerb5a11ab2011-10-12 09:58:41 +0000836/*
837 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
838 */
839static int x509_get_crl_entry_ext( unsigned char **p,
840 const unsigned char *end,
841 x509_buf *ext )
842{
843 int ret;
844 size_t len = 0;
845
846 /* OPTIONAL */
847 if (end <= *p)
848 return( 0 );
849
850 ext->tag = **p;
851 ext->p = *p;
852
853 /*
854 * Get CRL-entry extension sequence header
855 * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
856 */
857 if( ( ret = asn1_get_tag( p, end, &ext->len,
858 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
859 {
860 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
861 {
862 ext->p = NULL;
863 return( 0 );
864 }
865 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
866 }
867
868 end = *p + ext->len;
869
870 if( end != *p + ext->len )
871 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
872 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
873
874 while( *p < end )
875 {
876 if( ( ret = asn1_get_tag( p, end, &len,
877 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
878 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
879
880 *p += len;
881 }
882
883 if( *p != end )
884 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
885 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
886
887 return( 0 );
888}
889
Paul Bakker74111d32011-01-15 16:57:55 +0000890static int x509_get_basic_constraints( unsigned char **p,
891 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000892 int *ca_istrue,
893 int *max_pathlen )
894{
Paul Bakker23986e52011-04-24 08:57:21 +0000895 int ret;
896 size_t len;
Paul Bakker74111d32011-01-15 16:57:55 +0000897
898 /*
899 * BasicConstraints ::= SEQUENCE {
900 * cA BOOLEAN DEFAULT FALSE,
901 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
902 */
Paul Bakker3cccddb2011-01-16 21:46:31 +0000903 *ca_istrue = 0; /* DEFAULT FALSE */
Paul Bakker74111d32011-01-15 16:57:55 +0000904 *max_pathlen = 0; /* endless */
905
906 if( ( ret = asn1_get_tag( p, end, &len,
907 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000908 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000909
910 if( *p == end )
911 return 0;
912
Paul Bakker3cccddb2011-01-16 21:46:31 +0000913 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000914 {
915 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker3cccddb2011-01-16 21:46:31 +0000916 ret = asn1_get_int( p, end, ca_istrue );
Paul Bakker74111d32011-01-15 16:57:55 +0000917
918 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000919 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000920
Paul Bakker3cccddb2011-01-16 21:46:31 +0000921 if( *ca_istrue != 0 )
922 *ca_istrue = 1;
Paul Bakker74111d32011-01-15 16:57:55 +0000923 }
924
925 if( *p == end )
926 return 0;
927
928 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000929 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000930
931 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000932 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000933 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
934
935 (*max_pathlen)++;
936
Paul Bakker74111d32011-01-15 16:57:55 +0000937 return 0;
938}
939
940static int x509_get_ns_cert_type( unsigned char **p,
941 const unsigned char *end,
942 unsigned char *ns_cert_type)
943{
944 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000945 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000946
947 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000948 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000949
950 if( bs.len != 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000951 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000952 POLARSSL_ERR_ASN1_INVALID_LENGTH );
953
954 /* Get actual bitstring */
955 *ns_cert_type = *bs.p;
956 return 0;
957}
958
959static int x509_get_key_usage( unsigned char **p,
960 const unsigned char *end,
961 unsigned char *key_usage)
962{
963 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000964 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000965
966 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000967 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000968
969 if( bs.len != 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000970 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000971 POLARSSL_ERR_ASN1_INVALID_LENGTH );
972
973 /* Get actual bitstring */
974 *key_usage = *bs.p;
975 return 0;
976}
977
Paul Bakkerd98030e2009-05-02 15:13:40 +0000978/*
Paul Bakker74111d32011-01-15 16:57:55 +0000979 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
980 *
981 * KeyPurposeId ::= OBJECT IDENTIFIER
982 */
983static int x509_get_ext_key_usage( unsigned char **p,
984 const unsigned char *end,
985 x509_sequence *ext_key_usage)
986{
987 int ret;
988
989 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000990 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000991
992 /* Sequence length must be >= 1 */
993 if( ext_key_usage->buf.p == NULL )
Paul Bakker9d781402011-05-09 16:17:09 +0000994 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000995 POLARSSL_ERR_ASN1_INVALID_LENGTH );
996
997 return 0;
998}
999
1000/*
1001 * X.509 v3 extensions
1002 *
1003 * TODO: Perform all of the basic constraints tests required by the RFC
1004 * TODO: Set values for undetected extensions to a sane default?
1005 *
Paul Bakkerd98030e2009-05-02 15:13:40 +00001006 */
1007static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001008 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +00001009 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001010{
Paul Bakker23986e52011-04-24 08:57:21 +00001011 int ret;
1012 size_t len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001013 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001014
Paul Bakkerfbc09f32011-10-12 09:56:41 +00001015 if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001016 {
1017 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
1018 return( 0 );
1019
1020 return( ret );
1021 }
1022
Paul Bakker5121ce52009-01-03 21:22:43 +00001023 while( *p < end )
1024 {
Paul Bakker74111d32011-01-15 16:57:55 +00001025 /*
1026 * Extension ::= SEQUENCE {
1027 * extnID OBJECT IDENTIFIER,
1028 * critical BOOLEAN DEFAULT FALSE,
1029 * extnValue OCTET STRING }
1030 */
1031 x509_buf extn_oid = {0, 0, NULL};
1032 int is_critical = 0; /* DEFAULT FALSE */
1033
Paul Bakker5121ce52009-01-03 21:22:43 +00001034 if( ( ret = asn1_get_tag( p, end, &len,
1035 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +00001036 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001037
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001038 end_ext_data = *p + len;
1039
Paul Bakker74111d32011-01-15 16:57:55 +00001040 /* Get extension ID */
1041 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +00001042
Paul Bakker74111d32011-01-15 16:57:55 +00001043 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +00001044 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001045
Paul Bakker74111d32011-01-15 16:57:55 +00001046 extn_oid.p = *p;
1047 *p += extn_oid.len;
1048
1049 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +00001050 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +00001051 POLARSSL_ERR_ASN1_OUT_OF_DATA );
1052
1053 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001054 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +00001055 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
Paul Bakker9d781402011-05-09 16:17:09 +00001056 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001057
Paul Bakker74111d32011-01-15 16:57:55 +00001058 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001059 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +00001060 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +00001061 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001062
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001063 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +00001064
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001065 if( end_ext_octet != end_ext_data )
Paul Bakker9d781402011-05-09 16:17:09 +00001066 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001067 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001068
Paul Bakker74111d32011-01-15 16:57:55 +00001069 /*
1070 * Detect supported extensions
1071 */
1072 if( ( OID_SIZE( OID_BASIC_CONSTRAINTS ) == extn_oid.len ) &&
1073 memcmp( extn_oid.p, OID_BASIC_CONSTRAINTS, extn_oid.len ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001074 {
Paul Bakker74111d32011-01-15 16:57:55 +00001075 /* Parse basic constraints */
1076 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
Paul Bakker3cccddb2011-01-16 21:46:31 +00001077 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +00001078 return ( ret );
1079 crt->ext_types |= EXT_BASIC_CONSTRAINTS;
Paul Bakker5121ce52009-01-03 21:22:43 +00001080 }
Paul Bakker74111d32011-01-15 16:57:55 +00001081 else if( ( OID_SIZE( OID_NS_CERT_TYPE ) == extn_oid.len ) &&
1082 memcmp( extn_oid.p, OID_NS_CERT_TYPE, extn_oid.len ) == 0 )
1083 {
1084 /* Parse netscape certificate type */
1085 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
1086 &crt->ns_cert_type ) ) != 0 )
1087 return ( ret );
1088 crt->ext_types |= EXT_NS_CERT_TYPE;
1089 }
1090 else if( ( OID_SIZE( OID_KEY_USAGE ) == extn_oid.len ) &&
1091 memcmp( extn_oid.p, OID_KEY_USAGE, extn_oid.len ) == 0 )
1092 {
1093 /* Parse key usage */
1094 if( ( ret = x509_get_key_usage( p, end_ext_octet,
1095 &crt->key_usage ) ) != 0 )
1096 return ( ret );
1097 crt->ext_types |= EXT_KEY_USAGE;
1098 }
1099 else if( ( OID_SIZE( OID_EXTENDED_KEY_USAGE ) == extn_oid.len ) &&
1100 memcmp( extn_oid.p, OID_EXTENDED_KEY_USAGE, extn_oid.len ) == 0 )
1101 {
1102 /* Parse extended key usage */
1103 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
1104 &crt->ext_key_usage ) ) != 0 )
1105 return ( ret );
1106 crt->ext_types |= EXT_EXTENDED_KEY_USAGE;
1107 }
1108 else
1109 {
1110 /* No parser found, skip extension */
1111 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +00001112
Paul Bakker5c721f92011-07-27 16:51:09 +00001113#if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
Paul Bakker74111d32011-01-15 16:57:55 +00001114 if( is_critical )
1115 {
1116 /* Data is marked as critical: fail */
Paul Bakker9d781402011-05-09 16:17:09 +00001117 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +00001118 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
1119 }
Paul Bakker5c721f92011-07-27 16:51:09 +00001120#endif
Paul Bakker74111d32011-01-15 16:57:55 +00001121 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001122 }
1123
1124 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +00001125 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +00001126 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001127
Paul Bakker5121ce52009-01-03 21:22:43 +00001128 return( 0 );
1129}
1130
1131/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001132 * X.509 CRL Entries
1133 */
1134static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001135 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001136 x509_crl_entry *entry )
1137{
Paul Bakker23986e52011-04-24 08:57:21 +00001138 int ret;
1139 size_t entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001140 x509_crl_entry *cur_entry = entry;
1141
1142 if( *p == end )
1143 return( 0 );
1144
Paul Bakker9be19372009-07-27 20:21:53 +00001145 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001146 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1147 {
1148 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
1149 return( 0 );
1150
1151 return( ret );
1152 }
1153
Paul Bakker9be19372009-07-27 20:21:53 +00001154 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001155
1156 while( *p < end )
1157 {
Paul Bakker23986e52011-04-24 08:57:21 +00001158 size_t len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001159 const unsigned char *end2;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001160
1161 if( ( ret = asn1_get_tag( p, end, &len2,
1162 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1163 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001164 return( ret );
1165 }
1166
Paul Bakker9be19372009-07-27 20:21:53 +00001167 cur_entry->raw.tag = **p;
1168 cur_entry->raw.p = *p;
1169 cur_entry->raw.len = len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001170 end2 = *p + len2;
Paul Bakker9be19372009-07-27 20:21:53 +00001171
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001172 if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001173 return( ret );
1174
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001175 if( ( ret = x509_get_time( p, end2, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001176 return( ret );
1177
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001178 if( ( ret = x509_get_crl_entry_ext( p, end2, &cur_entry->entry_ext ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001179 return( ret );
1180
Paul Bakker74111d32011-01-15 16:57:55 +00001181 if ( *p < end )
1182 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001183 cur_entry->next = malloc( sizeof( x509_crl_entry ) );
1184 cur_entry = cur_entry->next;
1185 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
1186 }
1187 }
1188
1189 return( 0 );
1190}
1191
Paul Bakker27d66162010-03-17 06:56:01 +00001192static int x509_get_sig_alg( const x509_buf *sig_oid, int *sig_alg )
1193{
1194 if( sig_oid->len == 9 &&
1195 memcmp( sig_oid->p, OID_PKCS1, 8 ) == 0 )
1196 {
1197 if( sig_oid->p[8] >= 2 && sig_oid->p[8] <= 5 )
1198 {
1199 *sig_alg = sig_oid->p[8];
1200 return( 0 );
1201 }
1202
1203 if ( sig_oid->p[8] >= 11 && sig_oid->p[8] <= 14 )
1204 {
1205 *sig_alg = sig_oid->p[8];
1206 return( 0 );
1207 }
1208
1209 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1210 }
Paul Bakker400ff6f2011-02-20 10:40:16 +00001211 if( sig_oid->len == 5 &&
1212 memcmp( sig_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
1213 {
1214 *sig_alg = SIG_RSA_SHA1;
1215 return( 0 );
1216 }
Paul Bakker27d66162010-03-17 06:56:01 +00001217
1218 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1219}
1220
Paul Bakkerd98030e2009-05-02 15:13:40 +00001221/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001222 * Parse one or more certificates and add them to the chained list
1223 */
Paul Bakker23986e52011-04-24 08:57:21 +00001224int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001225{
Paul Bakker23986e52011-04-24 08:57:21 +00001226 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001227 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00001228 unsigned char *p, *end;
1229 x509_cert *crt;
Paul Bakker96743fc2011-02-12 14:30:57 +00001230#if defined(POLARSSL_PEM_C)
1231 pem_context pem;
Paul Bakker5690efc2011-05-26 13:16:06 +00001232 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001233#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001234
1235 crt = chain;
1236
Paul Bakker320a4b52009-03-28 18:52:39 +00001237 /*
1238 * Check for valid input
1239 */
1240 if( crt == NULL || buf == NULL )
1241 return( 1 );
1242
Paul Bakkere9581d62009-03-28 20:29:25 +00001243 while( crt->version != 0 && crt->next != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00001244 crt = crt->next;
1245
1246 /*
Paul Bakker320a4b52009-03-28 18:52:39 +00001247 * Add new certificate on the end of the chain if needed.
1248 */
Paul Bakkere9581d62009-03-28 20:29:25 +00001249 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001250 {
1251 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1252
Paul Bakker7d06ad22009-05-02 15:53:56 +00001253 if( crt->next == NULL )
1254 {
Paul Bakker320a4b52009-03-28 18:52:39 +00001255 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001256 return( 1 );
1257 }
Paul Bakker320a4b52009-03-28 18:52:39 +00001258
Paul Bakker7d06ad22009-05-02 15:53:56 +00001259 crt = crt->next;
1260 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001261 }
1262
Paul Bakker96743fc2011-02-12 14:30:57 +00001263#if defined(POLARSSL_PEM_C)
1264 pem_init( &pem );
1265 ret = pem_read_buffer( &pem,
1266 "-----BEGIN CERTIFICATE-----",
1267 "-----END CERTIFICATE-----",
1268 buf, NULL, 0, &use_len );
Paul Bakker5121ce52009-01-03 21:22:43 +00001269
Paul Bakker96743fc2011-02-12 14:30:57 +00001270 if( ret == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001271 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001272 /*
1273 * Was PEM encoded
1274 */
1275 buflen -= use_len;
1276 buf += use_len;
Paul Bakker5121ce52009-01-03 21:22:43 +00001277
1278 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001279 * Steal PEM buffer
Paul Bakker5121ce52009-01-03 21:22:43 +00001280 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001281 p = pem.buf;
1282 pem.buf = NULL;
1283 len = pem.buflen;
1284 pem_free( &pem );
1285 }
1286 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
1287 {
1288 pem_free( &pem );
1289 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001290 }
1291 else
1292 {
1293 /*
1294 * nope, copy the raw DER data
1295 */
1296 p = (unsigned char *) malloc( len = buflen );
1297
1298 if( p == NULL )
1299 return( 1 );
1300
1301 memcpy( p, buf, buflen );
1302
1303 buflen = 0;
1304 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001305#else
1306 p = (unsigned char *) malloc( len = buflen );
1307
1308 if( p == NULL )
1309 return( 1 );
1310
1311 memcpy( p, buf, buflen );
1312
1313 buflen = 0;
1314#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001315
1316 crt->raw.p = p;
1317 crt->raw.len = len;
1318 end = p + len;
1319
1320 /*
1321 * Certificate ::= SEQUENCE {
1322 * tbsCertificate TBSCertificate,
1323 * signatureAlgorithm AlgorithmIdentifier,
1324 * signatureValue BIT STRING }
1325 */
1326 if( ( ret = asn1_get_tag( &p, end, &len,
1327 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1328 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001329 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001330 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001331 }
1332
Paul Bakker23986e52011-04-24 08:57:21 +00001333 if( len != (size_t) ( end - p ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001334 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001335 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001336 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001337 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001338 }
1339
1340 /*
1341 * TBSCertificate ::= SEQUENCE {
1342 */
1343 crt->tbs.p = p;
1344
1345 if( ( ret = asn1_get_tag( &p, end, &len,
1346 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1347 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001348 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001349 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001350 }
1351
1352 end = p + len;
1353 crt->tbs.len = end - crt->tbs.p;
1354
1355 /*
1356 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1357 *
1358 * CertificateSerialNumber ::= INTEGER
1359 *
1360 * signature AlgorithmIdentifier
1361 */
1362 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1363 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1364 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
1365 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001366 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001367 return( ret );
1368 }
1369
1370 crt->version++;
1371
1372 if( crt->version > 3 )
1373 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001374 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001375 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001376 }
1377
Paul Bakker27d66162010-03-17 06:56:01 +00001378 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_alg ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001379 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001380 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001381 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001382 }
1383
1384 /*
1385 * issuer Name
1386 */
1387 crt->issuer_raw.p = p;
1388
1389 if( ( ret = asn1_get_tag( &p, end, &len,
1390 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1391 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001392 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001393 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001394 }
1395
1396 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1397 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001398 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001399 return( ret );
1400 }
1401
1402 crt->issuer_raw.len = p - crt->issuer_raw.p;
1403
1404 /*
1405 * Validity ::= SEQUENCE {
1406 * notBefore Time,
1407 * notAfter Time }
1408 *
1409 */
1410 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1411 &crt->valid_to ) ) != 0 )
1412 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001413 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001414 return( ret );
1415 }
1416
1417 /*
1418 * subject Name
1419 */
1420 crt->subject_raw.p = p;
1421
1422 if( ( ret = asn1_get_tag( &p, end, &len,
1423 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1424 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001425 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001426 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001427 }
1428
1429 if( ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
1430 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001431 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001432 return( ret );
1433 }
1434
1435 crt->subject_raw.len = p - crt->subject_raw.p;
1436
1437 /*
1438 * SubjectPublicKeyInfo ::= SEQUENCE
1439 * algorithm AlgorithmIdentifier,
1440 * subjectPublicKey BIT STRING }
1441 */
1442 if( ( ret = asn1_get_tag( &p, end, &len,
1443 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1444 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001445 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001446 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001447 }
1448
1449 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1450 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1451 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001452 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001453 return( ret );
1454 }
1455
1456 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1457 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001458 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001459 return( ret );
1460 }
1461
1462 crt->rsa.len = mpi_size( &crt->rsa.N );
1463
1464 /*
1465 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1466 * -- If present, version shall be v2 or v3
1467 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1468 * -- If present, version shall be v2 or v3
1469 * extensions [3] EXPLICIT Extensions OPTIONAL
1470 * -- If present, version shall be v3
1471 */
1472 if( crt->version == 2 || crt->version == 3 )
1473 {
1474 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1475 if( ret != 0 )
1476 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001477 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001478 return( ret );
1479 }
1480 }
1481
1482 if( crt->version == 2 || crt->version == 3 )
1483 {
1484 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1485 if( ret != 0 )
1486 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001487 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001488 return( ret );
1489 }
1490 }
1491
1492 if( crt->version == 3 )
1493 {
Paul Bakker74111d32011-01-15 16:57:55 +00001494 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001495 if( ret != 0 )
1496 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001497 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001498 return( ret );
1499 }
1500 }
1501
1502 if( p != end )
1503 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001504 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001505 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001506 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001507 }
1508
1509 end = crt->raw.p + crt->raw.len;
1510
1511 /*
1512 * signatureAlgorithm AlgorithmIdentifier,
1513 * signatureValue BIT STRING
1514 */
1515 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1516 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001517 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001518 return( ret );
1519 }
1520
Paul Bakker320a4b52009-03-28 18:52:39 +00001521 if( memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001522 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001523 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001524 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001525 }
1526
1527 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1528 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001529 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001530 return( ret );
1531 }
1532
1533 if( p != end )
1534 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001535 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001536 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001537 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001538 }
1539
Paul Bakker5121ce52009-01-03 21:22:43 +00001540 if( buflen > 0 )
Paul Bakker320a4b52009-03-28 18:52:39 +00001541 {
1542 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1543
Paul Bakker7d06ad22009-05-02 15:53:56 +00001544 if( crt->next == NULL )
1545 {
Paul Bakker320a4b52009-03-28 18:52:39 +00001546 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001547 return( 1 );
1548 }
Paul Bakker320a4b52009-03-28 18:52:39 +00001549
Paul Bakker7d06ad22009-05-02 15:53:56 +00001550 crt = crt->next;
1551 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001552
Paul Bakker5121ce52009-01-03 21:22:43 +00001553 return( x509parse_crt( crt, buf, buflen ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001554 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001555
1556 return( 0 );
1557}
1558
1559/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001560 * Parse one or more CRLs and add them to the chained list
1561 */
Paul Bakker23986e52011-04-24 08:57:21 +00001562int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001563{
Paul Bakker23986e52011-04-24 08:57:21 +00001564 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001565 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001566 unsigned char *p, *end;
1567 x509_crl *crl;
Paul Bakker96743fc2011-02-12 14:30:57 +00001568#if defined(POLARSSL_PEM_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00001569 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001570 pem_context pem;
1571#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001572
1573 crl = chain;
1574
1575 /*
1576 * Check for valid input
1577 */
1578 if( crl == NULL || buf == NULL )
1579 return( 1 );
1580
1581 while( crl->version != 0 && crl->next != NULL )
1582 crl = crl->next;
1583
1584 /*
1585 * Add new CRL on the end of the chain if needed.
1586 */
1587 if ( crl->version != 0 && crl->next == NULL)
1588 {
1589 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1590
Paul Bakker7d06ad22009-05-02 15:53:56 +00001591 if( crl->next == NULL )
1592 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001593 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001594 return( 1 );
1595 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001596
Paul Bakker7d06ad22009-05-02 15:53:56 +00001597 crl = crl->next;
1598 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001599 }
1600
Paul Bakker96743fc2011-02-12 14:30:57 +00001601#if defined(POLARSSL_PEM_C)
1602 pem_init( &pem );
1603 ret = pem_read_buffer( &pem,
1604 "-----BEGIN X509 CRL-----",
1605 "-----END X509 CRL-----",
1606 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001607
Paul Bakker96743fc2011-02-12 14:30:57 +00001608 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001609 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001610 /*
1611 * Was PEM encoded
1612 */
1613 buflen -= use_len;
1614 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001615
1616 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001617 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001618 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001619 p = pem.buf;
1620 pem.buf = NULL;
1621 len = pem.buflen;
1622 pem_free( &pem );
1623 }
1624 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
1625 {
1626 pem_free( &pem );
1627 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001628 }
1629 else
1630 {
1631 /*
1632 * nope, copy the raw DER data
1633 */
1634 p = (unsigned char *) malloc( len = buflen );
1635
1636 if( p == NULL )
1637 return( 1 );
1638
1639 memcpy( p, buf, buflen );
1640
1641 buflen = 0;
1642 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001643#else
1644 p = (unsigned char *) malloc( len = buflen );
1645
1646 if( p == NULL )
1647 return( 1 );
1648
1649 memcpy( p, buf, buflen );
1650
1651 buflen = 0;
1652#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001653
1654 crl->raw.p = p;
1655 crl->raw.len = len;
1656 end = p + len;
1657
1658 /*
1659 * CertificateList ::= SEQUENCE {
1660 * tbsCertList TBSCertList,
1661 * signatureAlgorithm AlgorithmIdentifier,
1662 * signatureValue BIT STRING }
1663 */
1664 if( ( ret = asn1_get_tag( &p, end, &len,
1665 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1666 {
1667 x509_crl_free( crl );
1668 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1669 }
1670
Paul Bakker23986e52011-04-24 08:57:21 +00001671 if( len != (size_t) ( end - p ) )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001672 {
1673 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001674 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001675 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1676 }
1677
1678 /*
1679 * TBSCertList ::= SEQUENCE {
1680 */
1681 crl->tbs.p = p;
1682
1683 if( ( ret = asn1_get_tag( &p, end, &len,
1684 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1685 {
1686 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001687 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001688 }
1689
1690 end = p + len;
1691 crl->tbs.len = end - crl->tbs.p;
1692
1693 /*
1694 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1695 * -- if present, MUST be v2
1696 *
1697 * signature AlgorithmIdentifier
1698 */
Paul Bakker3329d1f2011-10-12 09:55:01 +00001699 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
Paul Bakkerd98030e2009-05-02 15:13:40 +00001700 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1701 {
1702 x509_crl_free( crl );
1703 return( ret );
1704 }
1705
1706 crl->version++;
1707
1708 if( crl->version > 2 )
1709 {
1710 x509_crl_free( crl );
1711 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1712 }
1713
Paul Bakker27d66162010-03-17 06:56:01 +00001714 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_alg ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001715 {
1716 x509_crl_free( crl );
1717 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1718 }
1719
1720 /*
1721 * issuer Name
1722 */
1723 crl->issuer_raw.p = p;
1724
1725 if( ( ret = asn1_get_tag( &p, end, &len,
1726 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1727 {
1728 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001729 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001730 }
1731
1732 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1733 {
1734 x509_crl_free( crl );
1735 return( ret );
1736 }
1737
1738 crl->issuer_raw.len = p - crl->issuer_raw.p;
1739
1740 /*
1741 * thisUpdate Time
1742 * nextUpdate Time OPTIONAL
1743 */
Paul Bakker91200182010-02-18 21:26:15 +00001744 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001745 {
1746 x509_crl_free( crl );
1747 return( ret );
1748 }
1749
Paul Bakker91200182010-02-18 21:26:15 +00001750 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001751 {
Paul Bakker9d781402011-05-09 16:17:09 +00001752 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001753 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker9d781402011-05-09 16:17:09 +00001754 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001755 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001756 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001757 x509_crl_free( crl );
1758 return( ret );
1759 }
1760 }
1761
1762 /*
1763 * revokedCertificates SEQUENCE OF SEQUENCE {
1764 * userCertificate CertificateSerialNumber,
1765 * revocationDate Time,
1766 * crlEntryExtensions Extensions OPTIONAL
1767 * -- if present, MUST be v2
1768 * } OPTIONAL
1769 */
1770 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1771 {
1772 x509_crl_free( crl );
1773 return( ret );
1774 }
1775
1776 /*
1777 * crlExtensions EXPLICIT Extensions OPTIONAL
1778 * -- if present, MUST be v2
1779 */
1780 if( crl->version == 2 )
1781 {
1782 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1783
1784 if( ret != 0 )
1785 {
1786 x509_crl_free( crl );
1787 return( ret );
1788 }
1789 }
1790
1791 if( p != end )
1792 {
1793 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001794 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001795 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1796 }
1797
1798 end = crl->raw.p + crl->raw.len;
1799
1800 /*
1801 * signatureAlgorithm AlgorithmIdentifier,
1802 * signatureValue BIT STRING
1803 */
1804 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1805 {
1806 x509_crl_free( crl );
1807 return( ret );
1808 }
1809
1810 if( memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
1811 {
1812 x509_crl_free( crl );
1813 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1814 }
1815
1816 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1817 {
1818 x509_crl_free( crl );
1819 return( ret );
1820 }
1821
1822 if( p != end )
1823 {
1824 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001825 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001826 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1827 }
1828
1829 if( buflen > 0 )
1830 {
1831 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1832
Paul Bakker7d06ad22009-05-02 15:53:56 +00001833 if( crl->next == NULL )
1834 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001835 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001836 return( 1 );
1837 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001838
Paul Bakker7d06ad22009-05-02 15:53:56 +00001839 crl = crl->next;
1840 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001841
1842 return( x509parse_crl( crl, buf, buflen ) );
1843 }
1844
1845 return( 0 );
1846}
1847
Paul Bakker335db3f2011-04-25 15:28:35 +00001848#if defined(POLARSSL_FS_IO)
Paul Bakkerd98030e2009-05-02 15:13:40 +00001849/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001850 * Load all data from a file into a given buffer.
1851 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001852int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001853{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001854 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001855
Paul Bakkerd98030e2009-05-02 15:13:40 +00001856 if( ( f = fopen( path, "rb" ) ) == NULL )
1857 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001858
Paul Bakkerd98030e2009-05-02 15:13:40 +00001859 fseek( f, 0, SEEK_END );
1860 *n = (size_t) ftell( f );
1861 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001862
Paul Bakkerd98030e2009-05-02 15:13:40 +00001863 if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
1864 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001865
Paul Bakkerd98030e2009-05-02 15:13:40 +00001866 if( fread( *buf, 1, *n, f ) != *n )
1867 {
1868 fclose( f );
1869 free( *buf );
1870 return( 1 );
1871 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001872
Paul Bakkerd98030e2009-05-02 15:13:40 +00001873 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001874
Paul Bakkerd98030e2009-05-02 15:13:40 +00001875 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001876
Paul Bakkerd98030e2009-05-02 15:13:40 +00001877 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001878}
1879
1880/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001881 * Load one or more certificates and add them to the chained list
1882 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001883int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001884{
1885 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001886 size_t n;
1887 unsigned char *buf;
1888
Paul Bakker2b245eb2009-04-19 18:44:26 +00001889 if ( load_file( path, &buf, &n ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001890 return( 1 );
1891
Paul Bakker27fdf462011-06-09 13:55:13 +00001892 ret = x509parse_crt( chain, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001893
1894 memset( buf, 0, n + 1 );
1895 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001896
1897 return( ret );
1898}
1899
Paul Bakkerd98030e2009-05-02 15:13:40 +00001900/*
1901 * Load one or more CRLs and add them to the chained list
1902 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001903int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001904{
1905 int ret;
1906 size_t n;
1907 unsigned char *buf;
1908
1909 if ( load_file( path, &buf, &n ) )
1910 return( 1 );
1911
Paul Bakker27fdf462011-06-09 13:55:13 +00001912 ret = x509parse_crl( chain, buf, n );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001913
1914 memset( buf, 0, n + 1 );
1915 free( buf );
1916
1917 return( ret );
1918}
1919
Paul Bakker5121ce52009-01-03 21:22:43 +00001920/*
Paul Bakker335db3f2011-04-25 15:28:35 +00001921 * Load and parse a private RSA key
1922 */
1923int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
1924{
1925 int ret;
1926 size_t n;
1927 unsigned char *buf;
1928
1929 if ( load_file( path, &buf, &n ) )
1930 return( 1 );
1931
1932 if( pwd == NULL )
Paul Bakker27fdf462011-06-09 13:55:13 +00001933 ret = x509parse_key( rsa, buf, n, NULL, 0 );
Paul Bakker335db3f2011-04-25 15:28:35 +00001934 else
Paul Bakker27fdf462011-06-09 13:55:13 +00001935 ret = x509parse_key( rsa, buf, n,
Paul Bakker335db3f2011-04-25 15:28:35 +00001936 (unsigned char *) pwd, strlen( pwd ) );
1937
1938 memset( buf, 0, n + 1 );
1939 free( buf );
1940
1941 return( ret );
1942}
1943
1944/*
1945 * Load and parse a public RSA key
1946 */
1947int x509parse_public_keyfile( rsa_context *rsa, const char *path )
1948{
1949 int ret;
1950 size_t n;
1951 unsigned char *buf;
1952
1953 if ( load_file( path, &buf, &n ) )
1954 return( 1 );
1955
Paul Bakker27fdf462011-06-09 13:55:13 +00001956 ret = x509parse_public_key( rsa, buf, n );
Paul Bakker335db3f2011-04-25 15:28:35 +00001957
1958 memset( buf, 0, n + 1 );
1959 free( buf );
1960
1961 return( ret );
1962}
1963#endif /* POLARSSL_FS_IO */
1964
1965/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001966 * Parse a private RSA key
1967 */
Paul Bakker23986e52011-04-24 08:57:21 +00001968int x509parse_key( rsa_context *rsa, const unsigned char *key, size_t keylen,
1969 const unsigned char *pwd, size_t pwdlen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001970{
Paul Bakker23986e52011-04-24 08:57:21 +00001971 int ret;
1972 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00001973 unsigned char *p, *end;
Paul Bakkered56b222011-07-13 11:26:43 +00001974 unsigned char *p_alt;
1975 x509_buf pk_alg_oid;
1976
Paul Bakker96743fc2011-02-12 14:30:57 +00001977#if defined(POLARSSL_PEM_C)
1978 pem_context pem;
Paul Bakker5121ce52009-01-03 21:22:43 +00001979
Paul Bakker96743fc2011-02-12 14:30:57 +00001980 pem_init( &pem );
1981 ret = pem_read_buffer( &pem,
1982 "-----BEGIN RSA PRIVATE KEY-----",
1983 "-----END RSA PRIVATE KEY-----",
1984 key, pwd, pwdlen, &len );
Paul Bakker5121ce52009-01-03 21:22:43 +00001985
Paul Bakkered56b222011-07-13 11:26:43 +00001986 if( ret == POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
1987 {
1988 ret = pem_read_buffer( &pem,
1989 "-----BEGIN PRIVATE KEY-----",
1990 "-----END PRIVATE KEY-----",
1991 key, pwd, pwdlen, &len );
1992 }
1993
Paul Bakker96743fc2011-02-12 14:30:57 +00001994 if( ret == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001995 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001996 /*
1997 * Was PEM encoded
1998 */
1999 keylen = pem.buflen;
Paul Bakker5121ce52009-01-03 21:22:43 +00002000 }
Paul Bakker96743fc2011-02-12 14:30:57 +00002001 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
Paul Bakkerff60ee62010-03-16 21:09:09 +00002002 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002003 pem_free( &pem );
2004 return( ret );
Paul Bakkerff60ee62010-03-16 21:09:09 +00002005 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002006
Paul Bakker96743fc2011-02-12 14:30:57 +00002007 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2008#else
Paul Bakker5690efc2011-05-26 13:16:06 +00002009 ((void) pwd);
2010 ((void) pwdlen);
Paul Bakker96743fc2011-02-12 14:30:57 +00002011 p = (unsigned char *) key;
2012#endif
2013 end = p + keylen;
2014
Paul Bakker5121ce52009-01-03 21:22:43 +00002015 /*
Paul Bakkered56b222011-07-13 11:26:43 +00002016 * Note: Depending on the type of private key file one can expect either a
2017 * PrivatKeyInfo object (PKCS#8) or a RSAPrivateKey (PKCS#1) directly.
2018 *
2019 * PrivateKeyInfo ::= SEQUENCE {
Paul Bakker5c721f92011-07-27 16:51:09 +00002020 * version Version,
Paul Bakkered56b222011-07-13 11:26:43 +00002021 * algorithm AlgorithmIdentifier,
2022 * PrivateKey BIT STRING
2023 * }
2024 *
2025 * AlgorithmIdentifier ::= SEQUENCE {
2026 * algorithm OBJECT IDENTIFIER,
2027 * parameters ANY DEFINED BY algorithm OPTIONAL
2028 * }
2029 *
Paul Bakker5121ce52009-01-03 21:22:43 +00002030 * RSAPrivateKey ::= SEQUENCE {
2031 * version Version,
2032 * modulus INTEGER, -- n
2033 * publicExponent INTEGER, -- e
2034 * privateExponent INTEGER, -- d
2035 * prime1 INTEGER, -- p
2036 * prime2 INTEGER, -- q
2037 * exponent1 INTEGER, -- d mod (p-1)
2038 * exponent2 INTEGER, -- d mod (q-1)
2039 * coefficient INTEGER, -- (inverse of q) mod p
2040 * otherPrimeInfos OtherPrimeInfos OPTIONAL
2041 * }
2042 */
2043 if( ( ret = asn1_get_tag( &p, end, &len,
2044 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2045 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002046#if defined(POLARSSL_PEM_C)
2047 pem_free( &pem );
2048#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002049 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002050 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002051 }
2052
2053 end = p + len;
2054
2055 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2056 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002057#if defined(POLARSSL_PEM_C)
2058 pem_free( &pem );
2059#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002060 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002061 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002062 }
2063
2064 if( rsa->ver != 0 )
2065 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002066#if defined(POLARSSL_PEM_C)
2067 pem_free( &pem );
2068#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002069 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002070 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002071 }
2072
Paul Bakkered56b222011-07-13 11:26:43 +00002073 p_alt = p;
2074
2075 if( ( ret = x509_get_alg( &p_alt, end, &pk_alg_oid ) ) != 0 )
2076 {
2077 // Assume that we have the PKCS#1 format if wrong
2078 // tag was encountered
2079 //
2080 if( ret != POLARSSL_ERR_X509_CERT_INVALID_ALG +
2081 POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
2082 {
2083#if defined(POLARSSL_PEM_C)
2084 pem_free( &pem );
2085#endif
2086 rsa_free( rsa );
2087 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
2088 }
2089 }
2090 else
2091 {
2092 int can_handle;
2093
2094 /*
2095 * only RSA keys handled at this time
2096 */
2097 can_handle = 0;
2098
2099 if( pk_alg_oid.len == 9 &&
2100 memcmp( pk_alg_oid.p, OID_PKCS1_RSA, 9 ) == 0 )
2101 can_handle = 1;
2102
2103 if( pk_alg_oid.len == 9 &&
2104 memcmp( pk_alg_oid.p, OID_PKCS1, 8 ) == 0 )
2105 {
2106 if( pk_alg_oid.p[8] >= 2 && pk_alg_oid.p[8] <= 5 )
2107 can_handle = 1;
2108
2109 if ( pk_alg_oid.p[8] >= 11 && pk_alg_oid.p[8] <= 14 )
2110 can_handle = 1;
2111 }
2112
2113 if( pk_alg_oid.len == 5 &&
2114 memcmp( pk_alg_oid.p, OID_RSA_SHA_OBS, 5 ) == 0 )
2115 can_handle = 1;
2116
2117 if( can_handle == 0 )
2118 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
2119
2120 /*
2121 * Parse the PKCS#8 format
2122 */
2123
2124 p = p_alt;
2125 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2126 {
2127#if defined(POLARSSL_PEM_C)
2128 pem_free( &pem );
2129#endif
2130 rsa_free( rsa );
2131 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2132 }
2133
2134 if( ( end - p ) < 1 )
2135 {
2136#if defined(POLARSSL_PEM_C)
2137 pem_free( &pem );
2138#endif
2139 rsa_free( rsa );
2140 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
2141 POLARSSL_ERR_ASN1_OUT_OF_DATA );
2142 }
2143
2144 end = p + len;
2145
2146 if( ( ret = asn1_get_tag( &p, end, &len,
2147 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2148 {
2149#if defined(POLARSSL_PEM_C)
2150 pem_free( &pem );
2151#endif
2152 rsa_free( rsa );
2153 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2154 }
2155
2156 end = p + len;
2157
2158 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2159 {
2160#if defined(POLARSSL_PEM_C)
2161 pem_free( &pem );
2162#endif
2163 rsa_free( rsa );
2164 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2165 }
2166
2167 if( rsa->ver != 0 )
2168 {
2169#if defined(POLARSSL_PEM_C)
2170 pem_free( &pem );
2171#endif
2172 rsa_free( rsa );
2173 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2174 }
2175 }
2176
Paul Bakker5121ce52009-01-03 21:22:43 +00002177 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
2178 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
2179 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
2180 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
2181 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
2182 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
2183 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
2184 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
2185 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002186#if defined(POLARSSL_PEM_C)
2187 pem_free( &pem );
2188#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002189 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002190 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002191 }
2192
2193 rsa->len = mpi_size( &rsa->N );
2194
2195 if( p != end )
2196 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002197#if defined(POLARSSL_PEM_C)
2198 pem_free( &pem );
2199#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002200 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002201 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00002202 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002203 }
2204
2205 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2206 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002207#if defined(POLARSSL_PEM_C)
2208 pem_free( &pem );
2209#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002210 rsa_free( rsa );
2211 return( ret );
2212 }
2213
Paul Bakker96743fc2011-02-12 14:30:57 +00002214#if defined(POLARSSL_PEM_C)
2215 pem_free( &pem );
2216#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002217
2218 return( 0 );
2219}
2220
2221/*
Paul Bakker53019ae2011-03-25 13:58:48 +00002222 * Parse a public RSA key
2223 */
Paul Bakker23986e52011-04-24 08:57:21 +00002224int x509parse_public_key( rsa_context *rsa, const unsigned char *key, size_t keylen )
Paul Bakker53019ae2011-03-25 13:58:48 +00002225{
Paul Bakker23986e52011-04-24 08:57:21 +00002226 int ret;
2227 size_t len;
Paul Bakker53019ae2011-03-25 13:58:48 +00002228 unsigned char *p, *end;
2229 x509_buf alg_oid;
2230#if defined(POLARSSL_PEM_C)
2231 pem_context pem;
2232
2233 pem_init( &pem );
2234 ret = pem_read_buffer( &pem,
2235 "-----BEGIN PUBLIC KEY-----",
2236 "-----END PUBLIC KEY-----",
2237 key, NULL, 0, &len );
2238
2239 if( ret == 0 )
2240 {
2241 /*
2242 * Was PEM encoded
2243 */
2244 keylen = pem.buflen;
2245 }
2246 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
2247 {
2248 pem_free( &pem );
2249 return( ret );
2250 }
2251
2252 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2253#else
2254 p = (unsigned char *) key;
2255#endif
2256 end = p + keylen;
2257
2258 /*
2259 * PublicKeyInfo ::= SEQUENCE {
2260 * algorithm AlgorithmIdentifier,
2261 * PublicKey BIT STRING
2262 * }
2263 *
2264 * AlgorithmIdentifier ::= SEQUENCE {
2265 * algorithm OBJECT IDENTIFIER,
2266 * parameters ANY DEFINED BY algorithm OPTIONAL
2267 * }
2268 *
2269 * RSAPublicKey ::= SEQUENCE {
2270 * modulus INTEGER, -- n
2271 * publicExponent INTEGER -- e
2272 * }
2273 */
2274
2275 if( ( ret = asn1_get_tag( &p, end, &len,
2276 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2277 {
2278#if defined(POLARSSL_PEM_C)
2279 pem_free( &pem );
2280#endif
2281 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002282 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002283 }
2284
2285 if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
2286 {
2287#if defined(POLARSSL_PEM_C)
2288 pem_free( &pem );
2289#endif
2290 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002291 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002292 }
2293
2294 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
2295 {
2296#if defined(POLARSSL_PEM_C)
2297 pem_free( &pem );
2298#endif
2299 rsa_free( rsa );
2300 return( ret );
2301 }
2302
2303 rsa->len = mpi_size( &rsa->N );
2304
2305#if defined(POLARSSL_PEM_C)
2306 pem_free( &pem );
2307#endif
2308
2309 return( 0 );
2310}
2311
Paul Bakkereaa89f82011-04-04 21:36:15 +00002312#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00002313/*
Paul Bakker1b57b062011-01-06 15:48:19 +00002314 * Parse DHM parameters
2315 */
Paul Bakker23986e52011-04-24 08:57:21 +00002316int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
Paul Bakker1b57b062011-01-06 15:48:19 +00002317{
Paul Bakker23986e52011-04-24 08:57:21 +00002318 int ret;
2319 size_t len;
Paul Bakker1b57b062011-01-06 15:48:19 +00002320 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00002321#if defined(POLARSSL_PEM_C)
2322 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00002323
Paul Bakker96743fc2011-02-12 14:30:57 +00002324 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00002325
Paul Bakker96743fc2011-02-12 14:30:57 +00002326 ret = pem_read_buffer( &pem,
2327 "-----BEGIN DH PARAMETERS-----",
2328 "-----END DH PARAMETERS-----",
2329 dhmin, NULL, 0, &dhminlen );
2330
2331 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00002332 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002333 /*
2334 * Was PEM encoded
2335 */
2336 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00002337 }
Paul Bakker96743fc2011-02-12 14:30:57 +00002338 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00002339 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002340 pem_free( &pem );
2341 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002342 }
2343
Paul Bakker96743fc2011-02-12 14:30:57 +00002344 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
2345#else
2346 p = (unsigned char *) dhmin;
2347#endif
2348 end = p + dhminlen;
2349
Paul Bakker1b57b062011-01-06 15:48:19 +00002350 memset( dhm, 0, sizeof( dhm_context ) );
2351
Paul Bakker1b57b062011-01-06 15:48:19 +00002352 /*
2353 * DHParams ::= SEQUENCE {
2354 * prime INTEGER, -- P
2355 * generator INTEGER, -- g
2356 * }
2357 */
2358 if( ( ret = asn1_get_tag( &p, end, &len,
2359 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2360 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002361#if defined(POLARSSL_PEM_C)
2362 pem_free( &pem );
2363#endif
Paul Bakker9d781402011-05-09 16:17:09 +00002364 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002365 }
2366
2367 end = p + len;
2368
2369 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
2370 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
2371 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002372#if defined(POLARSSL_PEM_C)
2373 pem_free( &pem );
2374#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002375 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002376 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002377 }
2378
2379 if( p != end )
2380 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002381#if defined(POLARSSL_PEM_C)
2382 pem_free( &pem );
2383#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002384 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002385 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker1b57b062011-01-06 15:48:19 +00002386 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
2387 }
2388
Paul Bakker96743fc2011-02-12 14:30:57 +00002389#if defined(POLARSSL_PEM_C)
2390 pem_free( &pem );
2391#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002392
2393 return( 0 );
2394}
2395
Paul Bakker335db3f2011-04-25 15:28:35 +00002396#if defined(POLARSSL_FS_IO)
Paul Bakker1b57b062011-01-06 15:48:19 +00002397/*
2398 * Load and parse a private RSA key
2399 */
2400int x509parse_dhmfile( dhm_context *dhm, const char *path )
2401{
2402 int ret;
2403 size_t n;
2404 unsigned char *buf;
2405
2406 if ( load_file( path, &buf, &n ) )
2407 return( 1 );
2408
Paul Bakker27fdf462011-06-09 13:55:13 +00002409 ret = x509parse_dhm( dhm, buf, n );
Paul Bakker1b57b062011-01-06 15:48:19 +00002410
2411 memset( buf, 0, n + 1 );
2412 free( buf );
2413
2414 return( ret );
2415}
Paul Bakker335db3f2011-04-25 15:28:35 +00002416#endif /* POLARSSL_FS_IO */
Paul Bakkereaa89f82011-04-04 21:36:15 +00002417#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00002418
Paul Bakker5121ce52009-01-03 21:22:43 +00002419#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002420#include <stdarg.h>
2421
2422#if !defined vsnprintf
2423#define vsnprintf _vsnprintf
2424#endif // vsnprintf
2425
2426/*
2427 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2428 * Result value is not size of buffer needed, but -1 if no fit is possible.
2429 *
2430 * This fuction tries to 'fix' this by at least suggesting enlarging the
2431 * size by 20.
2432 */
2433int compat_snprintf(char *str, size_t size, const char *format, ...)
2434{
2435 va_list ap;
2436 int res = -1;
2437
2438 va_start( ap, format );
2439
2440 res = vsnprintf( str, size, format, ap );
2441
2442 va_end( ap );
2443
2444 // No quick fix possible
2445 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00002446 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002447
2448 return res;
2449}
2450
2451#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002452#endif
2453
Paul Bakkerd98030e2009-05-02 15:13:40 +00002454#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2455
2456#define SAFE_SNPRINTF() \
2457{ \
2458 if( ret == -1 ) \
2459 return( -1 ); \
2460 \
Paul Bakker23986e52011-04-24 08:57:21 +00002461 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002462 p[n - 1] = '\0'; \
2463 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2464 } \
2465 \
Paul Bakker23986e52011-04-24 08:57:21 +00002466 n -= (unsigned int) ret; \
2467 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002468}
2469
Paul Bakker5121ce52009-01-03 21:22:43 +00002470/*
2471 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002472 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002473 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002474int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002475{
Paul Bakker23986e52011-04-24 08:57:21 +00002476 int ret;
2477 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002478 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002479 const x509_name *name;
Paul Bakker5121ce52009-01-03 21:22:43 +00002480 char s[128], *p;
2481
2482 memset( s, 0, sizeof( s ) );
2483
2484 name = dn;
2485 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002486 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002487
2488 while( name != NULL )
2489 {
Paul Bakker74111d32011-01-15 16:57:55 +00002490 if( name != dn )
2491 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002492 ret = snprintf( p, n, ", " );
2493 SAFE_SNPRINTF();
2494 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002495
2496 if( memcmp( name->oid.p, OID_X520, 2 ) == 0 )
2497 {
2498 switch( name->oid.p[2] )
2499 {
2500 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002501 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002502
2503 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002504 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002505
2506 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002507 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002508
2509 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002510 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002511
2512 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002513 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002514
2515 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002516 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002517
2518 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002519 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002520 name->oid.p[2] );
2521 break;
2522 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002523 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002524 }
2525 else if( memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
2526 {
2527 switch( name->oid.p[8] )
2528 {
2529 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002530 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002531
2532 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002533 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002534 name->oid.p[8] );
2535 break;
2536 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002537 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002538 }
2539 else
Paul Bakker74111d32011-01-15 16:57:55 +00002540 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002541 ret = snprintf( p, n, "\?\?=" );
Paul Bakker74111d32011-01-15 16:57:55 +00002542 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002543 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002544
2545 for( i = 0; i < name->val.len; i++ )
2546 {
Paul Bakker27fdf462011-06-09 13:55:13 +00002547 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002548 break;
2549
2550 c = name->val.p[i];
2551 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2552 s[i] = '?';
2553 else s[i] = c;
2554 }
2555 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002556 ret = snprintf( p, n, "%s", s );
2557 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002558 name = name->next;
2559 }
2560
Paul Bakker23986e52011-04-24 08:57:21 +00002561 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002562}
2563
2564/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002565 * Store the serial in printable form into buf; no more
2566 * than size characters will be written
2567 */
2568int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2569{
Paul Bakker23986e52011-04-24 08:57:21 +00002570 int ret;
2571 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00002572 char *p;
2573
2574 p = buf;
2575 n = size;
2576
2577 nr = ( serial->len <= 32 )
2578 ? serial->len : 32;
2579
2580 for( i = 0; i < nr; i++ )
2581 {
2582 ret = snprintf( p, n, "%02X%s",
2583 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2584 SAFE_SNPRINTF();
2585 }
2586
Paul Bakker23986e52011-04-24 08:57:21 +00002587 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00002588}
2589
2590/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002591 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002592 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002593int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2594 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002595{
Paul Bakker23986e52011-04-24 08:57:21 +00002596 int ret;
2597 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002598 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00002599
2600 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002601 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002602
Paul Bakkerd98030e2009-05-02 15:13:40 +00002603 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002604 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002605 SAFE_SNPRINTF();
2606 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002607 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002608 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002609
Paul Bakkerdd476992011-01-16 21:34:59 +00002610 ret = x509parse_serial_gets( p, n, &crt->serial);
2611 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002612
Paul Bakkerd98030e2009-05-02 15:13:40 +00002613 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2614 SAFE_SNPRINTF();
2615 ret = x509parse_dn_gets( p, n, &crt->issuer );
2616 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002617
Paul Bakkerd98030e2009-05-02 15:13:40 +00002618 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2619 SAFE_SNPRINTF();
2620 ret = x509parse_dn_gets( p, n, &crt->subject );
2621 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002622
Paul Bakkerd98030e2009-05-02 15:13:40 +00002623 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002624 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2625 crt->valid_from.year, crt->valid_from.mon,
2626 crt->valid_from.day, crt->valid_from.hour,
2627 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002628 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002629
Paul Bakkerd98030e2009-05-02 15:13:40 +00002630 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002631 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2632 crt->valid_to.year, crt->valid_to.mon,
2633 crt->valid_to.day, crt->valid_to.hour,
2634 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002635 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002636
Paul Bakkerd98030e2009-05-02 15:13:40 +00002637 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2638 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002639
Paul Bakker27d66162010-03-17 06:56:01 +00002640 switch( crt->sig_alg )
Paul Bakker5121ce52009-01-03 21:22:43 +00002641 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002642 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2643 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2644 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2645 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2646 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2647 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2648 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2649 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2650 default: ret = snprintf( p, n, "???" ); break;
2651 }
2652 SAFE_SNPRINTF();
2653
2654 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
Paul Bakkerf4f69682011-04-24 16:08:12 +00002655 (int) crt->rsa.N.n * (int) sizeof( unsigned long ) * 8 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002656 SAFE_SNPRINTF();
2657
Paul Bakker23986e52011-04-24 08:57:21 +00002658 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002659}
2660
Paul Bakker74111d32011-01-15 16:57:55 +00002661/* Compare a given OID string with an OID x509_buf * */
2662#define OID_CMP(oid_str, oid_buf) \
2663 ( ( OID_SIZE(oid_str) == (oid_buf)->len ) && \
2664 memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0)
2665
2666/*
2667 * Return an informational string describing the given OID
2668 */
2669const char *x509_oid_get_description( x509_buf *oid )
2670{
2671 if ( oid == NULL )
2672 return ( NULL );
2673
2674 else if( OID_CMP( OID_SERVER_AUTH, oid ) )
2675 return( STRING_SERVER_AUTH );
2676
2677 else if( OID_CMP( OID_CLIENT_AUTH, oid ) )
2678 return( STRING_CLIENT_AUTH );
2679
2680 else if( OID_CMP( OID_CODE_SIGNING, oid ) )
2681 return( STRING_CODE_SIGNING );
2682
2683 else if( OID_CMP( OID_EMAIL_PROTECTION, oid ) )
2684 return( STRING_EMAIL_PROTECTION );
2685
2686 else if( OID_CMP( OID_TIME_STAMPING, oid ) )
2687 return( STRING_TIME_STAMPING );
2688
2689 else if( OID_CMP( OID_OCSP_SIGNING, oid ) )
2690 return( STRING_OCSP_SIGNING );
2691
2692 return( NULL );
2693}
2694
2695/* Return the x.y.z.... style numeric string for the given OID */
2696int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2697{
Paul Bakker23986e52011-04-24 08:57:21 +00002698 int ret;
2699 size_t i, n;
Paul Bakker74111d32011-01-15 16:57:55 +00002700 unsigned int value;
2701 char *p;
2702
2703 p = buf;
2704 n = size;
2705
2706 /* First byte contains first two dots */
2707 if( oid->len > 0 )
2708 {
2709 ret = snprintf( p, n, "%d.%d", oid->p[0]/40, oid->p[0]%40 );
2710 SAFE_SNPRINTF();
2711 }
2712
2713 /* TODO: value can overflow in value. */
2714 value = 0;
Paul Bakker23986e52011-04-24 08:57:21 +00002715 for( i = 1; i < oid->len; i++ )
Paul Bakker74111d32011-01-15 16:57:55 +00002716 {
2717 value <<= 7;
2718 value += oid->p[i] & 0x7F;
2719
2720 if( !( oid->p[i] & 0x80 ) )
2721 {
2722 /* Last byte */
2723 ret = snprintf( p, n, ".%d", value );
2724 SAFE_SNPRINTF();
2725 value = 0;
2726 }
2727 }
2728
Paul Bakker23986e52011-04-24 08:57:21 +00002729 return( (int) ( size - n ) );
Paul Bakker74111d32011-01-15 16:57:55 +00002730}
2731
Paul Bakkerd98030e2009-05-02 15:13:40 +00002732/*
2733 * Return an informational string about the CRL.
2734 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002735int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2736 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002737{
Paul Bakker23986e52011-04-24 08:57:21 +00002738 int ret;
2739 size_t i, n, nr;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002740 char *p;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002741 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002742
2743 p = buf;
2744 n = size;
2745
2746 ret = snprintf( p, n, "%sCRL version : %d",
2747 prefix, crl->version );
2748 SAFE_SNPRINTF();
2749
2750 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2751 SAFE_SNPRINTF();
2752 ret = x509parse_dn_gets( p, n, &crl->issuer );
2753 SAFE_SNPRINTF();
2754
2755 ret = snprintf( p, n, "\n%sthis update : " \
2756 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2757 crl->this_update.year, crl->this_update.mon,
2758 crl->this_update.day, crl->this_update.hour,
2759 crl->this_update.min, crl->this_update.sec );
2760 SAFE_SNPRINTF();
2761
2762 ret = snprintf( p, n, "\n%snext update : " \
2763 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2764 crl->next_update.year, crl->next_update.mon,
2765 crl->next_update.day, crl->next_update.hour,
2766 crl->next_update.min, crl->next_update.sec );
2767 SAFE_SNPRINTF();
2768
2769 entry = &crl->entry;
2770
2771 ret = snprintf( p, n, "\n%sRevoked certificates:",
2772 prefix );
2773 SAFE_SNPRINTF();
2774
Paul Bakker9be19372009-07-27 20:21:53 +00002775 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002776 {
2777 ret = snprintf( p, n, "\n%sserial number: ",
2778 prefix );
2779 SAFE_SNPRINTF();
2780
2781 nr = ( entry->serial.len <= 32 )
2782 ? entry->serial.len : 32;
2783
Paul Bakker74111d32011-01-15 16:57:55 +00002784 for( i = 0; i < nr; i++ )
2785 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002786 ret = snprintf( p, n, "%02X%s",
2787 entry->serial.p[i], ( i < nr - 1 ) ? ":" : "" );
2788 SAFE_SNPRINTF();
2789 }
2790
2791 ret = snprintf( p, n, " revocation date: " \
2792 "%04d-%02d-%02d %02d:%02d:%02d",
2793 entry->revocation_date.year, entry->revocation_date.mon,
2794 entry->revocation_date.day, entry->revocation_date.hour,
2795 entry->revocation_date.min, entry->revocation_date.sec );
2796 SAFE_SNPRINTF();
2797
2798 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002799 }
2800
Paul Bakkerd98030e2009-05-02 15:13:40 +00002801 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2802 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002803
Paul Bakker27d66162010-03-17 06:56:01 +00002804 switch( crl->sig_alg )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002805 {
2806 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2807 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2808 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2809 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2810 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2811 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2812 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2813 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2814 default: ret = snprintf( p, n, "???" ); break;
2815 }
2816 SAFE_SNPRINTF();
2817
Paul Bakker1e27bb22009-07-19 20:25:25 +00002818 ret = snprintf( p, n, "\n" );
2819 SAFE_SNPRINTF();
2820
Paul Bakker23986e52011-04-24 08:57:21 +00002821 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002822}
2823
2824/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00002825 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00002826 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002827int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00002828{
2829 struct tm *lt;
2830 time_t tt;
2831
2832 tt = time( NULL );
2833 lt = localtime( &tt );
2834
Paul Bakker40ea7de2009-05-03 10:18:48 +00002835 if( lt->tm_year > to->year - 1900 )
2836 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002837
Paul Bakker40ea7de2009-05-03 10:18:48 +00002838 if( lt->tm_year == to->year - 1900 &&
2839 lt->tm_mon > to->mon - 1 )
2840 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002841
Paul Bakker40ea7de2009-05-03 10:18:48 +00002842 if( lt->tm_year == to->year - 1900 &&
2843 lt->tm_mon == to->mon - 1 &&
2844 lt->tm_mday > to->day )
2845 return( 1 );
2846
Paul Bakkerb6194992011-01-16 21:40:22 +00002847 if( lt->tm_year == to->year - 1900 &&
2848 lt->tm_mon == to->mon - 1 &&
2849 lt->tm_mday == to->day &&
2850 lt->tm_hour > to->hour - 1)
2851 return( 1 );
2852
2853 if( lt->tm_year == to->year - 1900 &&
2854 lt->tm_mon == to->mon - 1 &&
2855 lt->tm_mday == to->day &&
2856 lt->tm_hour == to->hour - 1 &&
2857 lt->tm_min > to->min - 1 )
2858 return( 1 );
2859
2860 if( lt->tm_year == to->year - 1900 &&
2861 lt->tm_mon == to->mon - 1 &&
2862 lt->tm_mday == to->day &&
2863 lt->tm_hour == to->hour - 1 &&
2864 lt->tm_min == to->min - 1 &&
2865 lt->tm_sec > to->sec - 1 )
2866 return( 1 );
2867
Paul Bakker40ea7de2009-05-03 10:18:48 +00002868 return( 0 );
2869}
2870
2871/*
2872 * Return 1 if the certificate is revoked, or 0 otherwise.
2873 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002874int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002875{
Paul Bakkerff60ee62010-03-16 21:09:09 +00002876 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00002877
2878 while( cur != NULL && cur->serial.len != 0 )
2879 {
Paul Bakkera056efc2011-01-16 21:38:35 +00002880 if( crt->serial.len == cur->serial.len &&
2881 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002882 {
2883 if( x509parse_time_expired( &cur->revocation_date ) )
2884 return( 1 );
2885 }
2886
2887 cur = cur->next;
2888 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002889
2890 return( 0 );
2891}
2892
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002893/*
2894 * Wrapper for x509 hashes.
2895 *
Paul Bakker0f5f72e2011-01-18 14:58:55 +00002896 * \param out Buffer to receive the hash (Should be at least 64 bytes)
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002897 */
Paul Bakker23986e52011-04-24 08:57:21 +00002898static void x509_hash( const unsigned char *in, size_t len, int alg,
Paul Bakker5121ce52009-01-03 21:22:43 +00002899 unsigned char *out )
2900{
2901 switch( alg )
2902 {
Paul Bakker40e46942009-01-03 21:51:57 +00002903#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002904 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002905#endif
Paul Bakker40e46942009-01-03 21:51:57 +00002906#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002907 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002908#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002909#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002910 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002911#endif
2912#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002913 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002914#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00002915#if defined(POLARSSL_SHA2_C)
2916 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
2917 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
2918#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00002919#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002920 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
2921 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
2922#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002923 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002924 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002925 break;
2926 }
2927}
2928
2929/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00002930 * Check that the given certificate is valid accoring to the CRL.
2931 */
2932static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
2933 x509_crl *crl_list)
2934{
2935 int flags = 0;
2936 int hash_id;
2937 unsigned char hash[64];
2938
2939 /*
2940 * TODO: What happens if no CRL is present?
2941 * Suggestion: Revocation state should be unknown if no CRL is present.
2942 * For backwards compatibility this is not yet implemented.
2943 */
2944
2945 while( ca != NULL && crl_list != NULL && crl_list->version != 0 )
2946 {
2947 if( crl_list->issuer_raw.len != ca->subject_raw.len ||
2948 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
2949 crl_list->issuer_raw.len ) != 0 )
2950 {
2951 crl_list = crl_list->next;
2952 continue;
2953 }
2954
2955 /*
2956 * Check if CRL is correctly signed by the trusted CA
2957 */
2958 hash_id = crl_list->sig_alg;
2959
2960 x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
2961
2962 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, hash_id,
2963 0, hash, crl_list->sig.p ) == 0 )
2964 {
2965 /*
2966 * CRL is not trusted
2967 */
2968 flags |= BADCRL_NOT_TRUSTED;
2969 break;
2970 }
2971
2972 /*
2973 * Check for validity of CRL (Do not drop out)
2974 */
2975 if( x509parse_time_expired( &crl_list->next_update ) )
2976 flags |= BADCRL_EXPIRED;
2977
2978 /*
2979 * Check if certificate is revoked
2980 */
2981 if( x509parse_revoked(crt, crl_list) )
2982 {
2983 flags |= BADCERT_REVOKED;
2984 break;
2985 }
2986
2987 crl_list = crl_list->next;
2988 }
2989 return flags;
2990}
2991
2992/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002993 * Verify the certificate validity
2994 */
2995int x509parse_verify( x509_cert *crt,
2996 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00002997 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002998 const char *cn, int *flags,
2999 int (*f_vrfy)(void *, x509_cert *, int, int),
3000 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00003001{
Paul Bakker23986e52011-04-24 08:57:21 +00003002 size_t cn_len;
Paul Bakker5121ce52009-01-03 21:22:43 +00003003 int hash_id;
3004 int pathlen;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003005 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00003006 x509_name *name;
Paul Bakker4593aea2009-02-09 22:32:35 +00003007 unsigned char hash[64];
Paul Bakker5121ce52009-01-03 21:22:43 +00003008
Paul Bakker40ea7de2009-05-03 10:18:48 +00003009 *flags = 0;
3010
3011 if( x509parse_time_expired( &crt->valid_to ) )
3012 *flags = BADCERT_EXPIRED;
Paul Bakker5121ce52009-01-03 21:22:43 +00003013
3014 if( cn != NULL )
3015 {
3016 name = &crt->subject;
3017 cn_len = strlen( cn );
3018
3019 while( name != NULL )
3020 {
3021 if( memcmp( name->oid.p, OID_CN, 3 ) == 0 &&
3022 memcmp( name->val.p, cn, cn_len ) == 0 &&
3023 name->val.len == cn_len )
3024 break;
3025
3026 name = name->next;
3027 }
3028
3029 if( name == NULL )
3030 *flags |= BADCERT_CN_MISMATCH;
3031 }
3032
Paul Bakker5121ce52009-01-03 21:22:43 +00003033 /*
3034 * Iterate upwards in the given cert chain,
3035 * ignoring any upper cert with CA != TRUE.
3036 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003037 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003038
3039 pathlen = 1;
3040
Paul Bakker76fd75a2011-01-16 21:12:10 +00003041 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003042 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003043 if( parent->ca_istrue == 0 ||
3044 crt->issuer_raw.len != parent->subject_raw.len ||
3045 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00003046 crt->issuer_raw.len ) != 0 )
3047 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003048 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003049 continue;
3050 }
3051
Paul Bakker27d66162010-03-17 06:56:01 +00003052 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00003053
3054 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
3055
Paul Bakker76fd75a2011-01-16 21:12:10 +00003056 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, hash_id, 0, hash,
3057 crt->sig.p ) != 0 )
3058 *flags |= BADCERT_NOT_TRUSTED;
3059
3060 /* Check trusted CA's CRL for the given crt */
3061 *flags |= x509parse_verifycrl(crt, parent, ca_crl);
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003062
3063 /* crt is verified to be a child of the parent cur, call verify callback */
Paul Bakker74111d32011-01-15 16:57:55 +00003064 if( NULL != f_vrfy )
3065 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003066 if( f_vrfy( p_vrfy, crt, pathlen - 1, ( *flags == 0 ) ) != 0 )
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003067 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker76fd75a2011-01-16 21:12:10 +00003068 else
3069 *flags = 0;
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003070 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00003071 else if( *flags != 0 )
3072 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00003073
3074 pathlen++;
3075
Paul Bakker76fd75a2011-01-16 21:12:10 +00003076 crt = parent;
3077 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003078 }
3079
3080 /*
Paul Bakker76fd75a2011-01-16 21:12:10 +00003081 * Attempt to validate topmost cert with our CA chain.
Paul Bakker5121ce52009-01-03 21:22:43 +00003082 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003083 *flags |= BADCERT_NOT_TRUSTED;
3084
Paul Bakker7c6d4a42009-03-28 20:35:47 +00003085 while( trust_ca != NULL && trust_ca->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003086 {
3087 if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
3088 memcmp( crt->issuer_raw.p, trust_ca->subject_raw.p,
3089 crt->issuer_raw.len ) != 0 )
3090 {
3091 trust_ca = trust_ca->next;
3092 continue;
3093 }
3094
3095 if( trust_ca->max_pathlen > 0 &&
3096 trust_ca->max_pathlen < pathlen )
3097 break;
3098
Paul Bakker27d66162010-03-17 06:56:01 +00003099 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00003100
3101 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
3102
3103 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
3104 0, hash, crt->sig.p ) == 0 )
3105 {
3106 /*
3107 * cert. is signed by a trusted CA
3108 */
3109 *flags &= ~BADCERT_NOT_TRUSTED;
3110 break;
3111 }
3112
3113 trust_ca = trust_ca->next;
3114 }
3115
Paul Bakker76fd75a2011-01-16 21:12:10 +00003116 /* Check trusted CA's CRL for the given crt */
3117 *flags |= x509parse_verifycrl( crt, trust_ca, ca_crl );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003118
3119 /* Verification succeeded, call callback on top cert */
Paul Bakker74111d32011-01-15 16:57:55 +00003120 if( NULL != f_vrfy )
3121 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003122 if( f_vrfy(p_vrfy, crt, pathlen-1, ( *flags == 0 ) ) != 0 )
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003123 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker76fd75a2011-01-16 21:12:10 +00003124 else
3125 *flags = 0;
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003126 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00003127 else if( *flags != 0 )
3128 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003129
Paul Bakker5121ce52009-01-03 21:22:43 +00003130 return( 0 );
3131}
3132
3133/*
3134 * Unallocate all certificate data
3135 */
3136void x509_free( x509_cert *crt )
3137{
3138 x509_cert *cert_cur = crt;
3139 x509_cert *cert_prv;
3140 x509_name *name_cur;
3141 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00003142 x509_sequence *seq_cur;
3143 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00003144
3145 if( crt == NULL )
3146 return;
3147
3148 do
3149 {
3150 rsa_free( &cert_cur->rsa );
3151
3152 name_cur = cert_cur->issuer.next;
3153 while( name_cur != NULL )
3154 {
3155 name_prv = name_cur;
3156 name_cur = name_cur->next;
3157 memset( name_prv, 0, sizeof( x509_name ) );
3158 free( name_prv );
3159 }
3160
3161 name_cur = cert_cur->subject.next;
3162 while( name_cur != NULL )
3163 {
3164 name_prv = name_cur;
3165 name_cur = name_cur->next;
3166 memset( name_prv, 0, sizeof( x509_name ) );
3167 free( name_prv );
3168 }
3169
Paul Bakker74111d32011-01-15 16:57:55 +00003170 seq_cur = cert_cur->ext_key_usage.next;
3171 while( seq_cur != NULL )
3172 {
3173 seq_prv = seq_cur;
3174 seq_cur = seq_cur->next;
3175 memset( seq_prv, 0, sizeof( x509_sequence ) );
3176 free( seq_prv );
3177 }
3178
Paul Bakker5121ce52009-01-03 21:22:43 +00003179 if( cert_cur->raw.p != NULL )
3180 {
3181 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
3182 free( cert_cur->raw.p );
3183 }
3184
3185 cert_cur = cert_cur->next;
3186 }
3187 while( cert_cur != NULL );
3188
3189 cert_cur = crt;
3190 do
3191 {
3192 cert_prv = cert_cur;
3193 cert_cur = cert_cur->next;
3194
3195 memset( cert_prv, 0, sizeof( x509_cert ) );
3196 if( cert_prv != crt )
3197 free( cert_prv );
3198 }
3199 while( cert_cur != NULL );
3200}
3201
Paul Bakkerd98030e2009-05-02 15:13:40 +00003202/*
3203 * Unallocate all CRL data
3204 */
3205void x509_crl_free( x509_crl *crl )
3206{
3207 x509_crl *crl_cur = crl;
3208 x509_crl *crl_prv;
3209 x509_name *name_cur;
3210 x509_name *name_prv;
3211 x509_crl_entry *entry_cur;
3212 x509_crl_entry *entry_prv;
3213
3214 if( crl == NULL )
3215 return;
3216
3217 do
3218 {
3219 name_cur = crl_cur->issuer.next;
3220 while( name_cur != NULL )
3221 {
3222 name_prv = name_cur;
3223 name_cur = name_cur->next;
3224 memset( name_prv, 0, sizeof( x509_name ) );
3225 free( name_prv );
3226 }
3227
3228 entry_cur = crl_cur->entry.next;
3229 while( entry_cur != NULL )
3230 {
3231 entry_prv = entry_cur;
3232 entry_cur = entry_cur->next;
3233 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
3234 free( entry_prv );
3235 }
3236
3237 if( crl_cur->raw.p != NULL )
3238 {
3239 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
3240 free( crl_cur->raw.p );
3241 }
3242
3243 crl_cur = crl_cur->next;
3244 }
3245 while( crl_cur != NULL );
3246
3247 crl_cur = crl;
3248 do
3249 {
3250 crl_prv = crl_cur;
3251 crl_cur = crl_cur->next;
3252
3253 memset( crl_prv, 0, sizeof( x509_crl ) );
3254 if( crl_prv != crl )
3255 free( crl_prv );
3256 }
3257 while( crl_cur != NULL );
3258}
3259
Paul Bakker40e46942009-01-03 21:51:57 +00003260#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00003261
Paul Bakker40e46942009-01-03 21:51:57 +00003262#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00003263
3264/*
3265 * Checkup routine
3266 */
3267int x509_self_test( int verbose )
3268{
Paul Bakker5690efc2011-05-26 13:16:06 +00003269#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00003270 int ret;
3271 int flags;
3272 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00003273 x509_cert cacert;
3274 x509_cert clicert;
3275 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00003276#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003277 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00003278#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003279
3280 if( verbose != 0 )
3281 printf( " X.509 certificate load: " );
3282
3283 memset( &clicert, 0, sizeof( x509_cert ) );
3284
3285 ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
3286 strlen( test_cli_crt ) );
3287 if( ret != 0 )
3288 {
3289 if( verbose != 0 )
3290 printf( "failed\n" );
3291
3292 return( ret );
3293 }
3294
3295 memset( &cacert, 0, sizeof( x509_cert ) );
3296
3297 ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
3298 strlen( test_ca_crt ) );
3299 if( ret != 0 )
3300 {
3301 if( verbose != 0 )
3302 printf( "failed\n" );
3303
3304 return( ret );
3305 }
3306
3307 if( verbose != 0 )
3308 printf( "passed\n X.509 private key load: " );
3309
3310 i = strlen( test_ca_key );
3311 j = strlen( test_ca_pwd );
3312
Paul Bakker66b78b22011-03-25 14:22:50 +00003313 rsa_init( &rsa, RSA_PKCS_V15, 0 );
3314
Paul Bakker5121ce52009-01-03 21:22:43 +00003315 if( ( ret = x509parse_key( &rsa,
3316 (unsigned char *) test_ca_key, i,
3317 (unsigned char *) test_ca_pwd, j ) ) != 0 )
3318 {
3319 if( verbose != 0 )
3320 printf( "failed\n" );
3321
3322 return( ret );
3323 }
3324
3325 if( verbose != 0 )
3326 printf( "passed\n X.509 signature verify: ");
3327
Paul Bakker23986e52011-04-24 08:57:21 +00003328 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003329 if( ret != 0 )
3330 {
Paul Bakker23986e52011-04-24 08:57:21 +00003331 printf("%02x", flags);
Paul Bakker5121ce52009-01-03 21:22:43 +00003332 if( verbose != 0 )
3333 printf( "failed\n" );
3334
3335 return( ret );
3336 }
3337
Paul Bakker5690efc2011-05-26 13:16:06 +00003338#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003339 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003340 printf( "passed\n X.509 DHM parameter load: " );
3341
3342 i = strlen( test_dhm_params );
3343 j = strlen( test_ca_pwd );
3344
3345 if( ( ret = x509parse_dhm( &dhm, (unsigned char *) test_dhm_params, i ) ) != 0 )
3346 {
3347 if( verbose != 0 )
3348 printf( "failed\n" );
3349
3350 return( ret );
3351 }
3352
3353 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003354 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00003355#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003356
3357 x509_free( &cacert );
3358 x509_free( &clicert );
3359 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00003360#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003361 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00003362#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003363
3364 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003365#else
3366 ((void) verbose);
3367 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3368#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003369}
3370
3371#endif
3372
3373#endif