blob: b37c4c21765efc1fc709134a6af52385ed9b950b [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"
42#include "polarssl/base64.h"
43#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,
727 int is_critical,
728 int *ca_istrue,
729 int *max_pathlen )
730{
731 int ret, len;
732
733 /*
734 * BasicConstraints ::= SEQUENCE {
735 * cA BOOLEAN DEFAULT FALSE,
736 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
737 */
738 int is_cacert = 0; /* DEFAULT FALSE */
739 *max_pathlen = 0; /* endless */
740
741 if( ( ret = asn1_get_tag( p, end, &len,
742 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
743 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
744
745 if( *p == end )
746 return 0;
747
748 if( ( ret = asn1_get_bool( p, end, &is_cacert ) ) != 0 )
749 {
750 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
751 ret = asn1_get_int( p, end, &is_cacert );
752
753 if( ret != 0 )
754 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
755
756 if( is_cacert != 0 )
757 is_cacert = 1;
758 }
759
760 if( *p == end )
761 return 0;
762
763 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
764 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
765
766 if( *p != end )
767 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
768 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
769
770 (*max_pathlen)++;
771
772 *ca_istrue = is_critical & is_cacert;
773 return 0;
774}
775
776static int x509_get_ns_cert_type( unsigned char **p,
777 const unsigned char *end,
778 unsigned char *ns_cert_type)
779{
780 int ret;
781 x509_bitstring bs = {0};
782
783 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
784 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
785
786 if( bs.len != 1 )
787 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
788 POLARSSL_ERR_ASN1_INVALID_LENGTH );
789
790 /* Get actual bitstring */
791 *ns_cert_type = *bs.p;
792 return 0;
793}
794
795static int x509_get_key_usage( unsigned char **p,
796 const unsigned char *end,
797 unsigned char *key_usage)
798{
799 int ret;
800 x509_bitstring bs = {0};
801
802 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
803 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
804
805 if( bs.len != 1 )
806 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
807 POLARSSL_ERR_ASN1_INVALID_LENGTH );
808
809 /* Get actual bitstring */
810 *key_usage = *bs.p;
811 return 0;
812}
813
Paul Bakkerd98030e2009-05-02 15:13:40 +0000814/*
Paul Bakker74111d32011-01-15 16:57:55 +0000815 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
816 *
817 * KeyPurposeId ::= OBJECT IDENTIFIER
818 */
819static int x509_get_ext_key_usage( unsigned char **p,
820 const unsigned char *end,
821 x509_sequence *ext_key_usage)
822{
823 int ret;
824
825 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
826 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
827
828 /* Sequence length must be >= 1 */
829 if( ext_key_usage->buf.p == NULL )
830 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
831 POLARSSL_ERR_ASN1_INVALID_LENGTH );
832
833 return 0;
834}
835
836/*
837 * X.509 v3 extensions
838 *
839 * TODO: Perform all of the basic constraints tests required by the RFC
840 * TODO: Set values for undetected extensions to a sane default?
841 *
Paul Bakkerd98030e2009-05-02 15:13:40 +0000842 */
843static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000844 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000845 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000846{
847 int ret, len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000848 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000849
Paul Bakker74111d32011-01-15 16:57:55 +0000850 if( ( ret = x509_get_ext( p, end, &crt->v3_ext ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000851 {
852 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
853 return( 0 );
854
855 return( ret );
856 }
857
Paul Bakker5121ce52009-01-03 21:22:43 +0000858 while( *p < end )
859 {
Paul Bakker74111d32011-01-15 16:57:55 +0000860 /*
861 * Extension ::= SEQUENCE {
862 * extnID OBJECT IDENTIFIER,
863 * critical BOOLEAN DEFAULT FALSE,
864 * extnValue OCTET STRING }
865 */
866 x509_buf extn_oid = {0, 0, NULL};
867 int is_critical = 0; /* DEFAULT FALSE */
868
Paul Bakker5121ce52009-01-03 21:22:43 +0000869 if( ( ret = asn1_get_tag( p, end, &len,
870 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000871 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000872
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000873 end_ext_data = *p + len;
874
Paul Bakker74111d32011-01-15 16:57:55 +0000875 /* Get extension ID */
876 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000877
Paul Bakker74111d32011-01-15 16:57:55 +0000878 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
879 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000880
Paul Bakker74111d32011-01-15 16:57:55 +0000881 extn_oid.p = *p;
882 *p += extn_oid.len;
883
884 if( ( end - *p ) < 1 )
885 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
886 POLARSSL_ERR_ASN1_OUT_OF_DATA );
887
888 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000889 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000890 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
891 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000892
Paul Bakker74111d32011-01-15 16:57:55 +0000893 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000894 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000895 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000896 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000897
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000898 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000899
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000900 if( end_ext_octet != end_ext_data )
901 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
902 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000903
Paul Bakker74111d32011-01-15 16:57:55 +0000904 /*
905 * Detect supported extensions
906 */
907 if( ( OID_SIZE( OID_BASIC_CONSTRAINTS ) == extn_oid.len ) &&
908 memcmp( extn_oid.p, OID_BASIC_CONSTRAINTS, extn_oid.len ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000909 {
Paul Bakker74111d32011-01-15 16:57:55 +0000910 /* Parse basic constraints */
911 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
912 is_critical, &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
913 return ( ret );
914 crt->ext_types |= EXT_BASIC_CONSTRAINTS;
Paul Bakker5121ce52009-01-03 21:22:43 +0000915 }
Paul Bakker74111d32011-01-15 16:57:55 +0000916 else if( ( OID_SIZE( OID_NS_CERT_TYPE ) == extn_oid.len ) &&
917 memcmp( extn_oid.p, OID_NS_CERT_TYPE, extn_oid.len ) == 0 )
918 {
919 /* Parse netscape certificate type */
920 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
921 &crt->ns_cert_type ) ) != 0 )
922 return ( ret );
923 crt->ext_types |= EXT_NS_CERT_TYPE;
924 }
925 else if( ( OID_SIZE( OID_KEY_USAGE ) == extn_oid.len ) &&
926 memcmp( extn_oid.p, OID_KEY_USAGE, extn_oid.len ) == 0 )
927 {
928 /* Parse key usage */
929 if( ( ret = x509_get_key_usage( p, end_ext_octet,
930 &crt->key_usage ) ) != 0 )
931 return ( ret );
932 crt->ext_types |= EXT_KEY_USAGE;
933 }
934 else if( ( OID_SIZE( OID_EXTENDED_KEY_USAGE ) == extn_oid.len ) &&
935 memcmp( extn_oid.p, OID_EXTENDED_KEY_USAGE, extn_oid.len ) == 0 )
936 {
937 /* Parse extended key usage */
938 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
939 &crt->ext_key_usage ) ) != 0 )
940 return ( ret );
941 crt->ext_types |= EXT_EXTENDED_KEY_USAGE;
942 }
943 else
944 {
945 /* No parser found, skip extension */
946 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +0000947
Paul Bakker74111d32011-01-15 16:57:55 +0000948 if( is_critical )
949 {
950 /* Data is marked as critical: fail */
951 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
952 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
953 }
954 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000955 }
956
957 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000958 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
959 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000960
Paul Bakker5121ce52009-01-03 21:22:43 +0000961 return( 0 );
962}
963
964/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000965 * X.509 CRL Entries
966 */
967static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000968 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000969 x509_crl_entry *entry )
970{
Paul Bakker9be19372009-07-27 20:21:53 +0000971 int ret, entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000972 x509_crl_entry *cur_entry = entry;
973
974 if( *p == end )
975 return( 0 );
976
Paul Bakker9be19372009-07-27 20:21:53 +0000977 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000978 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
979 {
980 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
981 return( 0 );
982
983 return( ret );
984 }
985
Paul Bakker9be19372009-07-27 20:21:53 +0000986 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000987
988 while( *p < end )
989 {
990 int len2;
991
992 if( ( ret = asn1_get_tag( p, end, &len2,
993 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
994 {
Paul Bakkerd98030e2009-05-02 15:13:40 +0000995 return( ret );
996 }
997
Paul Bakker9be19372009-07-27 20:21:53 +0000998 cur_entry->raw.tag = **p;
999 cur_entry->raw.p = *p;
1000 cur_entry->raw.len = len2;
1001
Paul Bakkerd98030e2009-05-02 15:13:40 +00001002 if( ( ret = x509_get_serial( p, end, &cur_entry->serial ) ) != 0 )
1003 return( ret );
1004
Paul Bakker91200182010-02-18 21:26:15 +00001005 if( ( ret = x509_get_time( p, end, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001006 return( ret );
1007
1008 if( ( ret = x509_get_crl_ext( p, end, &cur_entry->entry_ext ) ) != 0 )
1009 return( ret );
1010
Paul Bakker74111d32011-01-15 16:57:55 +00001011 if ( *p < end )
1012 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001013 cur_entry->next = malloc( sizeof( x509_crl_entry ) );
1014 cur_entry = cur_entry->next;
1015 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
1016 }
1017 }
1018
1019 return( 0 );
1020}
1021
Paul Bakker27d66162010-03-17 06:56:01 +00001022static int x509_get_sig_alg( const x509_buf *sig_oid, int *sig_alg )
1023{
1024 if( sig_oid->len == 9 &&
1025 memcmp( sig_oid->p, OID_PKCS1, 8 ) == 0 )
1026 {
1027 if( sig_oid->p[8] >= 2 && sig_oid->p[8] <= 5 )
1028 {
1029 *sig_alg = sig_oid->p[8];
1030 return( 0 );
1031 }
1032
1033 if ( sig_oid->p[8] >= 11 && sig_oid->p[8] <= 14 )
1034 {
1035 *sig_alg = sig_oid->p[8];
1036 return( 0 );
1037 }
1038
1039 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1040 }
1041
1042 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1043}
1044
Paul Bakkerd98030e2009-05-02 15:13:40 +00001045/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001046 * Parse one or more certificates and add them to the chained list
1047 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001048int x509parse_crt( x509_cert *chain, const unsigned char *buf, int buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001049{
1050 int ret, len;
Paul Bakkerff60ee62010-03-16 21:09:09 +00001051 const unsigned char *s1, *s2;
Paul Bakker5121ce52009-01-03 21:22:43 +00001052 unsigned char *p, *end;
1053 x509_cert *crt;
1054
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
1083 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001084 * check if the certificate is encoded in base64
1085 */
1086 s1 = (unsigned char *) strstr( (char *) buf,
1087 "-----BEGIN CERTIFICATE-----" );
1088
1089 if( s1 != NULL )
1090 {
1091 s2 = (unsigned char *) strstr( (char *) buf,
1092 "-----END CERTIFICATE-----" );
1093
1094 if( s2 == NULL || s2 <= s1 )
Paul Bakker40e46942009-01-03 21:51:57 +00001095 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001096
1097 s1 += 27;
1098 if( *s1 == '\r' ) s1++;
1099 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001100 else return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001101
1102 /*
1103 * get the DER data length and decode the buffer
1104 */
1105 len = 0;
1106 ret = base64_decode( NULL, &len, s1, s2 - s1 );
1107
Paul Bakker40e46942009-01-03 21:51:57 +00001108 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
1109 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001110
1111 if( ( p = (unsigned char *) malloc( len ) ) == NULL )
1112 return( 1 );
1113
1114 if( ( ret = base64_decode( p, &len, s1, s2 - s1 ) ) != 0 )
1115 {
1116 free( p );
Paul Bakker40e46942009-01-03 21:51:57 +00001117 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001118 }
1119
1120 /*
1121 * update the buffer size and offset
1122 */
1123 s2 += 25;
1124 if( *s2 == '\r' ) s2++;
1125 if( *s2 == '\n' ) s2++;
1126 else
1127 {
1128 free( p );
Paul Bakker40e46942009-01-03 21:51:57 +00001129 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001130 }
1131
1132 buflen -= s2 - buf;
1133 buf = s2;
1134 }
1135 else
1136 {
1137 /*
1138 * nope, copy the raw DER data
1139 */
1140 p = (unsigned char *) malloc( len = buflen );
1141
1142 if( p == NULL )
1143 return( 1 );
1144
1145 memcpy( p, buf, buflen );
1146
1147 buflen = 0;
1148 }
1149
1150 crt->raw.p = p;
1151 crt->raw.len = len;
1152 end = p + len;
1153
1154 /*
1155 * Certificate ::= SEQUENCE {
1156 * tbsCertificate TBSCertificate,
1157 * signatureAlgorithm AlgorithmIdentifier,
1158 * signatureValue BIT STRING }
1159 */
1160 if( ( ret = asn1_get_tag( &p, end, &len,
1161 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1162 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001163 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001164 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001165 }
1166
1167 if( len != (int) ( end - p ) )
1168 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001169 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001170 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1171 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001172 }
1173
1174 /*
1175 * TBSCertificate ::= SEQUENCE {
1176 */
1177 crt->tbs.p = p;
1178
1179 if( ( ret = asn1_get_tag( &p, end, &len,
1180 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1181 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001182 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001183 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001184 }
1185
1186 end = p + len;
1187 crt->tbs.len = end - crt->tbs.p;
1188
1189 /*
1190 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1191 *
1192 * CertificateSerialNumber ::= INTEGER
1193 *
1194 * signature AlgorithmIdentifier
1195 */
1196 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1197 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1198 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
1199 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001200 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001201 return( ret );
1202 }
1203
1204 crt->version++;
1205
1206 if( crt->version > 3 )
1207 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001208 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001209 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001210 }
1211
Paul Bakker27d66162010-03-17 06:56:01 +00001212 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_alg ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001213 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001214 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001215 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001216 }
1217
1218 /*
1219 * issuer Name
1220 */
1221 crt->issuer_raw.p = p;
1222
1223 if( ( ret = asn1_get_tag( &p, end, &len,
1224 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1225 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001226 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001227 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001228 }
1229
1230 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1231 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001232 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001233 return( ret );
1234 }
1235
1236 crt->issuer_raw.len = p - crt->issuer_raw.p;
1237
1238 /*
1239 * Validity ::= SEQUENCE {
1240 * notBefore Time,
1241 * notAfter Time }
1242 *
1243 */
1244 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1245 &crt->valid_to ) ) != 0 )
1246 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001247 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001248 return( ret );
1249 }
1250
1251 /*
1252 * subject Name
1253 */
1254 crt->subject_raw.p = p;
1255
1256 if( ( ret = asn1_get_tag( &p, end, &len,
1257 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1258 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001259 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001260 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001261 }
1262
1263 if( ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
1264 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001265 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001266 return( ret );
1267 }
1268
1269 crt->subject_raw.len = p - crt->subject_raw.p;
1270
1271 /*
1272 * SubjectPublicKeyInfo ::= SEQUENCE
1273 * algorithm AlgorithmIdentifier,
1274 * subjectPublicKey BIT STRING }
1275 */
1276 if( ( ret = asn1_get_tag( &p, end, &len,
1277 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1278 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001279 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001280 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001281 }
1282
1283 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1284 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1285 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001286 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001287 return( ret );
1288 }
1289
1290 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1291 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001292 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001293 return( ret );
1294 }
1295
1296 crt->rsa.len = mpi_size( &crt->rsa.N );
1297
1298 /*
1299 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1300 * -- If present, version shall be v2 or v3
1301 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1302 * -- If present, version shall be v2 or v3
1303 * extensions [3] EXPLICIT Extensions OPTIONAL
1304 * -- If present, version shall be v3
1305 */
1306 if( crt->version == 2 || crt->version == 3 )
1307 {
1308 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1309 if( ret != 0 )
1310 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001311 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001312 return( ret );
1313 }
1314 }
1315
1316 if( crt->version == 2 || crt->version == 3 )
1317 {
1318 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1319 if( ret != 0 )
1320 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001321 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001322 return( ret );
1323 }
1324 }
1325
1326 if( crt->version == 3 )
1327 {
Paul Bakker74111d32011-01-15 16:57:55 +00001328 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001329 if( ret != 0 )
1330 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001331 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001332 return( ret );
1333 }
1334 }
1335
1336 if( p != end )
1337 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001338 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001339 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1340 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001341 }
1342
1343 end = crt->raw.p + crt->raw.len;
1344
1345 /*
1346 * signatureAlgorithm AlgorithmIdentifier,
1347 * signatureValue BIT STRING
1348 */
1349 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1350 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001351 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001352 return( ret );
1353 }
1354
Paul Bakker320a4b52009-03-28 18:52:39 +00001355 if( memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001356 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001357 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001358 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001359 }
1360
1361 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1362 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001363 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001364 return( ret );
1365 }
1366
1367 if( p != end )
1368 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001369 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001370 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1371 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001372 }
1373
Paul Bakker5121ce52009-01-03 21:22:43 +00001374 if( buflen > 0 )
Paul Bakker320a4b52009-03-28 18:52:39 +00001375 {
1376 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1377
Paul Bakker7d06ad22009-05-02 15:53:56 +00001378 if( crt->next == NULL )
1379 {
Paul Bakker320a4b52009-03-28 18:52:39 +00001380 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001381 return( 1 );
1382 }
Paul Bakker320a4b52009-03-28 18:52:39 +00001383
Paul Bakker7d06ad22009-05-02 15:53:56 +00001384 crt = crt->next;
1385 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001386
Paul Bakker5121ce52009-01-03 21:22:43 +00001387 return( x509parse_crt( crt, buf, buflen ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001388 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001389
1390 return( 0 );
1391}
1392
1393/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001394 * Parse one or more CRLs and add them to the chained list
1395 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001396int x509parse_crl( x509_crl *chain, const unsigned char *buf, int buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001397{
1398 int ret, len;
1399 unsigned char *s1, *s2;
1400 unsigned char *p, *end;
1401 x509_crl *crl;
1402
1403 crl = chain;
1404
1405 /*
1406 * Check for valid input
1407 */
1408 if( crl == NULL || buf == NULL )
1409 return( 1 );
1410
1411 while( crl->version != 0 && crl->next != NULL )
1412 crl = crl->next;
1413
1414 /*
1415 * Add new CRL on the end of the chain if needed.
1416 */
1417 if ( crl->version != 0 && crl->next == NULL)
1418 {
1419 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1420
Paul Bakker7d06ad22009-05-02 15:53:56 +00001421 if( crl->next == NULL )
1422 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001423 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001424 return( 1 );
1425 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001426
Paul Bakker7d06ad22009-05-02 15:53:56 +00001427 crl = crl->next;
1428 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001429 }
1430
1431 /*
1432 * check if the CRL is encoded in base64
1433 */
1434 s1 = (unsigned char *) strstr( (char *) buf,
1435 "-----BEGIN X509 CRL-----" );
1436
1437 if( s1 != NULL )
1438 {
1439 s2 = (unsigned char *) strstr( (char *) buf,
1440 "-----END X509 CRL-----" );
1441
1442 if( s2 == NULL || s2 <= s1 )
1443 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1444
1445 s1 += 24;
1446 if( *s1 == '\r' ) s1++;
1447 if( *s1 == '\n' ) s1++;
1448 else return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1449
1450 /*
1451 * get the DER data length and decode the buffer
1452 */
1453 len = 0;
1454 ret = base64_decode( NULL, &len, s1, s2 - s1 );
1455
1456 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
1457 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
1458
1459 if( ( p = (unsigned char *) malloc( len ) ) == NULL )
1460 return( 1 );
1461
1462 if( ( ret = base64_decode( p, &len, s1, s2 - s1 ) ) != 0 )
1463 {
1464 free( p );
1465 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
1466 }
1467
1468 /*
1469 * update the buffer size and offset
1470 */
1471 s2 += 22;
1472 if( *s2 == '\r' ) s2++;
1473 if( *s2 == '\n' ) s2++;
1474 else
1475 {
1476 free( p );
1477 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1478 }
1479
1480 buflen -= s2 - buf;
1481 buf = s2;
1482 }
1483 else
1484 {
1485 /*
1486 * nope, copy the raw DER data
1487 */
1488 p = (unsigned char *) malloc( len = buflen );
1489
1490 if( p == NULL )
1491 return( 1 );
1492
1493 memcpy( p, buf, buflen );
1494
1495 buflen = 0;
1496 }
1497
1498 crl->raw.p = p;
1499 crl->raw.len = len;
1500 end = p + len;
1501
1502 /*
1503 * CertificateList ::= SEQUENCE {
1504 * tbsCertList TBSCertList,
1505 * signatureAlgorithm AlgorithmIdentifier,
1506 * signatureValue BIT STRING }
1507 */
1508 if( ( ret = asn1_get_tag( &p, end, &len,
1509 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1510 {
1511 x509_crl_free( crl );
1512 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1513 }
1514
1515 if( len != (int) ( end - p ) )
1516 {
1517 x509_crl_free( crl );
1518 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1519 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1520 }
1521
1522 /*
1523 * TBSCertList ::= SEQUENCE {
1524 */
1525 crl->tbs.p = p;
1526
1527 if( ( ret = asn1_get_tag( &p, end, &len,
1528 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1529 {
1530 x509_crl_free( crl );
1531 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
1532 }
1533
1534 end = p + len;
1535 crl->tbs.len = end - crl->tbs.p;
1536
1537 /*
1538 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1539 * -- if present, MUST be v2
1540 *
1541 * signature AlgorithmIdentifier
1542 */
1543 if( ( ret = x509_get_version( &p, end, &crl->version ) ) != 0 ||
1544 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1545 {
1546 x509_crl_free( crl );
1547 return( ret );
1548 }
1549
1550 crl->version++;
1551
1552 if( crl->version > 2 )
1553 {
1554 x509_crl_free( crl );
1555 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1556 }
1557
Paul Bakker27d66162010-03-17 06:56:01 +00001558 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_alg ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001559 {
1560 x509_crl_free( crl );
1561 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1562 }
1563
1564 /*
1565 * issuer Name
1566 */
1567 crl->issuer_raw.p = p;
1568
1569 if( ( ret = asn1_get_tag( &p, end, &len,
1570 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1571 {
1572 x509_crl_free( crl );
1573 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
1574 }
1575
1576 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1577 {
1578 x509_crl_free( crl );
1579 return( ret );
1580 }
1581
1582 crl->issuer_raw.len = p - crl->issuer_raw.p;
1583
1584 /*
1585 * thisUpdate Time
1586 * nextUpdate Time OPTIONAL
1587 */
Paul Bakker91200182010-02-18 21:26:15 +00001588 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001589 {
1590 x509_crl_free( crl );
1591 return( ret );
1592 }
1593
Paul Bakker91200182010-02-18 21:26:15 +00001594 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001595 {
Paul Bakker635f4b42009-07-20 20:34:41 +00001596 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE |
Paul Bakker9be19372009-07-27 20:21:53 +00001597 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
1598 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE |
1599 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001600 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001601 x509_crl_free( crl );
1602 return( ret );
1603 }
1604 }
1605
1606 /*
1607 * revokedCertificates SEQUENCE OF SEQUENCE {
1608 * userCertificate CertificateSerialNumber,
1609 * revocationDate Time,
1610 * crlEntryExtensions Extensions OPTIONAL
1611 * -- if present, MUST be v2
1612 * } OPTIONAL
1613 */
1614 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1615 {
1616 x509_crl_free( crl );
1617 return( ret );
1618 }
1619
1620 /*
1621 * crlExtensions EXPLICIT Extensions OPTIONAL
1622 * -- if present, MUST be v2
1623 */
1624 if( crl->version == 2 )
1625 {
1626 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1627
1628 if( ret != 0 )
1629 {
1630 x509_crl_free( crl );
1631 return( ret );
1632 }
1633 }
1634
1635 if( p != end )
1636 {
1637 x509_crl_free( crl );
1638 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1639 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1640 }
1641
1642 end = crl->raw.p + crl->raw.len;
1643
1644 /*
1645 * signatureAlgorithm AlgorithmIdentifier,
1646 * signatureValue BIT STRING
1647 */
1648 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1649 {
1650 x509_crl_free( crl );
1651 return( ret );
1652 }
1653
1654 if( memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
1655 {
1656 x509_crl_free( crl );
1657 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1658 }
1659
1660 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1661 {
1662 x509_crl_free( crl );
1663 return( ret );
1664 }
1665
1666 if( p != end )
1667 {
1668 x509_crl_free( crl );
1669 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1670 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1671 }
1672
1673 if( buflen > 0 )
1674 {
1675 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1676
Paul Bakker7d06ad22009-05-02 15:53:56 +00001677 if( crl->next == NULL )
1678 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001679 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001680 return( 1 );
1681 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001682
Paul Bakker7d06ad22009-05-02 15:53:56 +00001683 crl = crl->next;
1684 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001685
1686 return( x509parse_crl( crl, buf, buflen ) );
1687 }
1688
1689 return( 0 );
1690}
1691
1692/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001693 * Load all data from a file into a given buffer.
1694 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001695int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001696{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001697 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001698
Paul Bakkerd98030e2009-05-02 15:13:40 +00001699 if( ( f = fopen( path, "rb" ) ) == NULL )
1700 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001701
Paul Bakkerd98030e2009-05-02 15:13:40 +00001702 fseek( f, 0, SEEK_END );
1703 *n = (size_t) ftell( f );
1704 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001705
Paul Bakkerd98030e2009-05-02 15:13:40 +00001706 if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
1707 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001708
Paul Bakkerd98030e2009-05-02 15:13:40 +00001709 if( fread( *buf, 1, *n, f ) != *n )
1710 {
1711 fclose( f );
1712 free( *buf );
1713 return( 1 );
1714 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001715
Paul Bakkerd98030e2009-05-02 15:13:40 +00001716 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001717
Paul Bakkerd98030e2009-05-02 15:13:40 +00001718 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001719
Paul Bakkerd98030e2009-05-02 15:13:40 +00001720 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001721}
1722
1723/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001724 * Load one or more certificates and add them to the chained list
1725 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001726int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001727{
1728 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001729 size_t n;
1730 unsigned char *buf;
1731
Paul Bakker2b245eb2009-04-19 18:44:26 +00001732 if ( load_file( path, &buf, &n ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001733 return( 1 );
1734
Paul Bakker5121ce52009-01-03 21:22:43 +00001735 ret = x509parse_crt( chain, buf, (int) n );
1736
1737 memset( buf, 0, n + 1 );
1738 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001739
1740 return( ret );
1741}
1742
Paul Bakkerd98030e2009-05-02 15:13:40 +00001743/*
1744 * Load one or more CRLs and add them to the chained list
1745 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001746int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001747{
1748 int ret;
1749 size_t n;
1750 unsigned char *buf;
1751
1752 if ( load_file( path, &buf, &n ) )
1753 return( 1 );
1754
1755 ret = x509parse_crl( chain, buf, (int) n );
1756
1757 memset( buf, 0, n + 1 );
1758 free( buf );
1759
1760 return( ret );
1761}
1762
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001763#if defined(POLARSSL_DES_C) && defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001764/*
1765 * Read a 16-byte hex string and convert it to binary
1766 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001767static int x509_get_iv( const unsigned char *s, unsigned char iv[8] )
Paul Bakker5121ce52009-01-03 21:22:43 +00001768{
1769 int i, j, k;
1770
1771 memset( iv, 0, 8 );
1772
1773 for( i = 0; i < 16; i++, s++ )
1774 {
1775 if( *s >= '0' && *s <= '9' ) j = *s - '0'; else
1776 if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else
1777 if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else
Paul Bakker40e46942009-01-03 21:51:57 +00001778 return( POLARSSL_ERR_X509_KEY_INVALID_ENC_IV );
Paul Bakker5121ce52009-01-03 21:22:43 +00001779
1780 k = ( ( i & 1 ) != 0 ) ? j : j << 4;
1781
1782 iv[i >> 1] = (unsigned char)( iv[i >> 1] | k );
1783 }
1784
1785 return( 0 );
1786}
1787
1788/*
1789 * Decrypt with 3DES-CBC, using PBKDF1 for key derivation
1790 */
1791static void x509_des3_decrypt( unsigned char des3_iv[8],
1792 unsigned char *buf, int buflen,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001793 const unsigned char *pwd, int pwdlen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001794{
1795 md5_context md5_ctx;
1796 des3_context des3_ctx;
1797 unsigned char md5sum[16];
1798 unsigned char des3_key[24];
1799
1800 /*
1801 * 3DES key[ 0..15] = MD5(pwd || IV)
1802 * key[16..23] = MD5(pwd || IV || 3DES key[ 0..15])
1803 */
1804 md5_starts( &md5_ctx );
1805 md5_update( &md5_ctx, pwd, pwdlen );
1806 md5_update( &md5_ctx, des3_iv, 8 );
1807 md5_finish( &md5_ctx, md5sum );
1808 memcpy( des3_key, md5sum, 16 );
1809
1810 md5_starts( &md5_ctx );
1811 md5_update( &md5_ctx, md5sum, 16 );
1812 md5_update( &md5_ctx, pwd, pwdlen );
1813 md5_update( &md5_ctx, des3_iv, 8 );
1814 md5_finish( &md5_ctx, md5sum );
1815 memcpy( des3_key + 16, md5sum, 8 );
1816
1817 des3_set3key_dec( &des3_ctx, des3_key );
1818 des3_crypt_cbc( &des3_ctx, DES_DECRYPT, buflen,
1819 des3_iv, buf, buf );
1820
1821 memset( &md5_ctx, 0, sizeof( md5_ctx ) );
1822 memset( &des3_ctx, 0, sizeof( des3_ctx ) );
1823 memset( md5sum, 0, 16 );
1824 memset( des3_key, 0, 24 );
1825}
1826#endif
1827
1828/*
1829 * Parse a private RSA key
1830 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001831int x509parse_key( rsa_context *rsa, const unsigned char *key, int keylen,
1832 const unsigned char *pwd, int pwdlen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001833{
1834 int ret, len, enc;
Paul Bakkerff60ee62010-03-16 21:09:09 +00001835 unsigned char *buf, *s1, *s2;
Paul Bakker5121ce52009-01-03 21:22:43 +00001836 unsigned char *p, *end;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001837#if defined(POLARSSL_DES_C) && defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001838 unsigned char des3_iv[8];
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001839#else
1840 ((void) pwd);
1841 ((void) pwdlen);
1842#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001843
Paul Bakkerff60ee62010-03-16 21:09:09 +00001844 s1 = (unsigned char *) strstr( (char *) key,
Paul Bakker5121ce52009-01-03 21:22:43 +00001845 "-----BEGIN RSA PRIVATE KEY-----" );
1846
1847 if( s1 != NULL )
1848 {
Paul Bakkerff60ee62010-03-16 21:09:09 +00001849 s2 = (unsigned char *) strstr( (char *) key,
Paul Bakker5121ce52009-01-03 21:22:43 +00001850 "-----END RSA PRIVATE KEY-----" );
1851
1852 if( s2 == NULL || s2 <= s1 )
Paul Bakker40e46942009-01-03 21:51:57 +00001853 return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001854
1855 s1 += 31;
1856 if( *s1 == '\r' ) s1++;
1857 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001858 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001859
1860 enc = 0;
1861
1862 if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
1863 {
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001864#if defined(POLARSSL_DES_C) && defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001865 enc++;
1866
1867 s1 += 22;
1868 if( *s1 == '\r' ) s1++;
1869 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001870 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001871
1872 if( memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001873 return( POLARSSL_ERR_X509_KEY_UNKNOWN_ENC_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +00001874
1875 s1 += 23;
1876 if( x509_get_iv( s1, des3_iv ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001877 return( POLARSSL_ERR_X509_KEY_INVALID_ENC_IV );
Paul Bakker5121ce52009-01-03 21:22:43 +00001878
1879 s1 += 16;
1880 if( *s1 == '\r' ) s1++;
1881 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001882 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001883#else
Paul Bakker40e46942009-01-03 21:51:57 +00001884 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001885#endif
1886 }
1887
1888 len = 0;
1889 ret = base64_decode( NULL, &len, s1, s2 - s1 );
1890
Paul Bakker40e46942009-01-03 21:51:57 +00001891 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
1892 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001893
1894 if( ( buf = (unsigned char *) malloc( len ) ) == NULL )
1895 return( 1 );
1896
1897 if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
1898 {
1899 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001900 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001901 }
1902
Paul Bakkerff60ee62010-03-16 21:09:09 +00001903 keylen = len;
Paul Bakker5121ce52009-01-03 21:22:43 +00001904
1905 if( enc != 0 )
1906 {
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001907#if defined(POLARSSL_DES_C) && defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001908 if( pwd == NULL )
1909 {
1910 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001911 return( POLARSSL_ERR_X509_KEY_PASSWORD_REQUIRED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001912 }
1913
Paul Bakkerff60ee62010-03-16 21:09:09 +00001914 x509_des3_decrypt( des3_iv, buf, keylen, pwd, pwdlen );
Paul Bakker5121ce52009-01-03 21:22:43 +00001915
1916 if( buf[0] != 0x30 || buf[1] != 0x82 ||
1917 buf[4] != 0x02 || buf[5] != 0x01 )
1918 {
1919 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001920 return( POLARSSL_ERR_X509_KEY_PASSWORD_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001921 }
1922#else
Paul Bakker40e46942009-01-03 21:51:57 +00001923 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001924#endif
1925 }
1926 }
Paul Bakkerff60ee62010-03-16 21:09:09 +00001927 else
1928 {
1929 buf = NULL;
1930 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001931
1932 memset( rsa, 0, sizeof( rsa_context ) );
1933
Paul Bakkerff60ee62010-03-16 21:09:09 +00001934 p = ( s1 != NULL ) ? buf : (unsigned char *) key;
1935 end = p + keylen;
Paul Bakker5121ce52009-01-03 21:22:43 +00001936
1937 /*
1938 * RSAPrivateKey ::= SEQUENCE {
1939 * version Version,
1940 * modulus INTEGER, -- n
1941 * publicExponent INTEGER, -- e
1942 * privateExponent INTEGER, -- d
1943 * prime1 INTEGER, -- p
1944 * prime2 INTEGER, -- q
1945 * exponent1 INTEGER, -- d mod (p-1)
1946 * exponent2 INTEGER, -- d mod (q-1)
1947 * coefficient INTEGER, -- (inverse of q) mod p
1948 * otherPrimeInfos OtherPrimeInfos OPTIONAL
1949 * }
1950 */
1951 if( ( ret = asn1_get_tag( &p, end, &len,
1952 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1953 {
1954 if( s1 != NULL )
1955 free( buf );
1956
1957 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001958 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001959 }
1960
1961 end = p + len;
1962
1963 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
1964 {
1965 if( s1 != NULL )
1966 free( buf );
1967
1968 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001969 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001970 }
1971
1972 if( rsa->ver != 0 )
1973 {
1974 if( s1 != NULL )
1975 free( buf );
1976
1977 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001978 return( ret | POLARSSL_ERR_X509_KEY_INVALID_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001979 }
1980
1981 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
1982 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
1983 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
1984 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
1985 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
1986 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
1987 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
1988 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
1989 {
1990 if( s1 != NULL )
1991 free( buf );
1992
1993 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001994 return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001995 }
1996
1997 rsa->len = mpi_size( &rsa->N );
1998
1999 if( p != end )
2000 {
2001 if( s1 != NULL )
2002 free( buf );
2003
2004 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00002005 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT |
2006 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002007 }
2008
2009 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2010 {
2011 if( s1 != NULL )
2012 free( buf );
2013
2014 rsa_free( rsa );
2015 return( ret );
2016 }
2017
2018 if( s1 != NULL )
2019 free( buf );
2020
2021 return( 0 );
2022}
2023
2024/*
2025 * Load and parse a private RSA key
2026 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002027int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
Paul Bakker5121ce52009-01-03 21:22:43 +00002028{
2029 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002030 size_t n;
2031 unsigned char *buf;
2032
Paul Bakker2b245eb2009-04-19 18:44:26 +00002033 if ( load_file( path, &buf, &n ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00002034 return( 1 );
2035
Paul Bakker5121ce52009-01-03 21:22:43 +00002036 if( pwd == NULL )
2037 ret = x509parse_key( rsa, buf, (int) n, NULL, 0 );
2038 else
2039 ret = x509parse_key( rsa, buf, (int) n,
2040 (unsigned char *) pwd, strlen( pwd ) );
2041
2042 memset( buf, 0, n + 1 );
2043 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00002044
2045 return( ret );
2046}
2047
Paul Bakker1b57b062011-01-06 15:48:19 +00002048/*
2049 * Parse DHM parameters
2050 */
2051int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, int dhminlen )
2052{
2053 int ret, len;
2054 unsigned char *buf, *s1, *s2;
2055 unsigned char *p, *end;
2056
2057 s1 = (unsigned char *) strstr( (char *) dhmin,
2058 "-----BEGIN DH PARAMETERS-----" );
2059
2060 if( s1 != NULL )
2061 {
2062 s2 = (unsigned char *) strstr( (char *) dhmin,
2063 "-----END DH PARAMETERS-----" );
2064
2065 if( s2 == NULL || s2 <= s1 )
2066 return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
2067
2068 s1 += 29;
2069 if( *s1 == '\r' ) s1++;
2070 if( *s1 == '\n' ) s1++;
2071 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
2072
2073 len = 0;
2074 ret = base64_decode( NULL, &len, s1, s2 - s1 );
2075
2076 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
2077 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
2078
2079 if( ( buf = (unsigned char *) malloc( len ) ) == NULL )
2080 return( 1 );
2081
2082 if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
2083 {
2084 free( buf );
2085 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
2086 }
2087
2088 dhminlen = len;
2089 }
2090 else
2091 {
2092 buf = NULL;
2093 }
2094
2095 memset( dhm, 0, sizeof( dhm_context ) );
2096
2097 p = ( s1 != NULL ) ? buf : (unsigned char *) dhmin;
2098 end = p + dhminlen;
2099
2100 /*
2101 * DHParams ::= SEQUENCE {
2102 * prime INTEGER, -- P
2103 * generator INTEGER, -- g
2104 * }
2105 */
2106 if( ( ret = asn1_get_tag( &p, end, &len,
2107 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2108 {
2109 if( s1 != NULL )
2110 free( buf );
2111
2112 dhm_free( dhm );
2113 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
2114 }
2115
2116 end = p + len;
2117
2118 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
2119 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
2120 {
2121 if( s1 != NULL )
2122 free( buf );
2123
2124 dhm_free( dhm );
2125 return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
2126 }
2127
2128 if( p != end )
2129 {
2130 if( s1 != NULL )
2131 free( buf );
2132
2133 dhm_free( dhm );
2134 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT |
2135 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
2136 }
2137
2138 if( s1 != NULL )
2139 free( buf );
2140
2141 return( 0 );
2142}
2143
2144/*
2145 * Load and parse a private RSA key
2146 */
2147int x509parse_dhmfile( dhm_context *dhm, const char *path )
2148{
2149 int ret;
2150 size_t n;
2151 unsigned char *buf;
2152
2153 if ( load_file( path, &buf, &n ) )
2154 return( 1 );
2155
2156 ret = x509parse_dhm( dhm, buf, (int) n);
2157
2158 memset( buf, 0, n + 1 );
2159 free( buf );
2160
2161 return( ret );
2162}
2163
Paul Bakker5121ce52009-01-03 21:22:43 +00002164#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002165#include <stdarg.h>
2166
2167#if !defined vsnprintf
2168#define vsnprintf _vsnprintf
2169#endif // vsnprintf
2170
2171/*
2172 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2173 * Result value is not size of buffer needed, but -1 if no fit is possible.
2174 *
2175 * This fuction tries to 'fix' this by at least suggesting enlarging the
2176 * size by 20.
2177 */
2178int compat_snprintf(char *str, size_t size, const char *format, ...)
2179{
2180 va_list ap;
2181 int res = -1;
2182
2183 va_start( ap, format );
2184
2185 res = vsnprintf( str, size, format, ap );
2186
2187 va_end( ap );
2188
2189 // No quick fix possible
2190 if ( res < 0 )
2191 return( size + 20 );
2192
2193 return res;
2194}
2195
2196#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002197#endif
2198
Paul Bakkerd98030e2009-05-02 15:13:40 +00002199#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2200
2201#define SAFE_SNPRINTF() \
2202{ \
2203 if( ret == -1 ) \
2204 return( -1 ); \
2205 \
2206 if ( ret > n ) { \
2207 p[n - 1] = '\0'; \
2208 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2209 } \
2210 \
2211 n -= ret; \
2212 p += ret; \
2213}
2214
Paul Bakker5121ce52009-01-03 21:22:43 +00002215/*
2216 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002217 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002218 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002219int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002220{
Paul Bakkerd98030e2009-05-02 15:13:40 +00002221 int i, ret, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002222 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002223 const x509_name *name;
Paul Bakker5121ce52009-01-03 21:22:43 +00002224 char s[128], *p;
2225
2226 memset( s, 0, sizeof( s ) );
2227
2228 name = dn;
2229 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002230 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002231
2232 while( name != NULL )
2233 {
Paul Bakker74111d32011-01-15 16:57:55 +00002234 if( name != dn )
2235 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002236 ret = snprintf( p, n, ", " );
2237 SAFE_SNPRINTF();
2238 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002239
2240 if( memcmp( name->oid.p, OID_X520, 2 ) == 0 )
2241 {
2242 switch( name->oid.p[2] )
2243 {
2244 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002245 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002246
2247 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002248 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002249
2250 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002251 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002252
2253 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002254 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002255
2256 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002257 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002258
2259 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002260 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002261
2262 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002263 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002264 name->oid.p[2] );
2265 break;
2266 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002267 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002268 }
2269 else if( memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
2270 {
2271 switch( name->oid.p[8] )
2272 {
2273 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002274 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002275
2276 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002277 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002278 name->oid.p[8] );
2279 break;
2280 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002281 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002282 }
2283 else
Paul Bakker74111d32011-01-15 16:57:55 +00002284 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002285 ret = snprintf( p, n, "\?\?=" );
Paul Bakker74111d32011-01-15 16:57:55 +00002286 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002287 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002288
2289 for( i = 0; i < name->val.len; i++ )
2290 {
2291 if( i >= (int) sizeof( s ) - 1 )
2292 break;
2293
2294 c = name->val.p[i];
2295 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2296 s[i] = '?';
2297 else s[i] = c;
2298 }
2299 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002300 ret = snprintf( p, n, "%s", s );
2301 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002302 name = name->next;
2303 }
2304
Paul Bakkerd98030e2009-05-02 15:13:40 +00002305 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002306}
2307
2308/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002309 * Store the serial in printable form into buf; no more
2310 * than size characters will be written
2311 */
2312int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2313{
2314 int i, ret, nr, n;
2315 char *p;
2316
2317 p = buf;
2318 n = size;
2319
2320 nr = ( serial->len <= 32 )
2321 ? serial->len : 32;
2322
2323 for( i = 0; i < nr; i++ )
2324 {
2325 ret = snprintf( p, n, "%02X%s",
2326 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2327 SAFE_SNPRINTF();
2328 }
2329
2330 return( size - n );
2331}
2332
2333/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002334 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002335 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002336int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2337 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002338{
Paul Bakkerdd476992011-01-16 21:34:59 +00002339 int n, ret;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002340 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00002341
2342 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002343 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002344
Paul Bakkerd98030e2009-05-02 15:13:40 +00002345 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002346 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002347 SAFE_SNPRINTF();
2348 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002349 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002350 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002351
Paul Bakkerdd476992011-01-16 21:34:59 +00002352 ret = x509parse_serial_gets( p, n, &crt->serial);
2353 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002354
Paul Bakkerd98030e2009-05-02 15:13:40 +00002355 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2356 SAFE_SNPRINTF();
2357 ret = x509parse_dn_gets( p, n, &crt->issuer );
2358 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002359
Paul Bakkerd98030e2009-05-02 15:13:40 +00002360 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2361 SAFE_SNPRINTF();
2362 ret = x509parse_dn_gets( p, n, &crt->subject );
2363 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002364
Paul Bakkerd98030e2009-05-02 15:13:40 +00002365 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002366 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2367 crt->valid_from.year, crt->valid_from.mon,
2368 crt->valid_from.day, crt->valid_from.hour,
2369 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002370 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002371
Paul Bakkerd98030e2009-05-02 15:13:40 +00002372 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002373 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2374 crt->valid_to.year, crt->valid_to.mon,
2375 crt->valid_to.day, crt->valid_to.hour,
2376 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002377 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002378
Paul Bakkerd98030e2009-05-02 15:13:40 +00002379 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2380 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002381
Paul Bakker27d66162010-03-17 06:56:01 +00002382 switch( crt->sig_alg )
Paul Bakker5121ce52009-01-03 21:22:43 +00002383 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002384 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2385 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2386 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2387 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2388 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2389 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2390 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2391 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2392 default: ret = snprintf( p, n, "???" ); break;
2393 }
2394 SAFE_SNPRINTF();
2395
2396 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
2397 crt->rsa.N.n * (int) sizeof( unsigned long ) * 8 );
2398 SAFE_SNPRINTF();
2399
2400 return( size - n );
2401}
2402
Paul Bakker74111d32011-01-15 16:57:55 +00002403/* Compare a given OID string with an OID x509_buf * */
2404#define OID_CMP(oid_str, oid_buf) \
2405 ( ( OID_SIZE(oid_str) == (oid_buf)->len ) && \
2406 memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0)
2407
2408/*
2409 * Return an informational string describing the given OID
2410 */
2411const char *x509_oid_get_description( x509_buf *oid )
2412{
2413 if ( oid == NULL )
2414 return ( NULL );
2415
2416 else if( OID_CMP( OID_SERVER_AUTH, oid ) )
2417 return( STRING_SERVER_AUTH );
2418
2419 else if( OID_CMP( OID_CLIENT_AUTH, oid ) )
2420 return( STRING_CLIENT_AUTH );
2421
2422 else if( OID_CMP( OID_CODE_SIGNING, oid ) )
2423 return( STRING_CODE_SIGNING );
2424
2425 else if( OID_CMP( OID_EMAIL_PROTECTION, oid ) )
2426 return( STRING_EMAIL_PROTECTION );
2427
2428 else if( OID_CMP( OID_TIME_STAMPING, oid ) )
2429 return( STRING_TIME_STAMPING );
2430
2431 else if( OID_CMP( OID_OCSP_SIGNING, oid ) )
2432 return( STRING_OCSP_SIGNING );
2433
2434 return( NULL );
2435}
2436
2437/* Return the x.y.z.... style numeric string for the given OID */
2438int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2439{
2440 int ret, n, i;
2441 unsigned int value;
2442 char *p;
2443
2444 p = buf;
2445 n = size;
2446
2447 /* First byte contains first two dots */
2448 if( oid->len > 0 )
2449 {
2450 ret = snprintf( p, n, "%d.%d", oid->p[0]/40, oid->p[0]%40 );
2451 SAFE_SNPRINTF();
2452 }
2453
2454 /* TODO: value can overflow in value. */
2455 value = 0;
2456 for( i=1; i < oid->len; i++ )
2457 {
2458 value <<= 7;
2459 value += oid->p[i] & 0x7F;
2460
2461 if( !( oid->p[i] & 0x80 ) )
2462 {
2463 /* Last byte */
2464 ret = snprintf( p, n, ".%d", value );
2465 SAFE_SNPRINTF();
2466 value = 0;
2467 }
2468 }
2469
2470 return( size - n );
2471}
2472
Paul Bakkerd98030e2009-05-02 15:13:40 +00002473/*
2474 * Return an informational string about the CRL.
2475 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002476int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2477 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002478{
2479 int i, n, nr, ret;
2480 char *p;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002481 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002482
2483 p = buf;
2484 n = size;
2485
2486 ret = snprintf( p, n, "%sCRL version : %d",
2487 prefix, crl->version );
2488 SAFE_SNPRINTF();
2489
2490 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2491 SAFE_SNPRINTF();
2492 ret = x509parse_dn_gets( p, n, &crl->issuer );
2493 SAFE_SNPRINTF();
2494
2495 ret = snprintf( p, n, "\n%sthis update : " \
2496 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2497 crl->this_update.year, crl->this_update.mon,
2498 crl->this_update.day, crl->this_update.hour,
2499 crl->this_update.min, crl->this_update.sec );
2500 SAFE_SNPRINTF();
2501
2502 ret = snprintf( p, n, "\n%snext update : " \
2503 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2504 crl->next_update.year, crl->next_update.mon,
2505 crl->next_update.day, crl->next_update.hour,
2506 crl->next_update.min, crl->next_update.sec );
2507 SAFE_SNPRINTF();
2508
2509 entry = &crl->entry;
2510
2511 ret = snprintf( p, n, "\n%sRevoked certificates:",
2512 prefix );
2513 SAFE_SNPRINTF();
2514
Paul Bakker9be19372009-07-27 20:21:53 +00002515 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002516 {
2517 ret = snprintf( p, n, "\n%sserial number: ",
2518 prefix );
2519 SAFE_SNPRINTF();
2520
2521 nr = ( entry->serial.len <= 32 )
2522 ? entry->serial.len : 32;
2523
Paul Bakker74111d32011-01-15 16:57:55 +00002524 for( i = 0; i < nr; i++ )
2525 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002526 ret = snprintf( p, n, "%02X%s",
2527 entry->serial.p[i], ( i < nr - 1 ) ? ":" : "" );
2528 SAFE_SNPRINTF();
2529 }
2530
2531 ret = snprintf( p, n, " revocation date: " \
2532 "%04d-%02d-%02d %02d:%02d:%02d",
2533 entry->revocation_date.year, entry->revocation_date.mon,
2534 entry->revocation_date.day, entry->revocation_date.hour,
2535 entry->revocation_date.min, entry->revocation_date.sec );
2536 SAFE_SNPRINTF();
2537
2538 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002539 }
2540
Paul Bakkerd98030e2009-05-02 15:13:40 +00002541 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2542 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002543
Paul Bakker27d66162010-03-17 06:56:01 +00002544 switch( crl->sig_alg )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002545 {
2546 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2547 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2548 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2549 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2550 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2551 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2552 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2553 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2554 default: ret = snprintf( p, n, "???" ); break;
2555 }
2556 SAFE_SNPRINTF();
2557
Paul Bakker1e27bb22009-07-19 20:25:25 +00002558 ret = snprintf( p, n, "\n" );
2559 SAFE_SNPRINTF();
2560
Paul Bakkerd98030e2009-05-02 15:13:40 +00002561 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002562}
2563
2564/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00002565 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00002566 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002567int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00002568{
2569 struct tm *lt;
2570 time_t tt;
2571
2572 tt = time( NULL );
2573 lt = localtime( &tt );
2574
Paul Bakker40ea7de2009-05-03 10:18:48 +00002575 if( lt->tm_year > to->year - 1900 )
2576 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002577
Paul Bakker40ea7de2009-05-03 10:18:48 +00002578 if( lt->tm_year == to->year - 1900 &&
2579 lt->tm_mon > to->mon - 1 )
2580 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002581
Paul Bakker40ea7de2009-05-03 10:18:48 +00002582 if( lt->tm_year == to->year - 1900 &&
2583 lt->tm_mon == to->mon - 1 &&
2584 lt->tm_mday > to->day )
2585 return( 1 );
2586
2587 return( 0 );
2588}
2589
2590/*
2591 * Return 1 if the certificate is revoked, or 0 otherwise.
2592 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002593int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002594{
Paul Bakkerff60ee62010-03-16 21:09:09 +00002595 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00002596
2597 while( cur != NULL && cur->serial.len != 0 )
2598 {
2599 if( memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
2600 {
2601 if( x509parse_time_expired( &cur->revocation_date ) )
2602 return( 1 );
2603 }
2604
2605 cur = cur->next;
2606 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002607
2608 return( 0 );
2609}
2610
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002611/*
2612 * Wrapper for x509 hashes.
2613 *
2614 * @param out Buffer to receive the hash (Should be at least 64 bytes)
2615 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002616static void x509_hash( const unsigned char *in, int len, int alg,
Paul Bakker5121ce52009-01-03 21:22:43 +00002617 unsigned char *out )
2618{
2619 switch( alg )
2620 {
Paul Bakker40e46942009-01-03 21:51:57 +00002621#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002622 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002623#endif
Paul Bakker40e46942009-01-03 21:51:57 +00002624#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002625 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002626#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002627#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002628 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002629#endif
2630#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002631 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002632#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00002633#if defined(POLARSSL_SHA2_C)
2634 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
2635 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
2636#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00002637#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002638 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
2639 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
2640#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002641 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002642 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002643 break;
2644 }
2645}
2646
2647/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00002648 * Check that the given certificate is valid accoring to the CRL.
2649 */
2650static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
2651 x509_crl *crl_list)
2652{
2653 int flags = 0;
2654 int hash_id;
2655 unsigned char hash[64];
2656
2657 /*
2658 * TODO: What happens if no CRL is present?
2659 * Suggestion: Revocation state should be unknown if no CRL is present.
2660 * For backwards compatibility this is not yet implemented.
2661 */
2662
2663 while( ca != NULL && crl_list != NULL && crl_list->version != 0 )
2664 {
2665 if( crl_list->issuer_raw.len != ca->subject_raw.len ||
2666 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
2667 crl_list->issuer_raw.len ) != 0 )
2668 {
2669 crl_list = crl_list->next;
2670 continue;
2671 }
2672
2673 /*
2674 * Check if CRL is correctly signed by the trusted CA
2675 */
2676 hash_id = crl_list->sig_alg;
2677
2678 x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
2679
2680 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, hash_id,
2681 0, hash, crl_list->sig.p ) == 0 )
2682 {
2683 /*
2684 * CRL is not trusted
2685 */
2686 flags |= BADCRL_NOT_TRUSTED;
2687 break;
2688 }
2689
2690 /*
2691 * Check for validity of CRL (Do not drop out)
2692 */
2693 if( x509parse_time_expired( &crl_list->next_update ) )
2694 flags |= BADCRL_EXPIRED;
2695
2696 /*
2697 * Check if certificate is revoked
2698 */
2699 if( x509parse_revoked(crt, crl_list) )
2700 {
2701 flags |= BADCERT_REVOKED;
2702 break;
2703 }
2704
2705 crl_list = crl_list->next;
2706 }
2707 return flags;
2708}
2709
2710/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002711 * Verify the certificate validity
2712 */
2713int x509parse_verify( x509_cert *crt,
2714 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00002715 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002716 const char *cn, int *flags,
2717 int (*f_vrfy)(void *, x509_cert *, int, int),
2718 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00002719{
2720 int cn_len;
2721 int hash_id;
2722 int pathlen;
Paul Bakker76fd75a2011-01-16 21:12:10 +00002723 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00002724 x509_name *name;
Paul Bakker4593aea2009-02-09 22:32:35 +00002725 unsigned char hash[64];
Paul Bakker5121ce52009-01-03 21:22:43 +00002726
Paul Bakker40ea7de2009-05-03 10:18:48 +00002727 *flags = 0;
2728
2729 if( x509parse_time_expired( &crt->valid_to ) )
2730 *flags = BADCERT_EXPIRED;
Paul Bakker5121ce52009-01-03 21:22:43 +00002731
2732 if( cn != NULL )
2733 {
2734 name = &crt->subject;
2735 cn_len = strlen( cn );
2736
2737 while( name != NULL )
2738 {
2739 if( memcmp( name->oid.p, OID_CN, 3 ) == 0 &&
2740 memcmp( name->val.p, cn, cn_len ) == 0 &&
2741 name->val.len == cn_len )
2742 break;
2743
2744 name = name->next;
2745 }
2746
2747 if( name == NULL )
2748 *flags |= BADCERT_CN_MISMATCH;
2749 }
2750
Paul Bakker5121ce52009-01-03 21:22:43 +00002751 /*
2752 * Iterate upwards in the given cert chain,
2753 * ignoring any upper cert with CA != TRUE.
2754 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00002755 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002756
2757 pathlen = 1;
2758
Paul Bakker76fd75a2011-01-16 21:12:10 +00002759 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002760 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002761 if( parent->ca_istrue == 0 ||
2762 crt->issuer_raw.len != parent->subject_raw.len ||
2763 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00002764 crt->issuer_raw.len ) != 0 )
2765 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002766 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002767 continue;
2768 }
2769
Paul Bakker27d66162010-03-17 06:56:01 +00002770 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00002771
2772 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2773
Paul Bakker76fd75a2011-01-16 21:12:10 +00002774 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, hash_id, 0, hash,
2775 crt->sig.p ) != 0 )
2776 *flags |= BADCERT_NOT_TRUSTED;
2777
2778 /* Check trusted CA's CRL for the given crt */
2779 *flags |= x509parse_verifycrl(crt, parent, ca_crl);
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002780
2781 /* crt is verified to be a child of the parent cur, call verify callback */
Paul Bakker74111d32011-01-15 16:57:55 +00002782 if( NULL != f_vrfy )
2783 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002784 if( f_vrfy( p_vrfy, crt, pathlen - 1, ( *flags == 0 ) ) != 0 )
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002785 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker76fd75a2011-01-16 21:12:10 +00002786 else
2787 *flags = 0;
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002788 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00002789 else if( *flags != 0 )
2790 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002791
2792 pathlen++;
2793
Paul Bakker76fd75a2011-01-16 21:12:10 +00002794 crt = parent;
2795 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002796 }
2797
2798 /*
Paul Bakker76fd75a2011-01-16 21:12:10 +00002799 * Attempt to validate topmost cert with our CA chain.
Paul Bakker5121ce52009-01-03 21:22:43 +00002800 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00002801 *flags |= BADCERT_NOT_TRUSTED;
2802
Paul Bakker7c6d4a42009-03-28 20:35:47 +00002803 while( trust_ca != NULL && trust_ca->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002804 {
2805 if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
2806 memcmp( crt->issuer_raw.p, trust_ca->subject_raw.p,
2807 crt->issuer_raw.len ) != 0 )
2808 {
2809 trust_ca = trust_ca->next;
2810 continue;
2811 }
2812
2813 if( trust_ca->max_pathlen > 0 &&
2814 trust_ca->max_pathlen < pathlen )
2815 break;
2816
Paul Bakker27d66162010-03-17 06:56:01 +00002817 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00002818
2819 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2820
2821 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
2822 0, hash, crt->sig.p ) == 0 )
2823 {
2824 /*
2825 * cert. is signed by a trusted CA
2826 */
2827 *flags &= ~BADCERT_NOT_TRUSTED;
2828 break;
2829 }
2830
2831 trust_ca = trust_ca->next;
2832 }
2833
Paul Bakker76fd75a2011-01-16 21:12:10 +00002834 /* Check trusted CA's CRL for the given crt */
2835 *flags |= x509parse_verifycrl( crt, trust_ca, ca_crl );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002836
2837 /* Verification succeeded, call callback on top cert */
Paul Bakker74111d32011-01-15 16:57:55 +00002838 if( NULL != f_vrfy )
2839 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002840 if( f_vrfy(p_vrfy, crt, pathlen-1, ( *flags == 0 ) ) != 0 )
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002841 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker76fd75a2011-01-16 21:12:10 +00002842 else
2843 *flags = 0;
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002844 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00002845 else if( *flags != 0 )
2846 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002847
Paul Bakker5121ce52009-01-03 21:22:43 +00002848 return( 0 );
2849}
2850
2851/*
2852 * Unallocate all certificate data
2853 */
2854void x509_free( x509_cert *crt )
2855{
2856 x509_cert *cert_cur = crt;
2857 x509_cert *cert_prv;
2858 x509_name *name_cur;
2859 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00002860 x509_sequence *seq_cur;
2861 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00002862
2863 if( crt == NULL )
2864 return;
2865
2866 do
2867 {
2868 rsa_free( &cert_cur->rsa );
2869
2870 name_cur = cert_cur->issuer.next;
2871 while( name_cur != NULL )
2872 {
2873 name_prv = name_cur;
2874 name_cur = name_cur->next;
2875 memset( name_prv, 0, sizeof( x509_name ) );
2876 free( name_prv );
2877 }
2878
2879 name_cur = cert_cur->subject.next;
2880 while( name_cur != NULL )
2881 {
2882 name_prv = name_cur;
2883 name_cur = name_cur->next;
2884 memset( name_prv, 0, sizeof( x509_name ) );
2885 free( name_prv );
2886 }
2887
Paul Bakker74111d32011-01-15 16:57:55 +00002888 seq_cur = cert_cur->ext_key_usage.next;
2889 while( seq_cur != NULL )
2890 {
2891 seq_prv = seq_cur;
2892 seq_cur = seq_cur->next;
2893 memset( seq_prv, 0, sizeof( x509_sequence ) );
2894 free( seq_prv );
2895 }
2896
Paul Bakker5121ce52009-01-03 21:22:43 +00002897 if( cert_cur->raw.p != NULL )
2898 {
2899 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
2900 free( cert_cur->raw.p );
2901 }
2902
2903 cert_cur = cert_cur->next;
2904 }
2905 while( cert_cur != NULL );
2906
2907 cert_cur = crt;
2908 do
2909 {
2910 cert_prv = cert_cur;
2911 cert_cur = cert_cur->next;
2912
2913 memset( cert_prv, 0, sizeof( x509_cert ) );
2914 if( cert_prv != crt )
2915 free( cert_prv );
2916 }
2917 while( cert_cur != NULL );
2918}
2919
Paul Bakkerd98030e2009-05-02 15:13:40 +00002920/*
2921 * Unallocate all CRL data
2922 */
2923void x509_crl_free( x509_crl *crl )
2924{
2925 x509_crl *crl_cur = crl;
2926 x509_crl *crl_prv;
2927 x509_name *name_cur;
2928 x509_name *name_prv;
2929 x509_crl_entry *entry_cur;
2930 x509_crl_entry *entry_prv;
2931
2932 if( crl == NULL )
2933 return;
2934
2935 do
2936 {
2937 name_cur = crl_cur->issuer.next;
2938 while( name_cur != NULL )
2939 {
2940 name_prv = name_cur;
2941 name_cur = name_cur->next;
2942 memset( name_prv, 0, sizeof( x509_name ) );
2943 free( name_prv );
2944 }
2945
2946 entry_cur = crl_cur->entry.next;
2947 while( entry_cur != NULL )
2948 {
2949 entry_prv = entry_cur;
2950 entry_cur = entry_cur->next;
2951 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
2952 free( entry_prv );
2953 }
2954
2955 if( crl_cur->raw.p != NULL )
2956 {
2957 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
2958 free( crl_cur->raw.p );
2959 }
2960
2961 crl_cur = crl_cur->next;
2962 }
2963 while( crl_cur != NULL );
2964
2965 crl_cur = crl;
2966 do
2967 {
2968 crl_prv = crl_cur;
2969 crl_cur = crl_cur->next;
2970
2971 memset( crl_prv, 0, sizeof( x509_crl ) );
2972 if( crl_prv != crl )
2973 free( crl_prv );
2974 }
2975 while( crl_cur != NULL );
2976}
2977
Paul Bakker40e46942009-01-03 21:51:57 +00002978#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002979
Paul Bakker40e46942009-01-03 21:51:57 +00002980#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00002981
2982/*
2983 * Checkup routine
2984 */
2985int x509_self_test( int verbose )
2986{
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002987#if defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00002988 int ret, i, j;
2989 x509_cert cacert;
2990 x509_cert clicert;
2991 rsa_context rsa;
Paul Bakker1b57b062011-01-06 15:48:19 +00002992 dhm_context dhm;
Paul Bakker5121ce52009-01-03 21:22:43 +00002993
2994 if( verbose != 0 )
2995 printf( " X.509 certificate load: " );
2996
2997 memset( &clicert, 0, sizeof( x509_cert ) );
2998
2999 ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
3000 strlen( test_cli_crt ) );
3001 if( ret != 0 )
3002 {
3003 if( verbose != 0 )
3004 printf( "failed\n" );
3005
3006 return( ret );
3007 }
3008
3009 memset( &cacert, 0, sizeof( x509_cert ) );
3010
3011 ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
3012 strlen( test_ca_crt ) );
3013 if( ret != 0 )
3014 {
3015 if( verbose != 0 )
3016 printf( "failed\n" );
3017
3018 return( ret );
3019 }
3020
3021 if( verbose != 0 )
3022 printf( "passed\n X.509 private key load: " );
3023
3024 i = strlen( test_ca_key );
3025 j = strlen( test_ca_pwd );
3026
3027 if( ( ret = x509parse_key( &rsa,
3028 (unsigned char *) test_ca_key, i,
3029 (unsigned char *) test_ca_pwd, j ) ) != 0 )
3030 {
3031 if( verbose != 0 )
3032 printf( "failed\n" );
3033
3034 return( ret );
3035 }
3036
3037 if( verbose != 0 )
3038 printf( "passed\n X.509 signature verify: ");
3039
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003040 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &i, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003041 if( ret != 0 )
3042 {
3043 if( verbose != 0 )
3044 printf( "failed\n" );
3045
3046 return( ret );
3047 }
3048
3049 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003050 printf( "passed\n X.509 DHM parameter load: " );
3051
3052 i = strlen( test_dhm_params );
3053 j = strlen( test_ca_pwd );
3054
3055 if( ( ret = x509parse_dhm( &dhm, (unsigned char *) test_dhm_params, i ) ) != 0 )
3056 {
3057 if( verbose != 0 )
3058 printf( "failed\n" );
3059
3060 return( ret );
3061 }
3062
3063 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003064 printf( "passed\n\n" );
3065
3066 x509_free( &cacert );
3067 x509_free( &clicert );
3068 rsa_free( &rsa );
Paul Bakker1b57b062011-01-06 15:48:19 +00003069 dhm_free( &dhm );
Paul Bakker5121ce52009-01-03 21:22:43 +00003070
3071 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003072#else
3073 ((void) verbose);
3074 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3075#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003076}
3077
3078#endif
3079
3080#endif