blob: 6dae9430486e596ee7a76909cc949d749cab8bf4 [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 Bakkerd98030e2009-05-02 15:13:40 +00002309 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002310 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002311int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2312 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002313{
Paul Bakkerd98030e2009-05-02 15:13:40 +00002314 int i, n, nr, ret;
2315 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00002316
2317 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002318 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002319
Paul Bakkerd98030e2009-05-02 15:13:40 +00002320 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002321 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002322 SAFE_SNPRINTF();
2323 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002324 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002325 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002326
Paul Bakkerd98030e2009-05-02 15:13:40 +00002327 nr = ( crt->serial.len <= 32 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002328 ? crt->serial.len : 32;
2329
Paul Bakkerd98030e2009-05-02 15:13:40 +00002330 for( i = 0; i < nr; i++ )
2331 {
2332 ret = snprintf( p, n, "%02X%s",
2333 crt->serial.p[i], ( i < nr - 1 ) ? ":" : "" );
2334 SAFE_SNPRINTF();
2335 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002336
Paul Bakkerd98030e2009-05-02 15:13:40 +00002337 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2338 SAFE_SNPRINTF();
2339 ret = x509parse_dn_gets( p, n, &crt->issuer );
2340 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002341
Paul Bakkerd98030e2009-05-02 15:13:40 +00002342 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2343 SAFE_SNPRINTF();
2344 ret = x509parse_dn_gets( p, n, &crt->subject );
2345 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002346
Paul Bakkerd98030e2009-05-02 15:13:40 +00002347 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002348 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2349 crt->valid_from.year, crt->valid_from.mon,
2350 crt->valid_from.day, crt->valid_from.hour,
2351 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002352 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002353
Paul Bakkerd98030e2009-05-02 15:13:40 +00002354 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002355 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2356 crt->valid_to.year, crt->valid_to.mon,
2357 crt->valid_to.day, crt->valid_to.hour,
2358 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002359 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002360
Paul Bakkerd98030e2009-05-02 15:13:40 +00002361 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2362 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002363
Paul Bakker27d66162010-03-17 06:56:01 +00002364 switch( crt->sig_alg )
Paul Bakker5121ce52009-01-03 21:22:43 +00002365 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002366 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2367 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2368 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2369 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2370 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2371 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2372 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2373 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2374 default: ret = snprintf( p, n, "???" ); break;
2375 }
2376 SAFE_SNPRINTF();
2377
2378 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
2379 crt->rsa.N.n * (int) sizeof( unsigned long ) * 8 );
2380 SAFE_SNPRINTF();
2381
2382 return( size - n );
2383}
2384
Paul Bakker74111d32011-01-15 16:57:55 +00002385/* Compare a given OID string with an OID x509_buf * */
2386#define OID_CMP(oid_str, oid_buf) \
2387 ( ( OID_SIZE(oid_str) == (oid_buf)->len ) && \
2388 memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0)
2389
2390/*
2391 * Return an informational string describing the given OID
2392 */
2393const char *x509_oid_get_description( x509_buf *oid )
2394{
2395 if ( oid == NULL )
2396 return ( NULL );
2397
2398 else if( OID_CMP( OID_SERVER_AUTH, oid ) )
2399 return( STRING_SERVER_AUTH );
2400
2401 else if( OID_CMP( OID_CLIENT_AUTH, oid ) )
2402 return( STRING_CLIENT_AUTH );
2403
2404 else if( OID_CMP( OID_CODE_SIGNING, oid ) )
2405 return( STRING_CODE_SIGNING );
2406
2407 else if( OID_CMP( OID_EMAIL_PROTECTION, oid ) )
2408 return( STRING_EMAIL_PROTECTION );
2409
2410 else if( OID_CMP( OID_TIME_STAMPING, oid ) )
2411 return( STRING_TIME_STAMPING );
2412
2413 else if( OID_CMP( OID_OCSP_SIGNING, oid ) )
2414 return( STRING_OCSP_SIGNING );
2415
2416 return( NULL );
2417}
2418
2419/* Return the x.y.z.... style numeric string for the given OID */
2420int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2421{
2422 int ret, n, i;
2423 unsigned int value;
2424 char *p;
2425
2426 p = buf;
2427 n = size;
2428
2429 /* First byte contains first two dots */
2430 if( oid->len > 0 )
2431 {
2432 ret = snprintf( p, n, "%d.%d", oid->p[0]/40, oid->p[0]%40 );
2433 SAFE_SNPRINTF();
2434 }
2435
2436 /* TODO: value can overflow in value. */
2437 value = 0;
2438 for( i=1; i < oid->len; i++ )
2439 {
2440 value <<= 7;
2441 value += oid->p[i] & 0x7F;
2442
2443 if( !( oid->p[i] & 0x80 ) )
2444 {
2445 /* Last byte */
2446 ret = snprintf( p, n, ".%d", value );
2447 SAFE_SNPRINTF();
2448 value = 0;
2449 }
2450 }
2451
2452 return( size - n );
2453}
2454
Paul Bakkerd98030e2009-05-02 15:13:40 +00002455/*
2456 * Return an informational string about the CRL.
2457 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002458int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2459 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002460{
2461 int i, n, nr, ret;
2462 char *p;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002463 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002464
2465 p = buf;
2466 n = size;
2467
2468 ret = snprintf( p, n, "%sCRL version : %d",
2469 prefix, crl->version );
2470 SAFE_SNPRINTF();
2471
2472 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2473 SAFE_SNPRINTF();
2474 ret = x509parse_dn_gets( p, n, &crl->issuer );
2475 SAFE_SNPRINTF();
2476
2477 ret = snprintf( p, n, "\n%sthis update : " \
2478 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2479 crl->this_update.year, crl->this_update.mon,
2480 crl->this_update.day, crl->this_update.hour,
2481 crl->this_update.min, crl->this_update.sec );
2482 SAFE_SNPRINTF();
2483
2484 ret = snprintf( p, n, "\n%snext update : " \
2485 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2486 crl->next_update.year, crl->next_update.mon,
2487 crl->next_update.day, crl->next_update.hour,
2488 crl->next_update.min, crl->next_update.sec );
2489 SAFE_SNPRINTF();
2490
2491 entry = &crl->entry;
2492
2493 ret = snprintf( p, n, "\n%sRevoked certificates:",
2494 prefix );
2495 SAFE_SNPRINTF();
2496
Paul Bakker9be19372009-07-27 20:21:53 +00002497 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002498 {
2499 ret = snprintf( p, n, "\n%sserial number: ",
2500 prefix );
2501 SAFE_SNPRINTF();
2502
2503 nr = ( entry->serial.len <= 32 )
2504 ? entry->serial.len : 32;
2505
Paul Bakker74111d32011-01-15 16:57:55 +00002506 for( i = 0; i < nr; i++ )
2507 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002508 ret = snprintf( p, n, "%02X%s",
2509 entry->serial.p[i], ( i < nr - 1 ) ? ":" : "" );
2510 SAFE_SNPRINTF();
2511 }
2512
2513 ret = snprintf( p, n, " revocation date: " \
2514 "%04d-%02d-%02d %02d:%02d:%02d",
2515 entry->revocation_date.year, entry->revocation_date.mon,
2516 entry->revocation_date.day, entry->revocation_date.hour,
2517 entry->revocation_date.min, entry->revocation_date.sec );
2518 SAFE_SNPRINTF();
2519
2520 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002521 }
2522
Paul Bakkerd98030e2009-05-02 15:13:40 +00002523 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2524 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002525
Paul Bakker27d66162010-03-17 06:56:01 +00002526 switch( crl->sig_alg )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002527 {
2528 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2529 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2530 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2531 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2532 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2533 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2534 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2535 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2536 default: ret = snprintf( p, n, "???" ); break;
2537 }
2538 SAFE_SNPRINTF();
2539
Paul Bakker1e27bb22009-07-19 20:25:25 +00002540 ret = snprintf( p, n, "\n" );
2541 SAFE_SNPRINTF();
2542
Paul Bakkerd98030e2009-05-02 15:13:40 +00002543 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002544}
2545
2546/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00002547 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00002548 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002549int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00002550{
2551 struct tm *lt;
2552 time_t tt;
2553
2554 tt = time( NULL );
2555 lt = localtime( &tt );
2556
Paul Bakker40ea7de2009-05-03 10:18:48 +00002557 if( lt->tm_year > to->year - 1900 )
2558 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002559
Paul Bakker40ea7de2009-05-03 10:18:48 +00002560 if( lt->tm_year == to->year - 1900 &&
2561 lt->tm_mon > to->mon - 1 )
2562 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002563
Paul Bakker40ea7de2009-05-03 10:18:48 +00002564 if( lt->tm_year == to->year - 1900 &&
2565 lt->tm_mon == to->mon - 1 &&
2566 lt->tm_mday > to->day )
2567 return( 1 );
2568
2569 return( 0 );
2570}
2571
2572/*
2573 * Return 1 if the certificate is revoked, or 0 otherwise.
2574 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002575int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002576{
Paul Bakkerff60ee62010-03-16 21:09:09 +00002577 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00002578
2579 while( cur != NULL && cur->serial.len != 0 )
2580 {
2581 if( memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
2582 {
2583 if( x509parse_time_expired( &cur->revocation_date ) )
2584 return( 1 );
2585 }
2586
2587 cur = cur->next;
2588 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002589
2590 return( 0 );
2591}
2592
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002593/*
2594 * Wrapper for x509 hashes.
2595 *
2596 * @param out Buffer to receive the hash (Should be at least 64 bytes)
2597 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002598static void x509_hash( const unsigned char *in, int len, int alg,
Paul Bakker5121ce52009-01-03 21:22:43 +00002599 unsigned char *out )
2600{
2601 switch( alg )
2602 {
Paul Bakker40e46942009-01-03 21:51:57 +00002603#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002604 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002605#endif
Paul Bakker40e46942009-01-03 21:51:57 +00002606#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002607 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002608#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002609#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002610 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002611#endif
2612#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002613 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002614#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00002615#if defined(POLARSSL_SHA2_C)
2616 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
2617 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
2618#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00002619#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002620 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
2621 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
2622#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002623 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002624 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002625 break;
2626 }
2627}
2628
2629/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00002630 * Check that the given certificate is valid accoring to the CRL.
2631 */
2632static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
2633 x509_crl *crl_list)
2634{
2635 int flags = 0;
2636 int hash_id;
2637 unsigned char hash[64];
2638
2639 /*
2640 * TODO: What happens if no CRL is present?
2641 * Suggestion: Revocation state should be unknown if no CRL is present.
2642 * For backwards compatibility this is not yet implemented.
2643 */
2644
2645 while( ca != NULL && crl_list != NULL && crl_list->version != 0 )
2646 {
2647 if( crl_list->issuer_raw.len != ca->subject_raw.len ||
2648 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
2649 crl_list->issuer_raw.len ) != 0 )
2650 {
2651 crl_list = crl_list->next;
2652 continue;
2653 }
2654
2655 /*
2656 * Check if CRL is correctly signed by the trusted CA
2657 */
2658 hash_id = crl_list->sig_alg;
2659
2660 x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
2661
2662 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, hash_id,
2663 0, hash, crl_list->sig.p ) == 0 )
2664 {
2665 /*
2666 * CRL is not trusted
2667 */
2668 flags |= BADCRL_NOT_TRUSTED;
2669 break;
2670 }
2671
2672 /*
2673 * Check for validity of CRL (Do not drop out)
2674 */
2675 if( x509parse_time_expired( &crl_list->next_update ) )
2676 flags |= BADCRL_EXPIRED;
2677
2678 /*
2679 * Check if certificate is revoked
2680 */
2681 if( x509parse_revoked(crt, crl_list) )
2682 {
2683 flags |= BADCERT_REVOKED;
2684 break;
2685 }
2686
2687 crl_list = crl_list->next;
2688 }
2689 return flags;
2690}
2691
2692/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002693 * Verify the certificate validity
2694 */
2695int x509parse_verify( x509_cert *crt,
2696 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00002697 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002698 const char *cn, int *flags,
2699 int (*f_vrfy)(void *, x509_cert *, int, int),
2700 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00002701{
2702 int cn_len;
2703 int hash_id;
2704 int pathlen;
Paul Bakker76fd75a2011-01-16 21:12:10 +00002705 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00002706 x509_name *name;
Paul Bakker4593aea2009-02-09 22:32:35 +00002707 unsigned char hash[64];
Paul Bakker5121ce52009-01-03 21:22:43 +00002708
Paul Bakker40ea7de2009-05-03 10:18:48 +00002709 *flags = 0;
2710
2711 if( x509parse_time_expired( &crt->valid_to ) )
2712 *flags = BADCERT_EXPIRED;
Paul Bakker5121ce52009-01-03 21:22:43 +00002713
2714 if( cn != NULL )
2715 {
2716 name = &crt->subject;
2717 cn_len = strlen( cn );
2718
2719 while( name != NULL )
2720 {
2721 if( memcmp( name->oid.p, OID_CN, 3 ) == 0 &&
2722 memcmp( name->val.p, cn, cn_len ) == 0 &&
2723 name->val.len == cn_len )
2724 break;
2725
2726 name = name->next;
2727 }
2728
2729 if( name == NULL )
2730 *flags |= BADCERT_CN_MISMATCH;
2731 }
2732
Paul Bakker5121ce52009-01-03 21:22:43 +00002733 /*
2734 * Iterate upwards in the given cert chain,
2735 * ignoring any upper cert with CA != TRUE.
2736 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00002737 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002738
2739 pathlen = 1;
2740
Paul Bakker76fd75a2011-01-16 21:12:10 +00002741 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002742 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002743 if( parent->ca_istrue == 0 ||
2744 crt->issuer_raw.len != parent->subject_raw.len ||
2745 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00002746 crt->issuer_raw.len ) != 0 )
2747 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002748 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002749 continue;
2750 }
2751
Paul Bakker27d66162010-03-17 06:56:01 +00002752 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00002753
2754 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2755
Paul Bakker76fd75a2011-01-16 21:12:10 +00002756 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, hash_id, 0, hash,
2757 crt->sig.p ) != 0 )
2758 *flags |= BADCERT_NOT_TRUSTED;
2759
2760 /* Check trusted CA's CRL for the given crt */
2761 *flags |= x509parse_verifycrl(crt, parent, ca_crl);
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002762
2763 /* crt is verified to be a child of the parent cur, call verify callback */
Paul Bakker74111d32011-01-15 16:57:55 +00002764 if( NULL != f_vrfy )
2765 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002766 if( f_vrfy( p_vrfy, crt, pathlen - 1, ( *flags == 0 ) ) != 0 )
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002767 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker76fd75a2011-01-16 21:12:10 +00002768 else
2769 *flags = 0;
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002770 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00002771 else if( *flags != 0 )
2772 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002773
2774 pathlen++;
2775
Paul Bakker76fd75a2011-01-16 21:12:10 +00002776 crt = parent;
2777 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002778 }
2779
2780 /*
Paul Bakker76fd75a2011-01-16 21:12:10 +00002781 * Attempt to validate topmost cert with our CA chain.
Paul Bakker5121ce52009-01-03 21:22:43 +00002782 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00002783 *flags |= BADCERT_NOT_TRUSTED;
2784
Paul Bakker7c6d4a42009-03-28 20:35:47 +00002785 while( trust_ca != NULL && trust_ca->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002786 {
2787 if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
2788 memcmp( crt->issuer_raw.p, trust_ca->subject_raw.p,
2789 crt->issuer_raw.len ) != 0 )
2790 {
2791 trust_ca = trust_ca->next;
2792 continue;
2793 }
2794
2795 if( trust_ca->max_pathlen > 0 &&
2796 trust_ca->max_pathlen < pathlen )
2797 break;
2798
Paul Bakker27d66162010-03-17 06:56:01 +00002799 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00002800
2801 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2802
2803 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
2804 0, hash, crt->sig.p ) == 0 )
2805 {
2806 /*
2807 * cert. is signed by a trusted CA
2808 */
2809 *flags &= ~BADCERT_NOT_TRUSTED;
2810 break;
2811 }
2812
2813 trust_ca = trust_ca->next;
2814 }
2815
Paul Bakker76fd75a2011-01-16 21:12:10 +00002816 /* Check trusted CA's CRL for the given crt */
2817 *flags |= x509parse_verifycrl( crt, trust_ca, ca_crl );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002818
2819 /* Verification succeeded, call callback on top cert */
Paul Bakker74111d32011-01-15 16:57:55 +00002820 if( NULL != f_vrfy )
2821 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002822 if( f_vrfy(p_vrfy, crt, pathlen-1, ( *flags == 0 ) ) != 0 )
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002823 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker76fd75a2011-01-16 21:12:10 +00002824 else
2825 *flags = 0;
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002826 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00002827 else if( *flags != 0 )
2828 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002829
Paul Bakker5121ce52009-01-03 21:22:43 +00002830 return( 0 );
2831}
2832
2833/*
2834 * Unallocate all certificate data
2835 */
2836void x509_free( x509_cert *crt )
2837{
2838 x509_cert *cert_cur = crt;
2839 x509_cert *cert_prv;
2840 x509_name *name_cur;
2841 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00002842 x509_sequence *seq_cur;
2843 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00002844
2845 if( crt == NULL )
2846 return;
2847
2848 do
2849 {
2850 rsa_free( &cert_cur->rsa );
2851
2852 name_cur = cert_cur->issuer.next;
2853 while( name_cur != NULL )
2854 {
2855 name_prv = name_cur;
2856 name_cur = name_cur->next;
2857 memset( name_prv, 0, sizeof( x509_name ) );
2858 free( name_prv );
2859 }
2860
2861 name_cur = cert_cur->subject.next;
2862 while( name_cur != NULL )
2863 {
2864 name_prv = name_cur;
2865 name_cur = name_cur->next;
2866 memset( name_prv, 0, sizeof( x509_name ) );
2867 free( name_prv );
2868 }
2869
Paul Bakker74111d32011-01-15 16:57:55 +00002870 seq_cur = cert_cur->ext_key_usage.next;
2871 while( seq_cur != NULL )
2872 {
2873 seq_prv = seq_cur;
2874 seq_cur = seq_cur->next;
2875 memset( seq_prv, 0, sizeof( x509_sequence ) );
2876 free( seq_prv );
2877 }
2878
Paul Bakker5121ce52009-01-03 21:22:43 +00002879 if( cert_cur->raw.p != NULL )
2880 {
2881 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
2882 free( cert_cur->raw.p );
2883 }
2884
2885 cert_cur = cert_cur->next;
2886 }
2887 while( cert_cur != NULL );
2888
2889 cert_cur = crt;
2890 do
2891 {
2892 cert_prv = cert_cur;
2893 cert_cur = cert_cur->next;
2894
2895 memset( cert_prv, 0, sizeof( x509_cert ) );
2896 if( cert_prv != crt )
2897 free( cert_prv );
2898 }
2899 while( cert_cur != NULL );
2900}
2901
Paul Bakkerd98030e2009-05-02 15:13:40 +00002902/*
2903 * Unallocate all CRL data
2904 */
2905void x509_crl_free( x509_crl *crl )
2906{
2907 x509_crl *crl_cur = crl;
2908 x509_crl *crl_prv;
2909 x509_name *name_cur;
2910 x509_name *name_prv;
2911 x509_crl_entry *entry_cur;
2912 x509_crl_entry *entry_prv;
2913
2914 if( crl == NULL )
2915 return;
2916
2917 do
2918 {
2919 name_cur = crl_cur->issuer.next;
2920 while( name_cur != NULL )
2921 {
2922 name_prv = name_cur;
2923 name_cur = name_cur->next;
2924 memset( name_prv, 0, sizeof( x509_name ) );
2925 free( name_prv );
2926 }
2927
2928 entry_cur = crl_cur->entry.next;
2929 while( entry_cur != NULL )
2930 {
2931 entry_prv = entry_cur;
2932 entry_cur = entry_cur->next;
2933 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
2934 free( entry_prv );
2935 }
2936
2937 if( crl_cur->raw.p != NULL )
2938 {
2939 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
2940 free( crl_cur->raw.p );
2941 }
2942
2943 crl_cur = crl_cur->next;
2944 }
2945 while( crl_cur != NULL );
2946
2947 crl_cur = crl;
2948 do
2949 {
2950 crl_prv = crl_cur;
2951 crl_cur = crl_cur->next;
2952
2953 memset( crl_prv, 0, sizeof( x509_crl ) );
2954 if( crl_prv != crl )
2955 free( crl_prv );
2956 }
2957 while( crl_cur != NULL );
2958}
2959
Paul Bakker40e46942009-01-03 21:51:57 +00002960#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002961
Paul Bakker40e46942009-01-03 21:51:57 +00002962#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00002963
2964/*
2965 * Checkup routine
2966 */
2967int x509_self_test( int verbose )
2968{
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002969#if defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00002970 int ret, i, j;
2971 x509_cert cacert;
2972 x509_cert clicert;
2973 rsa_context rsa;
Paul Bakker1b57b062011-01-06 15:48:19 +00002974 dhm_context dhm;
Paul Bakker5121ce52009-01-03 21:22:43 +00002975
2976 if( verbose != 0 )
2977 printf( " X.509 certificate load: " );
2978
2979 memset( &clicert, 0, sizeof( x509_cert ) );
2980
2981 ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
2982 strlen( test_cli_crt ) );
2983 if( ret != 0 )
2984 {
2985 if( verbose != 0 )
2986 printf( "failed\n" );
2987
2988 return( ret );
2989 }
2990
2991 memset( &cacert, 0, sizeof( x509_cert ) );
2992
2993 ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
2994 strlen( test_ca_crt ) );
2995 if( ret != 0 )
2996 {
2997 if( verbose != 0 )
2998 printf( "failed\n" );
2999
3000 return( ret );
3001 }
3002
3003 if( verbose != 0 )
3004 printf( "passed\n X.509 private key load: " );
3005
3006 i = strlen( test_ca_key );
3007 j = strlen( test_ca_pwd );
3008
3009 if( ( ret = x509parse_key( &rsa,
3010 (unsigned char *) test_ca_key, i,
3011 (unsigned char *) test_ca_pwd, j ) ) != 0 )
3012 {
3013 if( verbose != 0 )
3014 printf( "failed\n" );
3015
3016 return( ret );
3017 }
3018
3019 if( verbose != 0 )
3020 printf( "passed\n X.509 signature verify: ");
3021
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003022 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &i, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003023 if( ret != 0 )
3024 {
3025 if( verbose != 0 )
3026 printf( "failed\n" );
3027
3028 return( ret );
3029 }
3030
3031 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003032 printf( "passed\n X.509 DHM parameter load: " );
3033
3034 i = strlen( test_dhm_params );
3035 j = strlen( test_ca_pwd );
3036
3037 if( ( ret = x509parse_dhm( &dhm, (unsigned char *) test_dhm_params, i ) ) != 0 )
3038 {
3039 if( verbose != 0 )
3040 printf( "failed\n" );
3041
3042 return( ret );
3043 }
3044
3045 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003046 printf( "passed\n\n" );
3047
3048 x509_free( &cacert );
3049 x509_free( &clicert );
3050 rsa_free( &rsa );
Paul Bakker1b57b062011-01-06 15:48:19 +00003051 dhm_free( &dhm );
Paul Bakker5121ce52009-01-03 21:22:43 +00003052
3053 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003054#else
3055 ((void) verbose);
3056 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3057#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003058}
3059
3060#endif
3061
3062#endif