blob: ffe13444c870a548d07fa44ad959ae096589c7f1 [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>
54#include <stdio.h>
55#include <time.h>
56
57/*
58 * ASN.1 DER decoding routines
59 */
60static int asn1_get_len( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +000061 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +000062 int *len )
63{
64 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +000065 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000066
67 if( ( **p & 0x80 ) == 0 )
68 *len = *(*p)++;
69 else
70 {
71 switch( **p & 0x7F )
72 {
73 case 1:
74 if( ( end - *p ) < 2 )
Paul Bakker40e46942009-01-03 21:51:57 +000075 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000076
77 *len = (*p)[1];
78 (*p) += 2;
79 break;
80
81 case 2:
82 if( ( end - *p ) < 3 )
Paul Bakker40e46942009-01-03 21:51:57 +000083 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000084
85 *len = ( (*p)[1] << 8 ) | (*p)[2];
86 (*p) += 3;
87 break;
88
89 default:
Paul Bakker40e46942009-01-03 21:51:57 +000090 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +000091 break;
92 }
93 }
94
95 if( *len > (int) ( end - *p ) )
Paul Bakker40e46942009-01-03 21:51:57 +000096 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000097
98 return( 0 );
99}
100
101static int asn1_get_tag( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000102 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000103 int *len, int tag )
104{
105 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000106 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000107
108 if( **p != tag )
Paul Bakker40e46942009-01-03 21:51:57 +0000109 return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000110
111 (*p)++;
112
113 return( asn1_get_len( p, end, len ) );
114}
115
116static int asn1_get_bool( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000117 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000118 int *val )
119{
120 int ret, len;
121
122 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 )
123 return( ret );
124
125 if( len != 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000126 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000127
128 *val = ( **p != 0 ) ? 1 : 0;
129 (*p)++;
130
131 return( 0 );
132}
133
134static int asn1_get_int( 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{
138 int ret, len;
139
140 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
141 return( ret );
142
143 if( len > (int) sizeof( int ) || ( **p & 0x80 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000144 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000145
146 *val = 0;
147
148 while( len-- > 0 )
149 {
150 *val = ( *val << 8 ) | **p;
151 (*p)++;
152 }
153
154 return( 0 );
155}
156
157static int asn1_get_mpi( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000158 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000159 mpi *X )
160{
161 int ret, len;
162
163 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
164 return( ret );
165
166 ret = mpi_read_binary( X, *p, len );
167
168 *p += len;
169
170 return( ret );
171}
172
Paul Bakker74111d32011-01-15 16:57:55 +0000173static int asn1_get_bitstring( unsigned char **p, const unsigned char *end,
174 x509_bitstring *bs)
175{
176 int ret;
177
178 /* Certificate type is a single byte bitstring */
179 if( ( ret = asn1_get_tag( p, end, &bs->len, ASN1_BIT_STRING ) ) != 0 )
180 return( ret );
181
182 /* Check length, subtract one for actual bit string length */
183 if ( bs->len < 1 )
184 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
185 bs->len -= 1;
186
187 /* Get number of unused bits, ensure unused bits <= 7 */
188 bs->unused_bits = **p;
189 if( bs->unused_bits > 7 )
190 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
191 (*p)++;
192
193 /* Get actual bitstring */
194 bs->p = *p;
195 *p += bs->len;
196
197 if( *p != end )
198 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
199
200 return 0;
201}
202
203
204/*
205 * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
206 */
207static int asn1_get_sequence_of( unsigned char **p,
208 const unsigned char *end,
209 x509_sequence *cur,
210 int tag)
211{
212 int ret, len;
213 x509_buf *buf;
214
215 /* Get main sequence tag */
216 if( ( ret = asn1_get_tag( p, end, &len,
217 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
218 return( ret );
219
220 if( *p + len != end )
221 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
222
223 while( *p < end )
224 {
225 buf = &(cur->buf);
226 buf->tag = **p;
227
228 if( ( ret = asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
229 return( ret );
230
231 buf->p = *p;
232 *p += buf->len;
233
234 /* Allocate and assign next pointer */
235 if (*p < end)
236 {
237 cur->next = (x509_sequence *) malloc(
238 sizeof( x509_sequence ) );
239
240 if( cur->next == NULL )
241 return( 1 );
242
243 cur = cur->next;
244 }
245 }
246
247 /* Set final sequence entry's next pointer to NULL */
248 cur->next = NULL;
249
250 if( *p != end )
251 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
252
253 return( 0 );
254}
255
Paul Bakker5121ce52009-01-03 21:22:43 +0000256/*
257 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
258 */
259static int x509_get_version( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000260 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000261 int *ver )
262{
263 int ret, len;
264
265 if( ( ret = asn1_get_tag( p, end, &len,
266 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
267 {
Paul Bakker40e46942009-01-03 21:51:57 +0000268 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000269 return( *ver = 0 );
270
271 return( ret );
272 }
273
274 end = *p + len;
275
276 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000277 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000278
279 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000280 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION |
281 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000282
283 return( 0 );
284}
285
286/*
287 * CertificateSerialNumber ::= INTEGER
288 */
289static int x509_get_serial( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000290 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000291 x509_buf *serial )
292{
293 int ret;
294
295 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000296 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL |
297 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000298
299 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
300 **p != ASN1_INTEGER )
Paul Bakker40e46942009-01-03 21:51:57 +0000301 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL |
302 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000303
304 serial->tag = *(*p)++;
305
306 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000307 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000308
309 serial->p = *p;
310 *p += serial->len;
311
312 return( 0 );
313}
314
315/*
316 * AlgorithmIdentifier ::= SEQUENCE {
317 * algorithm OBJECT IDENTIFIER,
318 * parameters ANY DEFINED BY algorithm OPTIONAL }
319 */
320static int x509_get_alg( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000321 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000322 x509_buf *alg )
323{
324 int ret, len;
325
326 if( ( ret = asn1_get_tag( p, end, &len,
327 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000328 return( POLARSSL_ERR_X509_CERT_INVALID_ALG | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000329
330 end = *p + len;
331 alg->tag = **p;
332
333 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000334 return( POLARSSL_ERR_X509_CERT_INVALID_ALG | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000335
336 alg->p = *p;
337 *p += alg->len;
338
339 if( *p == end )
340 return( 0 );
341
342 /*
343 * assume the algorithm parameters must be NULL
344 */
345 if( ( ret = asn1_get_tag( p, end, &len, ASN1_NULL ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000346 return( POLARSSL_ERR_X509_CERT_INVALID_ALG | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000347
348 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000349 return( POLARSSL_ERR_X509_CERT_INVALID_ALG |
350 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000351
352 return( 0 );
353}
354
355/*
356 * RelativeDistinguishedName ::=
357 * SET OF AttributeTypeAndValue
358 *
359 * AttributeTypeAndValue ::= SEQUENCE {
360 * type AttributeType,
361 * value AttributeValue }
362 *
363 * AttributeType ::= OBJECT IDENTIFIER
364 *
365 * AttributeValue ::= ANY DEFINED BY AttributeType
366 */
367static int x509_get_name( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000368 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000369 x509_name *cur )
370{
371 int ret, len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000372 const unsigned char *end2;
Paul Bakker5121ce52009-01-03 21:22:43 +0000373 x509_buf *oid;
374 x509_buf *val;
375
376 if( ( ret = asn1_get_tag( p, end, &len,
377 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000378 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000379
380 end2 = end;
381 end = *p + len;
382
383 if( ( ret = asn1_get_tag( p, end, &len,
384 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000385 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000386
387 if( *p + len != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000388 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
389 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000390
391 oid = &cur->oid;
392 oid->tag = **p;
393
394 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000395 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000396
397 oid->p = *p;
398 *p += oid->len;
399
400 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000401 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
402 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000403
404 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
405 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
406 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker40e46942009-01-03 21:51:57 +0000407 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
408 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000409
410 val = &cur->val;
411 val->tag = *(*p)++;
412
413 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000414 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000415
416 val->p = *p;
417 *p += val->len;
418
419 cur->next = NULL;
420
421 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000422 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
423 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000424
425 /*
426 * recurse until end of SEQUENCE is reached
427 */
428 if( *p == end2 )
429 return( 0 );
430
431 cur->next = (x509_name *) malloc(
432 sizeof( x509_name ) );
433
434 if( cur->next == NULL )
435 return( 1 );
436
437 return( x509_get_name( p, end2, cur->next ) );
438}
439
440/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000441 * Time ::= CHOICE {
442 * utcTime UTCTime,
443 * generalTime GeneralizedTime }
444 */
Paul Bakker91200182010-02-18 21:26:15 +0000445static int x509_get_time( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000446 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000447 x509_time *time )
448{
449 int ret, len;
450 char date[64];
Paul Bakker91200182010-02-18 21:26:15 +0000451 unsigned char tag;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000452
Paul Bakker91200182010-02-18 21:26:15 +0000453 if( ( end - *p ) < 1 )
454 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000455
Paul Bakker91200182010-02-18 21:26:15 +0000456 tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000457
Paul Bakker91200182010-02-18 21:26:15 +0000458 if ( tag == ASN1_UTC_TIME )
459 {
460 (*p)++;
461 ret = asn1_get_len( p, end, &len );
462
463 if( ret != 0 )
464 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000465
Paul Bakker91200182010-02-18 21:26:15 +0000466 memset( date, 0, sizeof( date ) );
467 memcpy( date, *p, ( len < (int) sizeof( date ) - 1 ) ?
468 len : (int) sizeof( date ) - 1 );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000469
Paul Bakker91200182010-02-18 21:26:15 +0000470 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
471 &time->year, &time->mon, &time->day,
472 &time->hour, &time->min, &time->sec ) < 5 )
473 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000474
Paul Bakker91200182010-02-18 21:26:15 +0000475 time->year += 100 * ( time->year < 90 );
476 time->year += 1900;
477
478 *p += len;
479
480 return( 0 );
481 }
482 else if ( tag == ASN1_GENERALIZED_TIME )
483 {
484 (*p)++;
485 ret = asn1_get_len( p, end, &len );
486
487 if( ret != 0 )
488 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret );
489
490 memset( date, 0, sizeof( date ) );
491 memcpy( date, *p, ( len < (int) sizeof( date ) - 1 ) ?
492 len : (int) sizeof( date ) - 1 );
493
494 if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
495 &time->year, &time->mon, &time->day,
496 &time->hour, &time->min, &time->sec ) < 5 )
497 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
498
499 *p += len;
500
501 return( 0 );
502 }
503 else
504 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000505}
506
507
508/*
509 * Validity ::= SEQUENCE {
510 * notBefore Time,
511 * notAfter Time }
512 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000513static int x509_get_dates( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000514 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000515 x509_time *from,
516 x509_time *to )
517{
518 int ret, len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000519
520 if( ( ret = asn1_get_tag( p, end, &len,
521 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000522 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000523
524 end = *p + len;
525
Paul Bakker91200182010-02-18 21:26:15 +0000526 if( ( ret = x509_get_time( p, end, from ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000527 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000528
Paul Bakker91200182010-02-18 21:26:15 +0000529 if( ( ret = x509_get_time( p, end, to ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000530 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000531
532 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000533 return( POLARSSL_ERR_X509_CERT_INVALID_DATE |
534 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000535
536 return( 0 );
537}
538
539/*
540 * SubjectPublicKeyInfo ::= SEQUENCE {
541 * algorithm AlgorithmIdentifier,
542 * subjectPublicKey BIT STRING }
543 */
544static int x509_get_pubkey( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000545 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000546 x509_buf *pk_alg_oid,
547 mpi *N, mpi *E )
548{
549 int ret, len;
550 unsigned char *end2;
551
552 if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 )
553 return( ret );
554
555 /*
556 * only RSA public keys handled at this time
557 */
558 if( pk_alg_oid->len != 9 ||
559 memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000560 return( POLARSSL_ERR_X509_CERT_UNKNOWN_PK_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000561
562 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000563 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000564
565 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000566 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY |
567 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000568
569 end2 = *p + len;
570
571 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000572 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000573
574 /*
575 * RSAPublicKey ::= SEQUENCE {
576 * modulus INTEGER, -- n
577 * publicExponent INTEGER -- e
578 * }
579 */
580 if( ( ret = asn1_get_tag( p, end2, &len,
581 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000582 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000583
584 if( *p + len != end2 )
Paul Bakker40e46942009-01-03 21:51:57 +0000585 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY |
586 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000587
588 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
589 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000590 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000591
592 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000593 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY |
594 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000595
596 return( 0 );
597}
598
599static int x509_get_sig( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000600 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000601 x509_buf *sig )
602{
603 int ret, len;
604
605 sig->tag = **p;
606
607 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000608 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000609
Paul Bakker74111d32011-01-15 16:57:55 +0000610
Paul Bakker5121ce52009-01-03 21:22:43 +0000611 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000612 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000613
614 sig->len = len;
615 sig->p = *p;
616
617 *p += len;
618
619 return( 0 );
620}
621
622/*
623 * X.509 v2/v3 unique identifier (not parsed)
624 */
625static int x509_get_uid( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000626 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000627 x509_buf *uid, int n )
628{
629 int ret;
630
631 if( *p == end )
632 return( 0 );
633
634 uid->tag = **p;
635
636 if( ( ret = asn1_get_tag( p, end, &uid->len,
637 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
638 {
Paul Bakker40e46942009-01-03 21:51:57 +0000639 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000640 return( 0 );
641
642 return( ret );
643 }
644
645 uid->p = *p;
646 *p += uid->len;
647
648 return( 0 );
649}
650
651/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000652 * X.509 Extensions (No parsing of extensions, pointer should
653 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000654 */
655static int x509_get_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000656 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000657 x509_buf *ext )
Paul Bakker5121ce52009-01-03 21:22:43 +0000658{
659 int ret, len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000660
661 if( *p == end )
662 return( 0 );
663
664 ext->tag = **p;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000665
Paul Bakker5121ce52009-01-03 21:22:43 +0000666 if( ( ret = asn1_get_tag( p, end, &ext->len,
667 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000668 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000669
670 ext->p = *p;
671 end = *p + ext->len;
672
673 /*
674 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
675 *
676 * Extension ::= SEQUENCE {
677 * extnID OBJECT IDENTIFIER,
678 * critical BOOLEAN DEFAULT FALSE,
679 * extnValue OCTET STRING }
680 */
681 if( ( ret = asn1_get_tag( p, end, &len,
682 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000683 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000684
685 if( end != *p + len )
Paul Bakker40e46942009-01-03 21:51:57 +0000686 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
687 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000688
Paul Bakkerd98030e2009-05-02 15:13:40 +0000689 return( 0 );
690}
691
692/*
693 * X.509 CRL v2 extensions (no extensions parsed yet.)
694 */
695static int x509_get_crl_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000696 const unsigned char *end,
697 x509_buf *ext )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000698{
699 int ret, len;
700
701 if( ( ret = x509_get_ext( p, end, ext ) ) != 0 )
702 {
703 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
704 return( 0 );
705
706 return( ret );
707 }
708
709 while( *p < end )
710 {
711 if( ( ret = asn1_get_tag( p, end, &len,
712 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
713 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
714
715 *p += len;
716 }
717
718 if( *p != end )
719 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
720 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
721
722 return( 0 );
723}
724
Paul Bakker74111d32011-01-15 16:57:55 +0000725static int x509_get_basic_constraints( unsigned char **p,
726 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000727 int *ca_istrue,
728 int *max_pathlen )
729{
730 int ret, len;
731
732 /*
733 * BasicConstraints ::= SEQUENCE {
734 * cA BOOLEAN DEFAULT FALSE,
735 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
736 */
Paul Bakker3cccddb2011-01-16 21:46:31 +0000737 *ca_istrue = 0; /* DEFAULT FALSE */
Paul Bakker74111d32011-01-15 16:57:55 +0000738 *max_pathlen = 0; /* endless */
739
740 if( ( ret = asn1_get_tag( p, end, &len,
741 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
742 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
743
744 if( *p == end )
745 return 0;
746
Paul Bakker3cccddb2011-01-16 21:46:31 +0000747 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000748 {
749 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker3cccddb2011-01-16 21:46:31 +0000750 ret = asn1_get_int( p, end, ca_istrue );
Paul Bakker74111d32011-01-15 16:57:55 +0000751
752 if( ret != 0 )
753 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
754
Paul Bakker3cccddb2011-01-16 21:46:31 +0000755 if( *ca_istrue != 0 )
756 *ca_istrue = 1;
Paul Bakker74111d32011-01-15 16:57:55 +0000757 }
758
759 if( *p == end )
760 return 0;
761
762 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
763 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
764
765 if( *p != end )
766 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
767 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
768
769 (*max_pathlen)++;
770
Paul Bakker74111d32011-01-15 16:57:55 +0000771 return 0;
772}
773
774static int x509_get_ns_cert_type( unsigned char **p,
775 const unsigned char *end,
776 unsigned char *ns_cert_type)
777{
778 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000779 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000780
781 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
782 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
783
784 if( bs.len != 1 )
785 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
786 POLARSSL_ERR_ASN1_INVALID_LENGTH );
787
788 /* Get actual bitstring */
789 *ns_cert_type = *bs.p;
790 return 0;
791}
792
793static int x509_get_key_usage( unsigned char **p,
794 const unsigned char *end,
795 unsigned char *key_usage)
796{
797 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000798 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000799
800 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
801 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
802
803 if( bs.len != 1 )
804 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
805 POLARSSL_ERR_ASN1_INVALID_LENGTH );
806
807 /* Get actual bitstring */
808 *key_usage = *bs.p;
809 return 0;
810}
811
Paul Bakkerd98030e2009-05-02 15:13:40 +0000812/*
Paul Bakker74111d32011-01-15 16:57:55 +0000813 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
814 *
815 * KeyPurposeId ::= OBJECT IDENTIFIER
816 */
817static int x509_get_ext_key_usage( unsigned char **p,
818 const unsigned char *end,
819 x509_sequence *ext_key_usage)
820{
821 int ret;
822
823 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
824 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
825
826 /* Sequence length must be >= 1 */
827 if( ext_key_usage->buf.p == NULL )
828 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
829 POLARSSL_ERR_ASN1_INVALID_LENGTH );
830
831 return 0;
832}
833
834/*
835 * X.509 v3 extensions
836 *
837 * TODO: Perform all of the basic constraints tests required by the RFC
838 * TODO: Set values for undetected extensions to a sane default?
839 *
Paul Bakkerd98030e2009-05-02 15:13:40 +0000840 */
841static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000842 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000843 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000844{
845 int ret, len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000846 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000847
Paul Bakker74111d32011-01-15 16:57:55 +0000848 if( ( ret = x509_get_ext( p, end, &crt->v3_ext ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000849 {
850 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
851 return( 0 );
852
853 return( ret );
854 }
855
Paul Bakker5121ce52009-01-03 21:22:43 +0000856 while( *p < end )
857 {
Paul Bakker74111d32011-01-15 16:57:55 +0000858 /*
859 * Extension ::= SEQUENCE {
860 * extnID OBJECT IDENTIFIER,
861 * critical BOOLEAN DEFAULT FALSE,
862 * extnValue OCTET STRING }
863 */
864 x509_buf extn_oid = {0, 0, NULL};
865 int is_critical = 0; /* DEFAULT FALSE */
866
Paul Bakker5121ce52009-01-03 21:22:43 +0000867 if( ( ret = asn1_get_tag( p, end, &len,
868 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000869 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000870
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000871 end_ext_data = *p + len;
872
Paul Bakker74111d32011-01-15 16:57:55 +0000873 /* Get extension ID */
874 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000875
Paul Bakker74111d32011-01-15 16:57:55 +0000876 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
877 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000878
Paul Bakker74111d32011-01-15 16:57:55 +0000879 extn_oid.p = *p;
880 *p += extn_oid.len;
881
882 if( ( end - *p ) < 1 )
883 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
884 POLARSSL_ERR_ASN1_OUT_OF_DATA );
885
886 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000887 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000888 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
889 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000890
Paul Bakker74111d32011-01-15 16:57:55 +0000891 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000892 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000893 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000894 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000895
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000896 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000897
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000898 if( end_ext_octet != end_ext_data )
899 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
900 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000901
Paul Bakker74111d32011-01-15 16:57:55 +0000902 /*
903 * Detect supported extensions
904 */
905 if( ( OID_SIZE( OID_BASIC_CONSTRAINTS ) == extn_oid.len ) &&
906 memcmp( extn_oid.p, OID_BASIC_CONSTRAINTS, extn_oid.len ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000907 {
Paul Bakker74111d32011-01-15 16:57:55 +0000908 /* Parse basic constraints */
909 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
Paul Bakker3cccddb2011-01-16 21:46:31 +0000910 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000911 return ( ret );
912 crt->ext_types |= EXT_BASIC_CONSTRAINTS;
Paul Bakker5121ce52009-01-03 21:22:43 +0000913 }
Paul Bakker74111d32011-01-15 16:57:55 +0000914 else if( ( OID_SIZE( OID_NS_CERT_TYPE ) == extn_oid.len ) &&
915 memcmp( extn_oid.p, OID_NS_CERT_TYPE, extn_oid.len ) == 0 )
916 {
917 /* Parse netscape certificate type */
918 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
919 &crt->ns_cert_type ) ) != 0 )
920 return ( ret );
921 crt->ext_types |= EXT_NS_CERT_TYPE;
922 }
923 else if( ( OID_SIZE( OID_KEY_USAGE ) == extn_oid.len ) &&
924 memcmp( extn_oid.p, OID_KEY_USAGE, extn_oid.len ) == 0 )
925 {
926 /* Parse key usage */
927 if( ( ret = x509_get_key_usage( p, end_ext_octet,
928 &crt->key_usage ) ) != 0 )
929 return ( ret );
930 crt->ext_types |= EXT_KEY_USAGE;
931 }
932 else if( ( OID_SIZE( OID_EXTENDED_KEY_USAGE ) == extn_oid.len ) &&
933 memcmp( extn_oid.p, OID_EXTENDED_KEY_USAGE, extn_oid.len ) == 0 )
934 {
935 /* Parse extended key usage */
936 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
937 &crt->ext_key_usage ) ) != 0 )
938 return ( ret );
939 crt->ext_types |= EXT_EXTENDED_KEY_USAGE;
940 }
941 else
942 {
943 /* No parser found, skip extension */
944 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +0000945
Paul Bakker74111d32011-01-15 16:57:55 +0000946 if( is_critical )
947 {
948 /* Data is marked as critical: fail */
949 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
950 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
951 }
952 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000953 }
954
955 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000956 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
957 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000958
Paul Bakker5121ce52009-01-03 21:22:43 +0000959 return( 0 );
960}
961
962/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000963 * X.509 CRL Entries
964 */
965static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000966 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000967 x509_crl_entry *entry )
968{
Paul Bakker9be19372009-07-27 20:21:53 +0000969 int ret, entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000970 x509_crl_entry *cur_entry = entry;
971
972 if( *p == end )
973 return( 0 );
974
Paul Bakker9be19372009-07-27 20:21:53 +0000975 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000976 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
977 {
978 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
979 return( 0 );
980
981 return( ret );
982 }
983
Paul Bakker9be19372009-07-27 20:21:53 +0000984 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000985
986 while( *p < end )
987 {
988 int len2;
989
990 if( ( ret = asn1_get_tag( p, end, &len2,
991 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
992 {
Paul Bakkerd98030e2009-05-02 15:13:40 +0000993 return( ret );
994 }
995
Paul Bakker9be19372009-07-27 20:21:53 +0000996 cur_entry->raw.tag = **p;
997 cur_entry->raw.p = *p;
998 cur_entry->raw.len = len2;
999
Paul Bakkerd98030e2009-05-02 15:13:40 +00001000 if( ( ret = x509_get_serial( p, end, &cur_entry->serial ) ) != 0 )
1001 return( ret );
1002
Paul Bakker91200182010-02-18 21:26:15 +00001003 if( ( ret = x509_get_time( p, end, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001004 return( ret );
1005
1006 if( ( ret = x509_get_crl_ext( p, end, &cur_entry->entry_ext ) ) != 0 )
1007 return( ret );
1008
Paul Bakker74111d32011-01-15 16:57:55 +00001009 if ( *p < end )
1010 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001011 cur_entry->next = malloc( sizeof( x509_crl_entry ) );
1012 cur_entry = cur_entry->next;
1013 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
1014 }
1015 }
1016
1017 return( 0 );
1018}
1019
Paul Bakker27d66162010-03-17 06:56:01 +00001020static int x509_get_sig_alg( const x509_buf *sig_oid, int *sig_alg )
1021{
1022 if( sig_oid->len == 9 &&
1023 memcmp( sig_oid->p, OID_PKCS1, 8 ) == 0 )
1024 {
1025 if( sig_oid->p[8] >= 2 && sig_oid->p[8] <= 5 )
1026 {
1027 *sig_alg = sig_oid->p[8];
1028 return( 0 );
1029 }
1030
1031 if ( sig_oid->p[8] >= 11 && sig_oid->p[8] <= 14 )
1032 {
1033 *sig_alg = sig_oid->p[8];
1034 return( 0 );
1035 }
1036
1037 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1038 }
1039
1040 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1041}
1042
Paul Bakkerd98030e2009-05-02 15:13:40 +00001043/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001044 * Parse one or more certificates and add them to the chained list
1045 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001046int x509parse_crt( x509_cert *chain, const unsigned char *buf, int buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001047{
Paul Bakker96743fc2011-02-12 14:30:57 +00001048 int ret, len, use_len;
Paul Bakker5121ce52009-01-03 21:22:43 +00001049 unsigned char *p, *end;
1050 x509_cert *crt;
Paul Bakker96743fc2011-02-12 14:30:57 +00001051#if defined(POLARSSL_PEM_C)
1052 pem_context pem;
1053#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001054
1055 crt = chain;
1056
Paul Bakker320a4b52009-03-28 18:52:39 +00001057 /*
1058 * Check for valid input
1059 */
1060 if( crt == NULL || buf == NULL )
1061 return( 1 );
1062
Paul Bakkere9581d62009-03-28 20:29:25 +00001063 while( crt->version != 0 && crt->next != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00001064 crt = crt->next;
1065
1066 /*
Paul Bakker320a4b52009-03-28 18:52:39 +00001067 * Add new certificate on the end of the chain if needed.
1068 */
Paul Bakkere9581d62009-03-28 20:29:25 +00001069 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001070 {
1071 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1072
Paul Bakker7d06ad22009-05-02 15:53:56 +00001073 if( crt->next == NULL )
1074 {
Paul Bakker320a4b52009-03-28 18:52:39 +00001075 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001076 return( 1 );
1077 }
Paul Bakker320a4b52009-03-28 18:52:39 +00001078
Paul Bakker7d06ad22009-05-02 15:53:56 +00001079 crt = crt->next;
1080 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001081 }
1082
Paul Bakker96743fc2011-02-12 14:30:57 +00001083#if defined(POLARSSL_PEM_C)
1084 pem_init( &pem );
1085 ret = pem_read_buffer( &pem,
1086 "-----BEGIN CERTIFICATE-----",
1087 "-----END CERTIFICATE-----",
1088 buf, NULL, 0, &use_len );
Paul Bakker5121ce52009-01-03 21:22:43 +00001089
Paul Bakker96743fc2011-02-12 14:30:57 +00001090 if( ret == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001091 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001092 /*
1093 * Was PEM encoded
1094 */
1095 buflen -= use_len;
1096 buf += use_len;
Paul Bakker5121ce52009-01-03 21:22:43 +00001097
1098 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001099 * Steal PEM buffer
Paul Bakker5121ce52009-01-03 21:22:43 +00001100 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001101 p = pem.buf;
1102 pem.buf = NULL;
1103 len = pem.buflen;
1104 pem_free( &pem );
1105 }
1106 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
1107 {
1108 pem_free( &pem );
1109 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001110 }
1111 else
1112 {
1113 /*
1114 * nope, copy the raw DER data
1115 */
1116 p = (unsigned char *) malloc( len = buflen );
1117
1118 if( p == NULL )
1119 return( 1 );
1120
1121 memcpy( p, buf, buflen );
1122
1123 buflen = 0;
1124 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001125#else
1126 p = (unsigned char *) malloc( len = buflen );
1127
1128 if( p == NULL )
1129 return( 1 );
1130
1131 memcpy( p, buf, buflen );
1132
1133 buflen = 0;
1134#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001135
1136 crt->raw.p = p;
1137 crt->raw.len = len;
1138 end = p + len;
1139
1140 /*
1141 * Certificate ::= SEQUENCE {
1142 * tbsCertificate TBSCertificate,
1143 * signatureAlgorithm AlgorithmIdentifier,
1144 * signatureValue BIT STRING }
1145 */
1146 if( ( ret = asn1_get_tag( &p, end, &len,
1147 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1148 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001149 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001150 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001151 }
1152
1153 if( len != (int) ( end - p ) )
1154 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001155 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001156 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1157 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001158 }
1159
1160 /*
1161 * TBSCertificate ::= SEQUENCE {
1162 */
1163 crt->tbs.p = p;
1164
1165 if( ( ret = asn1_get_tag( &p, end, &len,
1166 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1167 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001168 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001169 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001170 }
1171
1172 end = p + len;
1173 crt->tbs.len = end - crt->tbs.p;
1174
1175 /*
1176 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1177 *
1178 * CertificateSerialNumber ::= INTEGER
1179 *
1180 * signature AlgorithmIdentifier
1181 */
1182 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1183 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1184 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
1185 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001186 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001187 return( ret );
1188 }
1189
1190 crt->version++;
1191
1192 if( crt->version > 3 )
1193 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001194 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001195 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001196 }
1197
Paul Bakker27d66162010-03-17 06:56:01 +00001198 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_alg ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001199 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001200 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001201 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001202 }
1203
1204 /*
1205 * issuer Name
1206 */
1207 crt->issuer_raw.p = p;
1208
1209 if( ( ret = asn1_get_tag( &p, end, &len,
1210 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1211 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001212 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001213 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001214 }
1215
1216 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1217 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001218 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001219 return( ret );
1220 }
1221
1222 crt->issuer_raw.len = p - crt->issuer_raw.p;
1223
1224 /*
1225 * Validity ::= SEQUENCE {
1226 * notBefore Time,
1227 * notAfter Time }
1228 *
1229 */
1230 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1231 &crt->valid_to ) ) != 0 )
1232 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001233 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001234 return( ret );
1235 }
1236
1237 /*
1238 * subject Name
1239 */
1240 crt->subject_raw.p = p;
1241
1242 if( ( ret = asn1_get_tag( &p, end, &len,
1243 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1244 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001245 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001246 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001247 }
1248
1249 if( ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
1250 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001251 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001252 return( ret );
1253 }
1254
1255 crt->subject_raw.len = p - crt->subject_raw.p;
1256
1257 /*
1258 * SubjectPublicKeyInfo ::= SEQUENCE
1259 * algorithm AlgorithmIdentifier,
1260 * subjectPublicKey BIT STRING }
1261 */
1262 if( ( ret = asn1_get_tag( &p, end, &len,
1263 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1264 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001265 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001266 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001267 }
1268
1269 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1270 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1271 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001272 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001273 return( ret );
1274 }
1275
1276 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1277 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001278 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001279 return( ret );
1280 }
1281
1282 crt->rsa.len = mpi_size( &crt->rsa.N );
1283
1284 /*
1285 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1286 * -- If present, version shall be v2 or v3
1287 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1288 * -- If present, version shall be v2 or v3
1289 * extensions [3] EXPLICIT Extensions OPTIONAL
1290 * -- If present, version shall be v3
1291 */
1292 if( crt->version == 2 || crt->version == 3 )
1293 {
1294 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1295 if( ret != 0 )
1296 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001297 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001298 return( ret );
1299 }
1300 }
1301
1302 if( crt->version == 2 || crt->version == 3 )
1303 {
1304 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1305 if( ret != 0 )
1306 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001307 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001308 return( ret );
1309 }
1310 }
1311
1312 if( crt->version == 3 )
1313 {
Paul Bakker74111d32011-01-15 16:57:55 +00001314 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001315 if( ret != 0 )
1316 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001317 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001318 return( ret );
1319 }
1320 }
1321
1322 if( p != end )
1323 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001324 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001325 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1326 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001327 }
1328
1329 end = crt->raw.p + crt->raw.len;
1330
1331 /*
1332 * signatureAlgorithm AlgorithmIdentifier,
1333 * signatureValue BIT STRING
1334 */
1335 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1336 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001337 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001338 return( ret );
1339 }
1340
Paul Bakker320a4b52009-03-28 18:52:39 +00001341 if( memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001342 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001343 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001344 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001345 }
1346
1347 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1348 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001349 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001350 return( ret );
1351 }
1352
1353 if( p != end )
1354 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001355 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001356 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1357 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001358 }
1359
Paul Bakker5121ce52009-01-03 21:22:43 +00001360 if( buflen > 0 )
Paul Bakker320a4b52009-03-28 18:52:39 +00001361 {
1362 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1363
Paul Bakker7d06ad22009-05-02 15:53:56 +00001364 if( crt->next == NULL )
1365 {
Paul Bakker320a4b52009-03-28 18:52:39 +00001366 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001367 return( 1 );
1368 }
Paul Bakker320a4b52009-03-28 18:52:39 +00001369
Paul Bakker7d06ad22009-05-02 15:53:56 +00001370 crt = crt->next;
1371 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001372
Paul Bakker5121ce52009-01-03 21:22:43 +00001373 return( x509parse_crt( crt, buf, buflen ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001374 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001375
1376 return( 0 );
1377}
1378
1379/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001380 * Parse one or more CRLs and add them to the chained list
1381 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001382int x509parse_crl( x509_crl *chain, const unsigned char *buf, int buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001383{
Paul Bakker96743fc2011-02-12 14:30:57 +00001384 int ret, len, use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001385 unsigned char *p, *end;
1386 x509_crl *crl;
Paul Bakker96743fc2011-02-12 14:30:57 +00001387#if defined(POLARSSL_PEM_C)
1388 pem_context pem;
1389#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001390
1391 crl = chain;
1392
1393 /*
1394 * Check for valid input
1395 */
1396 if( crl == NULL || buf == NULL )
1397 return( 1 );
1398
1399 while( crl->version != 0 && crl->next != NULL )
1400 crl = crl->next;
1401
1402 /*
1403 * Add new CRL on the end of the chain if needed.
1404 */
1405 if ( crl->version != 0 && crl->next == NULL)
1406 {
1407 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1408
Paul Bakker7d06ad22009-05-02 15:53:56 +00001409 if( crl->next == NULL )
1410 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001411 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001412 return( 1 );
1413 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001414
Paul Bakker7d06ad22009-05-02 15:53:56 +00001415 crl = crl->next;
1416 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001417 }
1418
Paul Bakker96743fc2011-02-12 14:30:57 +00001419#if defined(POLARSSL_PEM_C)
1420 pem_init( &pem );
1421 ret = pem_read_buffer( &pem,
1422 "-----BEGIN X509 CRL-----",
1423 "-----END X509 CRL-----",
1424 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001425
Paul Bakker96743fc2011-02-12 14:30:57 +00001426 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001427 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001428 /*
1429 * Was PEM encoded
1430 */
1431 buflen -= use_len;
1432 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001433
1434 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001435 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001436 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001437 p = pem.buf;
1438 pem.buf = NULL;
1439 len = pem.buflen;
1440 pem_free( &pem );
1441 }
1442 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
1443 {
1444 pem_free( &pem );
1445 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001446 }
1447 else
1448 {
1449 /*
1450 * nope, copy the raw DER data
1451 */
1452 p = (unsigned char *) malloc( len = buflen );
1453
1454 if( p == NULL )
1455 return( 1 );
1456
1457 memcpy( p, buf, buflen );
1458
1459 buflen = 0;
1460 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001461#else
1462 p = (unsigned char *) malloc( len = buflen );
1463
1464 if( p == NULL )
1465 return( 1 );
1466
1467 memcpy( p, buf, buflen );
1468
1469 buflen = 0;
1470#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001471
1472 crl->raw.p = p;
1473 crl->raw.len = len;
1474 end = p + len;
1475
1476 /*
1477 * CertificateList ::= SEQUENCE {
1478 * tbsCertList TBSCertList,
1479 * signatureAlgorithm AlgorithmIdentifier,
1480 * signatureValue BIT STRING }
1481 */
1482 if( ( ret = asn1_get_tag( &p, end, &len,
1483 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1484 {
1485 x509_crl_free( crl );
1486 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1487 }
1488
1489 if( len != (int) ( end - p ) )
1490 {
1491 x509_crl_free( crl );
1492 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1493 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1494 }
1495
1496 /*
1497 * TBSCertList ::= SEQUENCE {
1498 */
1499 crl->tbs.p = p;
1500
1501 if( ( ret = asn1_get_tag( &p, end, &len,
1502 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1503 {
1504 x509_crl_free( crl );
1505 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
1506 }
1507
1508 end = p + len;
1509 crl->tbs.len = end - crl->tbs.p;
1510
1511 /*
1512 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1513 * -- if present, MUST be v2
1514 *
1515 * signature AlgorithmIdentifier
1516 */
1517 if( ( ret = x509_get_version( &p, end, &crl->version ) ) != 0 ||
1518 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1519 {
1520 x509_crl_free( crl );
1521 return( ret );
1522 }
1523
1524 crl->version++;
1525
1526 if( crl->version > 2 )
1527 {
1528 x509_crl_free( crl );
1529 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1530 }
1531
Paul Bakker27d66162010-03-17 06:56:01 +00001532 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_alg ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001533 {
1534 x509_crl_free( crl );
1535 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1536 }
1537
1538 /*
1539 * issuer Name
1540 */
1541 crl->issuer_raw.p = p;
1542
1543 if( ( ret = asn1_get_tag( &p, end, &len,
1544 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1545 {
1546 x509_crl_free( crl );
1547 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
1548 }
1549
1550 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1551 {
1552 x509_crl_free( crl );
1553 return( ret );
1554 }
1555
1556 crl->issuer_raw.len = p - crl->issuer_raw.p;
1557
1558 /*
1559 * thisUpdate Time
1560 * nextUpdate Time OPTIONAL
1561 */
Paul Bakker91200182010-02-18 21:26:15 +00001562 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001563 {
1564 x509_crl_free( crl );
1565 return( ret );
1566 }
1567
Paul Bakker91200182010-02-18 21:26:15 +00001568 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001569 {
Paul Bakker635f4b42009-07-20 20:34:41 +00001570 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE |
Paul Bakker9be19372009-07-27 20:21:53 +00001571 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
1572 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE |
1573 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001574 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001575 x509_crl_free( crl );
1576 return( ret );
1577 }
1578 }
1579
1580 /*
1581 * revokedCertificates SEQUENCE OF SEQUENCE {
1582 * userCertificate CertificateSerialNumber,
1583 * revocationDate Time,
1584 * crlEntryExtensions Extensions OPTIONAL
1585 * -- if present, MUST be v2
1586 * } OPTIONAL
1587 */
1588 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1589 {
1590 x509_crl_free( crl );
1591 return( ret );
1592 }
1593
1594 /*
1595 * crlExtensions EXPLICIT Extensions OPTIONAL
1596 * -- if present, MUST be v2
1597 */
1598 if( crl->version == 2 )
1599 {
1600 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1601
1602 if( ret != 0 )
1603 {
1604 x509_crl_free( crl );
1605 return( ret );
1606 }
1607 }
1608
1609 if( p != end )
1610 {
1611 x509_crl_free( crl );
1612 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1613 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1614 }
1615
1616 end = crl->raw.p + crl->raw.len;
1617
1618 /*
1619 * signatureAlgorithm AlgorithmIdentifier,
1620 * signatureValue BIT STRING
1621 */
1622 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1623 {
1624 x509_crl_free( crl );
1625 return( ret );
1626 }
1627
1628 if( memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
1629 {
1630 x509_crl_free( crl );
1631 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1632 }
1633
1634 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1635 {
1636 x509_crl_free( crl );
1637 return( ret );
1638 }
1639
1640 if( p != end )
1641 {
1642 x509_crl_free( crl );
1643 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1644 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1645 }
1646
1647 if( buflen > 0 )
1648 {
1649 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1650
Paul Bakker7d06ad22009-05-02 15:53:56 +00001651 if( crl->next == NULL )
1652 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001653 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001654 return( 1 );
1655 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001656
Paul Bakker7d06ad22009-05-02 15:53:56 +00001657 crl = crl->next;
1658 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001659
1660 return( x509parse_crl( crl, buf, buflen ) );
1661 }
1662
1663 return( 0 );
1664}
1665
1666/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001667 * Load all data from a file into a given buffer.
1668 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001669int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001670{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001671 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001672
Paul Bakkerd98030e2009-05-02 15:13:40 +00001673 if( ( f = fopen( path, "rb" ) ) == NULL )
1674 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001675
Paul Bakkerd98030e2009-05-02 15:13:40 +00001676 fseek( f, 0, SEEK_END );
1677 *n = (size_t) ftell( f );
1678 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001679
Paul Bakkerd98030e2009-05-02 15:13:40 +00001680 if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
1681 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001682
Paul Bakkerd98030e2009-05-02 15:13:40 +00001683 if( fread( *buf, 1, *n, f ) != *n )
1684 {
1685 fclose( f );
1686 free( *buf );
1687 return( 1 );
1688 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001689
Paul Bakkerd98030e2009-05-02 15:13:40 +00001690 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001691
Paul Bakkerd98030e2009-05-02 15:13:40 +00001692 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001693
Paul Bakkerd98030e2009-05-02 15:13:40 +00001694 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001695}
1696
1697/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001698 * Load one or more certificates and add them to the chained list
1699 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001700int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001701{
1702 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001703 size_t n;
1704 unsigned char *buf;
1705
Paul Bakker2b245eb2009-04-19 18:44:26 +00001706 if ( load_file( path, &buf, &n ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001707 return( 1 );
1708
Paul Bakker5121ce52009-01-03 21:22:43 +00001709 ret = x509parse_crt( chain, buf, (int) n );
1710
1711 memset( buf, 0, n + 1 );
1712 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001713
1714 return( ret );
1715}
1716
Paul Bakkerd98030e2009-05-02 15:13:40 +00001717/*
1718 * Load one or more CRLs and add them to the chained list
1719 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001720int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001721{
1722 int ret;
1723 size_t n;
1724 unsigned char *buf;
1725
1726 if ( load_file( path, &buf, &n ) )
1727 return( 1 );
1728
1729 ret = x509parse_crl( chain, buf, (int) n );
1730
1731 memset( buf, 0, n + 1 );
1732 free( buf );
1733
1734 return( ret );
1735}
1736
Paul Bakker5121ce52009-01-03 21:22:43 +00001737/*
1738 * Parse a private RSA key
1739 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001740int x509parse_key( rsa_context *rsa, const unsigned char *key, int keylen,
1741 const unsigned char *pwd, int pwdlen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001742{
Paul Bakker96743fc2011-02-12 14:30:57 +00001743 int ret, len;
Paul Bakker5121ce52009-01-03 21:22:43 +00001744 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00001745#if defined(POLARSSL_PEM_C)
1746 pem_context pem;
Paul Bakker5121ce52009-01-03 21:22:43 +00001747
Paul Bakker96743fc2011-02-12 14:30:57 +00001748 pem_init( &pem );
1749 ret = pem_read_buffer( &pem,
1750 "-----BEGIN RSA PRIVATE KEY-----",
1751 "-----END RSA PRIVATE KEY-----",
1752 key, pwd, pwdlen, &len );
Paul Bakker5121ce52009-01-03 21:22:43 +00001753
Paul Bakker96743fc2011-02-12 14:30:57 +00001754 if( ret == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001755 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001756 /*
1757 * Was PEM encoded
1758 */
1759 keylen = pem.buflen;
Paul Bakker5121ce52009-01-03 21:22:43 +00001760 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001761 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
Paul Bakkerff60ee62010-03-16 21:09:09 +00001762 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001763 pem_free( &pem );
1764 return( ret );
Paul Bakkerff60ee62010-03-16 21:09:09 +00001765 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001766
Paul Bakker96743fc2011-02-12 14:30:57 +00001767 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
1768#else
1769 p = (unsigned char *) key;
1770#endif
1771 end = p + keylen;
1772
Paul Bakker5121ce52009-01-03 21:22:43 +00001773 memset( rsa, 0, sizeof( rsa_context ) );
1774
Paul Bakker5121ce52009-01-03 21:22:43 +00001775 /*
1776 * RSAPrivateKey ::= SEQUENCE {
1777 * version Version,
1778 * modulus INTEGER, -- n
1779 * publicExponent INTEGER, -- e
1780 * privateExponent INTEGER, -- d
1781 * prime1 INTEGER, -- p
1782 * prime2 INTEGER, -- q
1783 * exponent1 INTEGER, -- d mod (p-1)
1784 * exponent2 INTEGER, -- d mod (q-1)
1785 * coefficient INTEGER, -- (inverse of q) mod p
1786 * otherPrimeInfos OtherPrimeInfos OPTIONAL
1787 * }
1788 */
1789 if( ( ret = asn1_get_tag( &p, end, &len,
1790 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1791 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001792#if defined(POLARSSL_PEM_C)
1793 pem_free( &pem );
1794#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001795 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001796 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001797 }
1798
1799 end = p + len;
1800
1801 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
1802 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001803#if defined(POLARSSL_PEM_C)
1804 pem_free( &pem );
1805#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001806 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001807 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001808 }
1809
1810 if( rsa->ver != 0 )
1811 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001812#if defined(POLARSSL_PEM_C)
1813 pem_free( &pem );
1814#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001815 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001816 return( ret | POLARSSL_ERR_X509_KEY_INVALID_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001817 }
1818
1819 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
1820 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
1821 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
1822 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
1823 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
1824 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
1825 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
1826 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
1827 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001828#if defined(POLARSSL_PEM_C)
1829 pem_free( &pem );
1830#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001831 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001832 return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001833 }
1834
1835 rsa->len = mpi_size( &rsa->N );
1836
1837 if( p != end )
1838 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001839#if defined(POLARSSL_PEM_C)
1840 pem_free( &pem );
1841#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001842 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001843 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT |
1844 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001845 }
1846
1847 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
1848 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001849#if defined(POLARSSL_PEM_C)
1850 pem_free( &pem );
1851#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001852 rsa_free( rsa );
1853 return( ret );
1854 }
1855
Paul Bakker96743fc2011-02-12 14:30:57 +00001856#if defined(POLARSSL_PEM_C)
1857 pem_free( &pem );
1858#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001859
1860 return( 0 );
1861}
1862
1863/*
1864 * Load and parse a private RSA key
1865 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001866int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
Paul Bakker5121ce52009-01-03 21:22:43 +00001867{
1868 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001869 size_t n;
1870 unsigned char *buf;
1871
Paul Bakker2b245eb2009-04-19 18:44:26 +00001872 if ( load_file( path, &buf, &n ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001873 return( 1 );
1874
Paul Bakker5121ce52009-01-03 21:22:43 +00001875 if( pwd == NULL )
1876 ret = x509parse_key( rsa, buf, (int) n, NULL, 0 );
1877 else
1878 ret = x509parse_key( rsa, buf, (int) n,
1879 (unsigned char *) pwd, strlen( pwd ) );
1880
1881 memset( buf, 0, n + 1 );
1882 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001883
1884 return( ret );
1885}
1886
Paul Bakker1b57b062011-01-06 15:48:19 +00001887/*
1888 * Parse DHM parameters
1889 */
1890int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, int dhminlen )
1891{
1892 int ret, len;
Paul Bakker1b57b062011-01-06 15:48:19 +00001893 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00001894#if defined(POLARSSL_PEM_C)
1895 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00001896
Paul Bakker96743fc2011-02-12 14:30:57 +00001897 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00001898
Paul Bakker96743fc2011-02-12 14:30:57 +00001899 ret = pem_read_buffer( &pem,
1900 "-----BEGIN DH PARAMETERS-----",
1901 "-----END DH PARAMETERS-----",
1902 dhmin, NULL, 0, &dhminlen );
1903
1904 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00001905 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001906 /*
1907 * Was PEM encoded
1908 */
1909 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00001910 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001911 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00001912 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001913 pem_free( &pem );
1914 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00001915 }
1916
Paul Bakker96743fc2011-02-12 14:30:57 +00001917 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
1918#else
1919 p = (unsigned char *) dhmin;
1920#endif
1921 end = p + dhminlen;
1922
Paul Bakker1b57b062011-01-06 15:48:19 +00001923 memset( dhm, 0, sizeof( dhm_context ) );
1924
Paul Bakker1b57b062011-01-06 15:48:19 +00001925 /*
1926 * DHParams ::= SEQUENCE {
1927 * prime INTEGER, -- P
1928 * generator INTEGER, -- g
1929 * }
1930 */
1931 if( ( ret = asn1_get_tag( &p, end, &len,
1932 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1933 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001934#if defined(POLARSSL_PEM_C)
1935 pem_free( &pem );
1936#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00001937 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
1938 }
1939
1940 end = p + len;
1941
1942 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
1943 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
1944 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001945#if defined(POLARSSL_PEM_C)
1946 pem_free( &pem );
1947#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00001948 dhm_free( dhm );
1949 return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
1950 }
1951
1952 if( p != end )
1953 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001954#if defined(POLARSSL_PEM_C)
1955 pem_free( &pem );
1956#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00001957 dhm_free( dhm );
1958 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT |
1959 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1960 }
1961
Paul Bakker96743fc2011-02-12 14:30:57 +00001962#if defined(POLARSSL_PEM_C)
1963 pem_free( &pem );
1964#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00001965
1966 return( 0 );
1967}
1968
1969/*
1970 * Load and parse a private RSA key
1971 */
1972int x509parse_dhmfile( dhm_context *dhm, const char *path )
1973{
1974 int ret;
1975 size_t n;
1976 unsigned char *buf;
1977
1978 if ( load_file( path, &buf, &n ) )
1979 return( 1 );
1980
1981 ret = x509parse_dhm( dhm, buf, (int) n);
1982
1983 memset( buf, 0, n + 1 );
1984 free( buf );
1985
1986 return( ret );
1987}
1988
Paul Bakker5121ce52009-01-03 21:22:43 +00001989#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00001990#include <stdarg.h>
1991
1992#if !defined vsnprintf
1993#define vsnprintf _vsnprintf
1994#endif // vsnprintf
1995
1996/*
1997 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
1998 * Result value is not size of buffer needed, but -1 if no fit is possible.
1999 *
2000 * This fuction tries to 'fix' this by at least suggesting enlarging the
2001 * size by 20.
2002 */
2003int compat_snprintf(char *str, size_t size, const char *format, ...)
2004{
2005 va_list ap;
2006 int res = -1;
2007
2008 va_start( ap, format );
2009
2010 res = vsnprintf( str, size, format, ap );
2011
2012 va_end( ap );
2013
2014 // No quick fix possible
2015 if ( res < 0 )
2016 return( size + 20 );
2017
2018 return res;
2019}
2020
2021#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002022#endif
2023
Paul Bakkerd98030e2009-05-02 15:13:40 +00002024#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2025
2026#define SAFE_SNPRINTF() \
2027{ \
2028 if( ret == -1 ) \
2029 return( -1 ); \
2030 \
2031 if ( ret > n ) { \
2032 p[n - 1] = '\0'; \
2033 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2034 } \
2035 \
2036 n -= ret; \
2037 p += ret; \
2038}
2039
Paul Bakker5121ce52009-01-03 21:22:43 +00002040/*
2041 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002042 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002043 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002044int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002045{
Paul Bakkerd98030e2009-05-02 15:13:40 +00002046 int i, ret, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002047 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002048 const x509_name *name;
Paul Bakker5121ce52009-01-03 21:22:43 +00002049 char s[128], *p;
2050
2051 memset( s, 0, sizeof( s ) );
2052
2053 name = dn;
2054 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002055 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002056
2057 while( name != NULL )
2058 {
Paul Bakker74111d32011-01-15 16:57:55 +00002059 if( name != dn )
2060 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002061 ret = snprintf( p, n, ", " );
2062 SAFE_SNPRINTF();
2063 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002064
2065 if( memcmp( name->oid.p, OID_X520, 2 ) == 0 )
2066 {
2067 switch( name->oid.p[2] )
2068 {
2069 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002070 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002071
2072 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002073 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002074
2075 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002076 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002077
2078 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002079 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002080
2081 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002082 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002083
2084 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002085 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002086
2087 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002088 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002089 name->oid.p[2] );
2090 break;
2091 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002092 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002093 }
2094 else if( memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
2095 {
2096 switch( name->oid.p[8] )
2097 {
2098 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002099 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002100
2101 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002102 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002103 name->oid.p[8] );
2104 break;
2105 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002106 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002107 }
2108 else
Paul Bakker74111d32011-01-15 16:57:55 +00002109 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002110 ret = snprintf( p, n, "\?\?=" );
Paul Bakker74111d32011-01-15 16:57:55 +00002111 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002112 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002113
2114 for( i = 0; i < name->val.len; i++ )
2115 {
2116 if( i >= (int) sizeof( s ) - 1 )
2117 break;
2118
2119 c = name->val.p[i];
2120 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2121 s[i] = '?';
2122 else s[i] = c;
2123 }
2124 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002125 ret = snprintf( p, n, "%s", s );
2126 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002127 name = name->next;
2128 }
2129
Paul Bakkerd98030e2009-05-02 15:13:40 +00002130 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002131}
2132
2133/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002134 * Store the serial in printable form into buf; no more
2135 * than size characters will be written
2136 */
2137int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2138{
2139 int i, ret, nr, n;
2140 char *p;
2141
2142 p = buf;
2143 n = size;
2144
2145 nr = ( serial->len <= 32 )
2146 ? serial->len : 32;
2147
2148 for( i = 0; i < nr; i++ )
2149 {
2150 ret = snprintf( p, n, "%02X%s",
2151 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2152 SAFE_SNPRINTF();
2153 }
2154
2155 return( size - n );
2156}
2157
2158/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002159 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002160 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002161int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2162 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002163{
Paul Bakkerdd476992011-01-16 21:34:59 +00002164 int n, ret;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002165 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00002166
2167 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002168 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002169
Paul Bakkerd98030e2009-05-02 15:13:40 +00002170 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002171 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002172 SAFE_SNPRINTF();
2173 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002174 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002175 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002176
Paul Bakkerdd476992011-01-16 21:34:59 +00002177 ret = x509parse_serial_gets( p, n, &crt->serial);
2178 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002179
Paul Bakkerd98030e2009-05-02 15:13:40 +00002180 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2181 SAFE_SNPRINTF();
2182 ret = x509parse_dn_gets( p, n, &crt->issuer );
2183 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002184
Paul Bakkerd98030e2009-05-02 15:13:40 +00002185 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2186 SAFE_SNPRINTF();
2187 ret = x509parse_dn_gets( p, n, &crt->subject );
2188 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002189
Paul Bakkerd98030e2009-05-02 15:13:40 +00002190 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002191 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2192 crt->valid_from.year, crt->valid_from.mon,
2193 crt->valid_from.day, crt->valid_from.hour,
2194 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002195 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002196
Paul Bakkerd98030e2009-05-02 15:13:40 +00002197 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002198 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2199 crt->valid_to.year, crt->valid_to.mon,
2200 crt->valid_to.day, crt->valid_to.hour,
2201 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002202 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002203
Paul Bakkerd98030e2009-05-02 15:13:40 +00002204 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2205 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002206
Paul Bakker27d66162010-03-17 06:56:01 +00002207 switch( crt->sig_alg )
Paul Bakker5121ce52009-01-03 21:22:43 +00002208 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002209 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2210 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2211 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2212 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2213 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2214 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2215 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2216 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2217 default: ret = snprintf( p, n, "???" ); break;
2218 }
2219 SAFE_SNPRINTF();
2220
2221 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
2222 crt->rsa.N.n * (int) sizeof( unsigned long ) * 8 );
2223 SAFE_SNPRINTF();
2224
2225 return( size - n );
2226}
2227
Paul Bakker74111d32011-01-15 16:57:55 +00002228/* Compare a given OID string with an OID x509_buf * */
2229#define OID_CMP(oid_str, oid_buf) \
2230 ( ( OID_SIZE(oid_str) == (oid_buf)->len ) && \
2231 memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0)
2232
2233/*
2234 * Return an informational string describing the given OID
2235 */
2236const char *x509_oid_get_description( x509_buf *oid )
2237{
2238 if ( oid == NULL )
2239 return ( NULL );
2240
2241 else if( OID_CMP( OID_SERVER_AUTH, oid ) )
2242 return( STRING_SERVER_AUTH );
2243
2244 else if( OID_CMP( OID_CLIENT_AUTH, oid ) )
2245 return( STRING_CLIENT_AUTH );
2246
2247 else if( OID_CMP( OID_CODE_SIGNING, oid ) )
2248 return( STRING_CODE_SIGNING );
2249
2250 else if( OID_CMP( OID_EMAIL_PROTECTION, oid ) )
2251 return( STRING_EMAIL_PROTECTION );
2252
2253 else if( OID_CMP( OID_TIME_STAMPING, oid ) )
2254 return( STRING_TIME_STAMPING );
2255
2256 else if( OID_CMP( OID_OCSP_SIGNING, oid ) )
2257 return( STRING_OCSP_SIGNING );
2258
2259 return( NULL );
2260}
2261
2262/* Return the x.y.z.... style numeric string for the given OID */
2263int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2264{
2265 int ret, n, i;
2266 unsigned int value;
2267 char *p;
2268
2269 p = buf;
2270 n = size;
2271
2272 /* First byte contains first two dots */
2273 if( oid->len > 0 )
2274 {
2275 ret = snprintf( p, n, "%d.%d", oid->p[0]/40, oid->p[0]%40 );
2276 SAFE_SNPRINTF();
2277 }
2278
2279 /* TODO: value can overflow in value. */
2280 value = 0;
2281 for( i=1; i < oid->len; i++ )
2282 {
2283 value <<= 7;
2284 value += oid->p[i] & 0x7F;
2285
2286 if( !( oid->p[i] & 0x80 ) )
2287 {
2288 /* Last byte */
2289 ret = snprintf( p, n, ".%d", value );
2290 SAFE_SNPRINTF();
2291 value = 0;
2292 }
2293 }
2294
2295 return( size - n );
2296}
2297
Paul Bakkerd98030e2009-05-02 15:13:40 +00002298/*
2299 * Return an informational string about the CRL.
2300 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002301int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2302 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002303{
2304 int i, n, nr, ret;
2305 char *p;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002306 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002307
2308 p = buf;
2309 n = size;
2310
2311 ret = snprintf( p, n, "%sCRL version : %d",
2312 prefix, crl->version );
2313 SAFE_SNPRINTF();
2314
2315 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2316 SAFE_SNPRINTF();
2317 ret = x509parse_dn_gets( p, n, &crl->issuer );
2318 SAFE_SNPRINTF();
2319
2320 ret = snprintf( p, n, "\n%sthis update : " \
2321 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2322 crl->this_update.year, crl->this_update.mon,
2323 crl->this_update.day, crl->this_update.hour,
2324 crl->this_update.min, crl->this_update.sec );
2325 SAFE_SNPRINTF();
2326
2327 ret = snprintf( p, n, "\n%snext update : " \
2328 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2329 crl->next_update.year, crl->next_update.mon,
2330 crl->next_update.day, crl->next_update.hour,
2331 crl->next_update.min, crl->next_update.sec );
2332 SAFE_SNPRINTF();
2333
2334 entry = &crl->entry;
2335
2336 ret = snprintf( p, n, "\n%sRevoked certificates:",
2337 prefix );
2338 SAFE_SNPRINTF();
2339
Paul Bakker9be19372009-07-27 20:21:53 +00002340 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002341 {
2342 ret = snprintf( p, n, "\n%sserial number: ",
2343 prefix );
2344 SAFE_SNPRINTF();
2345
2346 nr = ( entry->serial.len <= 32 )
2347 ? entry->serial.len : 32;
2348
Paul Bakker74111d32011-01-15 16:57:55 +00002349 for( i = 0; i < nr; i++ )
2350 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002351 ret = snprintf( p, n, "%02X%s",
2352 entry->serial.p[i], ( i < nr - 1 ) ? ":" : "" );
2353 SAFE_SNPRINTF();
2354 }
2355
2356 ret = snprintf( p, n, " revocation date: " \
2357 "%04d-%02d-%02d %02d:%02d:%02d",
2358 entry->revocation_date.year, entry->revocation_date.mon,
2359 entry->revocation_date.day, entry->revocation_date.hour,
2360 entry->revocation_date.min, entry->revocation_date.sec );
2361 SAFE_SNPRINTF();
2362
2363 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002364 }
2365
Paul Bakkerd98030e2009-05-02 15:13:40 +00002366 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2367 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002368
Paul Bakker27d66162010-03-17 06:56:01 +00002369 switch( crl->sig_alg )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002370 {
2371 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2372 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2373 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2374 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2375 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2376 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2377 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2378 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2379 default: ret = snprintf( p, n, "???" ); break;
2380 }
2381 SAFE_SNPRINTF();
2382
Paul Bakker1e27bb22009-07-19 20:25:25 +00002383 ret = snprintf( p, n, "\n" );
2384 SAFE_SNPRINTF();
2385
Paul Bakkerd98030e2009-05-02 15:13:40 +00002386 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002387}
2388
2389/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00002390 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00002391 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002392int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00002393{
2394 struct tm *lt;
2395 time_t tt;
2396
2397 tt = time( NULL );
2398 lt = localtime( &tt );
2399
Paul Bakker40ea7de2009-05-03 10:18:48 +00002400 if( lt->tm_year > to->year - 1900 )
2401 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002402
Paul Bakker40ea7de2009-05-03 10:18:48 +00002403 if( lt->tm_year == to->year - 1900 &&
2404 lt->tm_mon > to->mon - 1 )
2405 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002406
Paul Bakker40ea7de2009-05-03 10:18:48 +00002407 if( lt->tm_year == to->year - 1900 &&
2408 lt->tm_mon == to->mon - 1 &&
2409 lt->tm_mday > to->day )
2410 return( 1 );
2411
Paul Bakkerb6194992011-01-16 21:40:22 +00002412 if( lt->tm_year == to->year - 1900 &&
2413 lt->tm_mon == to->mon - 1 &&
2414 lt->tm_mday == to->day &&
2415 lt->tm_hour > to->hour - 1)
2416 return( 1 );
2417
2418 if( lt->tm_year == to->year - 1900 &&
2419 lt->tm_mon == to->mon - 1 &&
2420 lt->tm_mday == to->day &&
2421 lt->tm_hour == to->hour - 1 &&
2422 lt->tm_min > to->min - 1 )
2423 return( 1 );
2424
2425 if( lt->tm_year == to->year - 1900 &&
2426 lt->tm_mon == to->mon - 1 &&
2427 lt->tm_mday == to->day &&
2428 lt->tm_hour == to->hour - 1 &&
2429 lt->tm_min == to->min - 1 &&
2430 lt->tm_sec > to->sec - 1 )
2431 return( 1 );
2432
Paul Bakker40ea7de2009-05-03 10:18:48 +00002433 return( 0 );
2434}
2435
2436/*
2437 * Return 1 if the certificate is revoked, or 0 otherwise.
2438 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002439int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002440{
Paul Bakkerff60ee62010-03-16 21:09:09 +00002441 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00002442
2443 while( cur != NULL && cur->serial.len != 0 )
2444 {
Paul Bakkera056efc2011-01-16 21:38:35 +00002445 if( crt->serial.len == cur->serial.len &&
2446 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002447 {
2448 if( x509parse_time_expired( &cur->revocation_date ) )
2449 return( 1 );
2450 }
2451
2452 cur = cur->next;
2453 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002454
2455 return( 0 );
2456}
2457
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002458/*
2459 * Wrapper for x509 hashes.
2460 *
Paul Bakker0f5f72e2011-01-18 14:58:55 +00002461 * \param out Buffer to receive the hash (Should be at least 64 bytes)
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002462 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002463static void x509_hash( const unsigned char *in, int len, int alg,
Paul Bakker5121ce52009-01-03 21:22:43 +00002464 unsigned char *out )
2465{
2466 switch( alg )
2467 {
Paul Bakker40e46942009-01-03 21:51:57 +00002468#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002469 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002470#endif
Paul Bakker40e46942009-01-03 21:51:57 +00002471#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002472 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002473#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002474#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002475 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002476#endif
2477#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002478 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002479#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00002480#if defined(POLARSSL_SHA2_C)
2481 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
2482 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
2483#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00002484#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002485 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
2486 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
2487#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002488 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002489 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002490 break;
2491 }
2492}
2493
2494/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00002495 * Check that the given certificate is valid accoring to the CRL.
2496 */
2497static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
2498 x509_crl *crl_list)
2499{
2500 int flags = 0;
2501 int hash_id;
2502 unsigned char hash[64];
2503
2504 /*
2505 * TODO: What happens if no CRL is present?
2506 * Suggestion: Revocation state should be unknown if no CRL is present.
2507 * For backwards compatibility this is not yet implemented.
2508 */
2509
2510 while( ca != NULL && crl_list != NULL && crl_list->version != 0 )
2511 {
2512 if( crl_list->issuer_raw.len != ca->subject_raw.len ||
2513 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
2514 crl_list->issuer_raw.len ) != 0 )
2515 {
2516 crl_list = crl_list->next;
2517 continue;
2518 }
2519
2520 /*
2521 * Check if CRL is correctly signed by the trusted CA
2522 */
2523 hash_id = crl_list->sig_alg;
2524
2525 x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
2526
2527 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, hash_id,
2528 0, hash, crl_list->sig.p ) == 0 )
2529 {
2530 /*
2531 * CRL is not trusted
2532 */
2533 flags |= BADCRL_NOT_TRUSTED;
2534 break;
2535 }
2536
2537 /*
2538 * Check for validity of CRL (Do not drop out)
2539 */
2540 if( x509parse_time_expired( &crl_list->next_update ) )
2541 flags |= BADCRL_EXPIRED;
2542
2543 /*
2544 * Check if certificate is revoked
2545 */
2546 if( x509parse_revoked(crt, crl_list) )
2547 {
2548 flags |= BADCERT_REVOKED;
2549 break;
2550 }
2551
2552 crl_list = crl_list->next;
2553 }
2554 return flags;
2555}
2556
2557/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002558 * Verify the certificate validity
2559 */
2560int x509parse_verify( x509_cert *crt,
2561 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00002562 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002563 const char *cn, int *flags,
2564 int (*f_vrfy)(void *, x509_cert *, int, int),
2565 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00002566{
2567 int cn_len;
2568 int hash_id;
2569 int pathlen;
Paul Bakker76fd75a2011-01-16 21:12:10 +00002570 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00002571 x509_name *name;
Paul Bakker4593aea2009-02-09 22:32:35 +00002572 unsigned char hash[64];
Paul Bakker5121ce52009-01-03 21:22:43 +00002573
Paul Bakker40ea7de2009-05-03 10:18:48 +00002574 *flags = 0;
2575
2576 if( x509parse_time_expired( &crt->valid_to ) )
2577 *flags = BADCERT_EXPIRED;
Paul Bakker5121ce52009-01-03 21:22:43 +00002578
2579 if( cn != NULL )
2580 {
2581 name = &crt->subject;
2582 cn_len = strlen( cn );
2583
2584 while( name != NULL )
2585 {
2586 if( memcmp( name->oid.p, OID_CN, 3 ) == 0 &&
2587 memcmp( name->val.p, cn, cn_len ) == 0 &&
2588 name->val.len == cn_len )
2589 break;
2590
2591 name = name->next;
2592 }
2593
2594 if( name == NULL )
2595 *flags |= BADCERT_CN_MISMATCH;
2596 }
2597
Paul Bakker5121ce52009-01-03 21:22:43 +00002598 /*
2599 * Iterate upwards in the given cert chain,
2600 * ignoring any upper cert with CA != TRUE.
2601 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00002602 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002603
2604 pathlen = 1;
2605
Paul Bakker76fd75a2011-01-16 21:12:10 +00002606 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002607 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002608 if( parent->ca_istrue == 0 ||
2609 crt->issuer_raw.len != parent->subject_raw.len ||
2610 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00002611 crt->issuer_raw.len ) != 0 )
2612 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002613 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002614 continue;
2615 }
2616
Paul Bakker27d66162010-03-17 06:56:01 +00002617 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00002618
2619 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2620
Paul Bakker76fd75a2011-01-16 21:12:10 +00002621 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, hash_id, 0, hash,
2622 crt->sig.p ) != 0 )
2623 *flags |= BADCERT_NOT_TRUSTED;
2624
2625 /* Check trusted CA's CRL for the given crt */
2626 *flags |= x509parse_verifycrl(crt, parent, ca_crl);
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002627
2628 /* crt is verified to be a child of the parent cur, call verify callback */
Paul Bakker74111d32011-01-15 16:57:55 +00002629 if( NULL != f_vrfy )
2630 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002631 if( f_vrfy( p_vrfy, crt, pathlen - 1, ( *flags == 0 ) ) != 0 )
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002632 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker76fd75a2011-01-16 21:12:10 +00002633 else
2634 *flags = 0;
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002635 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00002636 else if( *flags != 0 )
2637 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002638
2639 pathlen++;
2640
Paul Bakker76fd75a2011-01-16 21:12:10 +00002641 crt = parent;
2642 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002643 }
2644
2645 /*
Paul Bakker76fd75a2011-01-16 21:12:10 +00002646 * Attempt to validate topmost cert with our CA chain.
Paul Bakker5121ce52009-01-03 21:22:43 +00002647 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00002648 *flags |= BADCERT_NOT_TRUSTED;
2649
Paul Bakker7c6d4a42009-03-28 20:35:47 +00002650 while( trust_ca != NULL && trust_ca->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002651 {
2652 if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
2653 memcmp( crt->issuer_raw.p, trust_ca->subject_raw.p,
2654 crt->issuer_raw.len ) != 0 )
2655 {
2656 trust_ca = trust_ca->next;
2657 continue;
2658 }
2659
2660 if( trust_ca->max_pathlen > 0 &&
2661 trust_ca->max_pathlen < pathlen )
2662 break;
2663
Paul Bakker27d66162010-03-17 06:56:01 +00002664 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00002665
2666 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2667
2668 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
2669 0, hash, crt->sig.p ) == 0 )
2670 {
2671 /*
2672 * cert. is signed by a trusted CA
2673 */
2674 *flags &= ~BADCERT_NOT_TRUSTED;
2675 break;
2676 }
2677
2678 trust_ca = trust_ca->next;
2679 }
2680
Paul Bakker76fd75a2011-01-16 21:12:10 +00002681 /* Check trusted CA's CRL for the given crt */
2682 *flags |= x509parse_verifycrl( crt, trust_ca, ca_crl );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002683
2684 /* Verification succeeded, call callback on top cert */
Paul Bakker74111d32011-01-15 16:57:55 +00002685 if( NULL != f_vrfy )
2686 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002687 if( f_vrfy(p_vrfy, crt, pathlen-1, ( *flags == 0 ) ) != 0 )
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002688 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker76fd75a2011-01-16 21:12:10 +00002689 else
2690 *flags = 0;
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002691 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00002692 else if( *flags != 0 )
2693 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002694
Paul Bakker5121ce52009-01-03 21:22:43 +00002695 return( 0 );
2696}
2697
2698/*
2699 * Unallocate all certificate data
2700 */
2701void x509_free( x509_cert *crt )
2702{
2703 x509_cert *cert_cur = crt;
2704 x509_cert *cert_prv;
2705 x509_name *name_cur;
2706 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00002707 x509_sequence *seq_cur;
2708 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00002709
2710 if( crt == NULL )
2711 return;
2712
2713 do
2714 {
2715 rsa_free( &cert_cur->rsa );
2716
2717 name_cur = cert_cur->issuer.next;
2718 while( name_cur != NULL )
2719 {
2720 name_prv = name_cur;
2721 name_cur = name_cur->next;
2722 memset( name_prv, 0, sizeof( x509_name ) );
2723 free( name_prv );
2724 }
2725
2726 name_cur = cert_cur->subject.next;
2727 while( name_cur != NULL )
2728 {
2729 name_prv = name_cur;
2730 name_cur = name_cur->next;
2731 memset( name_prv, 0, sizeof( x509_name ) );
2732 free( name_prv );
2733 }
2734
Paul Bakker74111d32011-01-15 16:57:55 +00002735 seq_cur = cert_cur->ext_key_usage.next;
2736 while( seq_cur != NULL )
2737 {
2738 seq_prv = seq_cur;
2739 seq_cur = seq_cur->next;
2740 memset( seq_prv, 0, sizeof( x509_sequence ) );
2741 free( seq_prv );
2742 }
2743
Paul Bakker5121ce52009-01-03 21:22:43 +00002744 if( cert_cur->raw.p != NULL )
2745 {
2746 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
2747 free( cert_cur->raw.p );
2748 }
2749
2750 cert_cur = cert_cur->next;
2751 }
2752 while( cert_cur != NULL );
2753
2754 cert_cur = crt;
2755 do
2756 {
2757 cert_prv = cert_cur;
2758 cert_cur = cert_cur->next;
2759
2760 memset( cert_prv, 0, sizeof( x509_cert ) );
2761 if( cert_prv != crt )
2762 free( cert_prv );
2763 }
2764 while( cert_cur != NULL );
2765}
2766
Paul Bakkerd98030e2009-05-02 15:13:40 +00002767/*
2768 * Unallocate all CRL data
2769 */
2770void x509_crl_free( x509_crl *crl )
2771{
2772 x509_crl *crl_cur = crl;
2773 x509_crl *crl_prv;
2774 x509_name *name_cur;
2775 x509_name *name_prv;
2776 x509_crl_entry *entry_cur;
2777 x509_crl_entry *entry_prv;
2778
2779 if( crl == NULL )
2780 return;
2781
2782 do
2783 {
2784 name_cur = crl_cur->issuer.next;
2785 while( name_cur != NULL )
2786 {
2787 name_prv = name_cur;
2788 name_cur = name_cur->next;
2789 memset( name_prv, 0, sizeof( x509_name ) );
2790 free( name_prv );
2791 }
2792
2793 entry_cur = crl_cur->entry.next;
2794 while( entry_cur != NULL )
2795 {
2796 entry_prv = entry_cur;
2797 entry_cur = entry_cur->next;
2798 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
2799 free( entry_prv );
2800 }
2801
2802 if( crl_cur->raw.p != NULL )
2803 {
2804 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
2805 free( crl_cur->raw.p );
2806 }
2807
2808 crl_cur = crl_cur->next;
2809 }
2810 while( crl_cur != NULL );
2811
2812 crl_cur = crl;
2813 do
2814 {
2815 crl_prv = crl_cur;
2816 crl_cur = crl_cur->next;
2817
2818 memset( crl_prv, 0, sizeof( x509_crl ) );
2819 if( crl_prv != crl )
2820 free( crl_prv );
2821 }
2822 while( crl_cur != NULL );
2823}
2824
Paul Bakker40e46942009-01-03 21:51:57 +00002825#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002826
Paul Bakker40e46942009-01-03 21:51:57 +00002827#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00002828
2829/*
2830 * Checkup routine
2831 */
2832int x509_self_test( int verbose )
2833{
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002834#if defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00002835 int ret, i, j;
2836 x509_cert cacert;
2837 x509_cert clicert;
2838 rsa_context rsa;
Paul Bakker1b57b062011-01-06 15:48:19 +00002839 dhm_context dhm;
Paul Bakker5121ce52009-01-03 21:22:43 +00002840
2841 if( verbose != 0 )
2842 printf( " X.509 certificate load: " );
2843
2844 memset( &clicert, 0, sizeof( x509_cert ) );
2845
2846 ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
2847 strlen( test_cli_crt ) );
2848 if( ret != 0 )
2849 {
2850 if( verbose != 0 )
2851 printf( "failed\n" );
2852
2853 return( ret );
2854 }
2855
2856 memset( &cacert, 0, sizeof( x509_cert ) );
2857
2858 ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
2859 strlen( test_ca_crt ) );
2860 if( ret != 0 )
2861 {
2862 if( verbose != 0 )
2863 printf( "failed\n" );
2864
2865 return( ret );
2866 }
2867
2868 if( verbose != 0 )
2869 printf( "passed\n X.509 private key load: " );
2870
2871 i = strlen( test_ca_key );
2872 j = strlen( test_ca_pwd );
2873
2874 if( ( ret = x509parse_key( &rsa,
2875 (unsigned char *) test_ca_key, i,
2876 (unsigned char *) test_ca_pwd, j ) ) != 0 )
2877 {
2878 if( verbose != 0 )
2879 printf( "failed\n" );
2880
2881 return( ret );
2882 }
2883
2884 if( verbose != 0 )
2885 printf( "passed\n X.509 signature verify: ");
2886
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002887 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &i, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00002888 if( ret != 0 )
2889 {
2890 if( verbose != 0 )
2891 printf( "failed\n" );
2892
2893 return( ret );
2894 }
2895
2896 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00002897 printf( "passed\n X.509 DHM parameter load: " );
2898
2899 i = strlen( test_dhm_params );
2900 j = strlen( test_ca_pwd );
2901
2902 if( ( ret = x509parse_dhm( &dhm, (unsigned char *) test_dhm_params, i ) ) != 0 )
2903 {
2904 if( verbose != 0 )
2905 printf( "failed\n" );
2906
2907 return( ret );
2908 }
2909
2910 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002911 printf( "passed\n\n" );
2912
2913 x509_free( &cacert );
2914 x509_free( &clicert );
2915 rsa_free( &rsa );
Paul Bakker1b57b062011-01-06 15:48:19 +00002916 dhm_free( &dhm );
Paul Bakker5121ce52009-01-03 21:22:43 +00002917
2918 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002919#else
2920 ((void) verbose);
2921 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
2922#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002923}
2924
2925#endif
2926
2927#endif