blob: 378f0a95646769bc394728774693a45039bdcf29 [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,
Paul Bakker74111d32011-01-15 16:57:55 +0000727 int *ca_istrue,
728 int *max_pathlen )
729{
730 int ret, len;
731
732 /*
733 * BasicConstraints ::= SEQUENCE {
734 * cA BOOLEAN DEFAULT FALSE,
735 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
736 */
Paul Bakker3cccddb2011-01-16 21:46:31 +0000737 *ca_istrue = 0; /* DEFAULT FALSE */
Paul Bakker74111d32011-01-15 16:57:55 +0000738 *max_pathlen = 0; /* endless */
739
740 if( ( ret = asn1_get_tag( p, end, &len,
741 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
742 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
743
744 if( *p == end )
745 return 0;
746
Paul Bakker3cccddb2011-01-16 21:46:31 +0000747 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000748 {
749 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker3cccddb2011-01-16 21:46:31 +0000750 ret = asn1_get_int( p, end, ca_istrue );
Paul Bakker74111d32011-01-15 16:57:55 +0000751
752 if( ret != 0 )
753 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
754
Paul Bakker3cccddb2011-01-16 21:46:31 +0000755 if( *ca_istrue != 0 )
756 *ca_istrue = 1;
Paul Bakker74111d32011-01-15 16:57:55 +0000757 }
758
759 if( *p == end )
760 return 0;
761
762 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
763 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
764
765 if( *p != end )
766 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
767 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
768
769 (*max_pathlen)++;
770
Paul Bakker74111d32011-01-15 16:57:55 +0000771 return 0;
772}
773
774static int x509_get_ns_cert_type( unsigned char **p,
775 const unsigned char *end,
776 unsigned char *ns_cert_type)
777{
778 int ret;
779 x509_bitstring bs = {0};
780
781 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
782 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
783
784 if( bs.len != 1 )
785 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
786 POLARSSL_ERR_ASN1_INVALID_LENGTH );
787
788 /* Get actual bitstring */
789 *ns_cert_type = *bs.p;
790 return 0;
791}
792
793static int x509_get_key_usage( unsigned char **p,
794 const unsigned char *end,
795 unsigned char *key_usage)
796{
797 int ret;
798 x509_bitstring bs = {0};
799
800 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
801 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
802
803 if( bs.len != 1 )
804 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
805 POLARSSL_ERR_ASN1_INVALID_LENGTH );
806
807 /* Get actual bitstring */
808 *key_usage = *bs.p;
809 return 0;
810}
811
Paul Bakkerd98030e2009-05-02 15:13:40 +0000812/*
Paul Bakker74111d32011-01-15 16:57:55 +0000813 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
814 *
815 * KeyPurposeId ::= OBJECT IDENTIFIER
816 */
817static int x509_get_ext_key_usage( unsigned char **p,
818 const unsigned char *end,
819 x509_sequence *ext_key_usage)
820{
821 int ret;
822
823 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
824 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
825
826 /* Sequence length must be >= 1 */
827 if( ext_key_usage->buf.p == NULL )
828 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
829 POLARSSL_ERR_ASN1_INVALID_LENGTH );
830
831 return 0;
832}
833
834/*
835 * X.509 v3 extensions
836 *
837 * TODO: Perform all of the basic constraints tests required by the RFC
838 * TODO: Set values for undetected extensions to a sane default?
839 *
Paul Bakkerd98030e2009-05-02 15:13:40 +0000840 */
841static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000842 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000843 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000844{
845 int ret, len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000846 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000847
Paul Bakker74111d32011-01-15 16:57:55 +0000848 if( ( ret = x509_get_ext( p, end, &crt->v3_ext ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000849 {
850 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
851 return( 0 );
852
853 return( ret );
854 }
855
Paul Bakker5121ce52009-01-03 21:22:43 +0000856 while( *p < end )
857 {
Paul Bakker74111d32011-01-15 16:57:55 +0000858 /*
859 * Extension ::= SEQUENCE {
860 * extnID OBJECT IDENTIFIER,
861 * critical BOOLEAN DEFAULT FALSE,
862 * extnValue OCTET STRING }
863 */
864 x509_buf extn_oid = {0, 0, NULL};
865 int is_critical = 0; /* DEFAULT FALSE */
866
Paul Bakker5121ce52009-01-03 21:22:43 +0000867 if( ( ret = asn1_get_tag( p, end, &len,
868 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000869 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000870
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000871 end_ext_data = *p + len;
872
Paul Bakker74111d32011-01-15 16:57:55 +0000873 /* Get extension ID */
874 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000875
Paul Bakker74111d32011-01-15 16:57:55 +0000876 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
877 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000878
Paul Bakker74111d32011-01-15 16:57:55 +0000879 extn_oid.p = *p;
880 *p += extn_oid.len;
881
882 if( ( end - *p ) < 1 )
883 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
884 POLARSSL_ERR_ASN1_OUT_OF_DATA );
885
886 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000887 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000888 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
889 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000890
Paul Bakker74111d32011-01-15 16:57:55 +0000891 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000892 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000893 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000894 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000895
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000896 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000897
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000898 if( end_ext_octet != end_ext_data )
899 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
900 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000901
Paul Bakker74111d32011-01-15 16:57:55 +0000902 /*
903 * Detect supported extensions
904 */
905 if( ( OID_SIZE( OID_BASIC_CONSTRAINTS ) == extn_oid.len ) &&
906 memcmp( extn_oid.p, OID_BASIC_CONSTRAINTS, extn_oid.len ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000907 {
Paul Bakker74111d32011-01-15 16:57:55 +0000908 /* Parse basic constraints */
909 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
Paul Bakker3cccddb2011-01-16 21:46:31 +0000910 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000911 return ( ret );
912 crt->ext_types |= EXT_BASIC_CONSTRAINTS;
Paul Bakker5121ce52009-01-03 21:22:43 +0000913 }
Paul Bakker74111d32011-01-15 16:57:55 +0000914 else if( ( OID_SIZE( OID_NS_CERT_TYPE ) == extn_oid.len ) &&
915 memcmp( extn_oid.p, OID_NS_CERT_TYPE, extn_oid.len ) == 0 )
916 {
917 /* Parse netscape certificate type */
918 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
919 &crt->ns_cert_type ) ) != 0 )
920 return ( ret );
921 crt->ext_types |= EXT_NS_CERT_TYPE;
922 }
923 else if( ( OID_SIZE( OID_KEY_USAGE ) == extn_oid.len ) &&
924 memcmp( extn_oid.p, OID_KEY_USAGE, extn_oid.len ) == 0 )
925 {
926 /* Parse key usage */
927 if( ( ret = x509_get_key_usage( p, end_ext_octet,
928 &crt->key_usage ) ) != 0 )
929 return ( ret );
930 crt->ext_types |= EXT_KEY_USAGE;
931 }
932 else if( ( OID_SIZE( OID_EXTENDED_KEY_USAGE ) == extn_oid.len ) &&
933 memcmp( extn_oid.p, OID_EXTENDED_KEY_USAGE, extn_oid.len ) == 0 )
934 {
935 /* Parse extended key usage */
936 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
937 &crt->ext_key_usage ) ) != 0 )
938 return ( ret );
939 crt->ext_types |= EXT_EXTENDED_KEY_USAGE;
940 }
941 else
942 {
943 /* No parser found, skip extension */
944 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +0000945
Paul Bakker74111d32011-01-15 16:57:55 +0000946 if( is_critical )
947 {
948 /* Data is marked as critical: fail */
949 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
950 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
951 }
952 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000953 }
954
955 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000956 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
957 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000958
Paul Bakker5121ce52009-01-03 21:22:43 +0000959 return( 0 );
960}
961
962/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000963 * X.509 CRL Entries
964 */
965static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000966 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000967 x509_crl_entry *entry )
968{
Paul Bakker9be19372009-07-27 20:21:53 +0000969 int ret, entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000970 x509_crl_entry *cur_entry = entry;
971
972 if( *p == end )
973 return( 0 );
974
Paul Bakker9be19372009-07-27 20:21:53 +0000975 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000976 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
977 {
978 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
979 return( 0 );
980
981 return( ret );
982 }
983
Paul Bakker9be19372009-07-27 20:21:53 +0000984 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000985
986 while( *p < end )
987 {
988 int len2;
989
990 if( ( ret = asn1_get_tag( p, end, &len2,
991 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
992 {
Paul Bakkerd98030e2009-05-02 15:13:40 +0000993 return( ret );
994 }
995
Paul Bakker9be19372009-07-27 20:21:53 +0000996 cur_entry->raw.tag = **p;
997 cur_entry->raw.p = *p;
998 cur_entry->raw.len = len2;
999
Paul Bakkerd98030e2009-05-02 15:13:40 +00001000 if( ( ret = x509_get_serial( p, end, &cur_entry->serial ) ) != 0 )
1001 return( ret );
1002
Paul Bakker91200182010-02-18 21:26:15 +00001003 if( ( ret = x509_get_time( p, end, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001004 return( ret );
1005
1006 if( ( ret = x509_get_crl_ext( p, end, &cur_entry->entry_ext ) ) != 0 )
1007 return( ret );
1008
Paul Bakker74111d32011-01-15 16:57:55 +00001009 if ( *p < end )
1010 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001011 cur_entry->next = malloc( sizeof( x509_crl_entry ) );
1012 cur_entry = cur_entry->next;
1013 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
1014 }
1015 }
1016
1017 return( 0 );
1018}
1019
Paul Bakker27d66162010-03-17 06:56:01 +00001020static int x509_get_sig_alg( const x509_buf *sig_oid, int *sig_alg )
1021{
1022 if( sig_oid->len == 9 &&
1023 memcmp( sig_oid->p, OID_PKCS1, 8 ) == 0 )
1024 {
1025 if( sig_oid->p[8] >= 2 && sig_oid->p[8] <= 5 )
1026 {
1027 *sig_alg = sig_oid->p[8];
1028 return( 0 );
1029 }
1030
1031 if ( sig_oid->p[8] >= 11 && sig_oid->p[8] <= 14 )
1032 {
1033 *sig_alg = sig_oid->p[8];
1034 return( 0 );
1035 }
1036
1037 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1038 }
1039
1040 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1041}
1042
Paul Bakkerd98030e2009-05-02 15:13:40 +00001043/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001044 * Parse one or more certificates and add them to the chained list
1045 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001046int x509parse_crt( x509_cert *chain, const unsigned char *buf, int buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001047{
1048 int ret, len;
Paul Bakkerff60ee62010-03-16 21:09:09 +00001049 const unsigned char *s1, *s2;
Paul Bakker5121ce52009-01-03 21:22:43 +00001050 unsigned char *p, *end;
1051 x509_cert *crt;
1052
1053 crt = chain;
1054
Paul Bakker320a4b52009-03-28 18:52:39 +00001055 /*
1056 * Check for valid input
1057 */
1058 if( crt == NULL || buf == NULL )
1059 return( 1 );
1060
Paul Bakkere9581d62009-03-28 20:29:25 +00001061 while( crt->version != 0 && crt->next != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00001062 crt = crt->next;
1063
1064 /*
Paul Bakker320a4b52009-03-28 18:52:39 +00001065 * Add new certificate on the end of the chain if needed.
1066 */
Paul Bakkere9581d62009-03-28 20:29:25 +00001067 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001068 {
1069 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1070
Paul Bakker7d06ad22009-05-02 15:53:56 +00001071 if( crt->next == NULL )
1072 {
Paul Bakker320a4b52009-03-28 18:52:39 +00001073 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001074 return( 1 );
1075 }
Paul Bakker320a4b52009-03-28 18:52:39 +00001076
Paul Bakker7d06ad22009-05-02 15:53:56 +00001077 crt = crt->next;
1078 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001079 }
1080
1081 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001082 * check if the certificate is encoded in base64
1083 */
1084 s1 = (unsigned char *) strstr( (char *) buf,
1085 "-----BEGIN CERTIFICATE-----" );
1086
1087 if( s1 != NULL )
1088 {
1089 s2 = (unsigned char *) strstr( (char *) buf,
1090 "-----END CERTIFICATE-----" );
1091
1092 if( s2 == NULL || s2 <= s1 )
Paul Bakker40e46942009-01-03 21:51:57 +00001093 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001094
1095 s1 += 27;
1096 if( *s1 == '\r' ) s1++;
1097 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001098 else return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001099
1100 /*
1101 * get the DER data length and decode the buffer
1102 */
1103 len = 0;
1104 ret = base64_decode( NULL, &len, s1, s2 - s1 );
1105
Paul Bakker40e46942009-01-03 21:51:57 +00001106 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
1107 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001108
1109 if( ( p = (unsigned char *) malloc( len ) ) == NULL )
1110 return( 1 );
1111
1112 if( ( ret = base64_decode( p, &len, s1, s2 - s1 ) ) != 0 )
1113 {
1114 free( p );
Paul Bakker40e46942009-01-03 21:51:57 +00001115 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001116 }
1117
1118 /*
1119 * update the buffer size and offset
1120 */
1121 s2 += 25;
1122 if( *s2 == '\r' ) s2++;
1123 if( *s2 == '\n' ) s2++;
1124 else
1125 {
1126 free( p );
Paul Bakker40e46942009-01-03 21:51:57 +00001127 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001128 }
1129
1130 buflen -= s2 - buf;
1131 buf = s2;
1132 }
1133 else
1134 {
1135 /*
1136 * nope, copy the raw DER data
1137 */
1138 p = (unsigned char *) malloc( len = buflen );
1139
1140 if( p == NULL )
1141 return( 1 );
1142
1143 memcpy( p, buf, buflen );
1144
1145 buflen = 0;
1146 }
1147
1148 crt->raw.p = p;
1149 crt->raw.len = len;
1150 end = p + len;
1151
1152 /*
1153 * Certificate ::= SEQUENCE {
1154 * tbsCertificate TBSCertificate,
1155 * signatureAlgorithm AlgorithmIdentifier,
1156 * signatureValue BIT STRING }
1157 */
1158 if( ( ret = asn1_get_tag( &p, end, &len,
1159 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1160 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001161 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001162 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001163 }
1164
1165 if( len != (int) ( end - p ) )
1166 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001167 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001168 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1169 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001170 }
1171
1172 /*
1173 * TBSCertificate ::= SEQUENCE {
1174 */
1175 crt->tbs.p = p;
1176
1177 if( ( ret = asn1_get_tag( &p, end, &len,
1178 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1179 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001180 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001181 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001182 }
1183
1184 end = p + len;
1185 crt->tbs.len = end - crt->tbs.p;
1186
1187 /*
1188 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1189 *
1190 * CertificateSerialNumber ::= INTEGER
1191 *
1192 * signature AlgorithmIdentifier
1193 */
1194 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1195 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1196 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
1197 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001198 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001199 return( ret );
1200 }
1201
1202 crt->version++;
1203
1204 if( crt->version > 3 )
1205 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001206 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001207 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001208 }
1209
Paul Bakker27d66162010-03-17 06:56:01 +00001210 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_alg ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001211 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001212 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001213 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001214 }
1215
1216 /*
1217 * issuer Name
1218 */
1219 crt->issuer_raw.p = p;
1220
1221 if( ( ret = asn1_get_tag( &p, end, &len,
1222 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1223 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001224 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001225 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001226 }
1227
1228 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1229 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001230 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001231 return( ret );
1232 }
1233
1234 crt->issuer_raw.len = p - crt->issuer_raw.p;
1235
1236 /*
1237 * Validity ::= SEQUENCE {
1238 * notBefore Time,
1239 * notAfter Time }
1240 *
1241 */
1242 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1243 &crt->valid_to ) ) != 0 )
1244 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001245 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001246 return( ret );
1247 }
1248
1249 /*
1250 * subject Name
1251 */
1252 crt->subject_raw.p = p;
1253
1254 if( ( ret = asn1_get_tag( &p, end, &len,
1255 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1256 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001257 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001258 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001259 }
1260
1261 if( ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
1262 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001263 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001264 return( ret );
1265 }
1266
1267 crt->subject_raw.len = p - crt->subject_raw.p;
1268
1269 /*
1270 * SubjectPublicKeyInfo ::= SEQUENCE
1271 * algorithm AlgorithmIdentifier,
1272 * subjectPublicKey BIT STRING }
1273 */
1274 if( ( ret = asn1_get_tag( &p, end, &len,
1275 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1276 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001277 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001278 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001279 }
1280
1281 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1282 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1283 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001284 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001285 return( ret );
1286 }
1287
1288 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1289 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001290 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001291 return( ret );
1292 }
1293
1294 crt->rsa.len = mpi_size( &crt->rsa.N );
1295
1296 /*
1297 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1298 * -- If present, version shall be v2 or v3
1299 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1300 * -- If present, version shall be v2 or v3
1301 * extensions [3] EXPLICIT Extensions OPTIONAL
1302 * -- If present, version shall be v3
1303 */
1304 if( crt->version == 2 || crt->version == 3 )
1305 {
1306 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1307 if( ret != 0 )
1308 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001309 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001310 return( ret );
1311 }
1312 }
1313
1314 if( crt->version == 2 || crt->version == 3 )
1315 {
1316 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1317 if( ret != 0 )
1318 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001319 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001320 return( ret );
1321 }
1322 }
1323
1324 if( crt->version == 3 )
1325 {
Paul Bakker74111d32011-01-15 16:57:55 +00001326 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001327 if( ret != 0 )
1328 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001329 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001330 return( ret );
1331 }
1332 }
1333
1334 if( p != end )
1335 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001336 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001337 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1338 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001339 }
1340
1341 end = crt->raw.p + crt->raw.len;
1342
1343 /*
1344 * signatureAlgorithm AlgorithmIdentifier,
1345 * signatureValue BIT STRING
1346 */
1347 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1348 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001349 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001350 return( ret );
1351 }
1352
Paul Bakker320a4b52009-03-28 18:52:39 +00001353 if( memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001354 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001355 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001356 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001357 }
1358
1359 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1360 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001361 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001362 return( ret );
1363 }
1364
1365 if( p != end )
1366 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001367 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001368 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1369 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001370 }
1371
Paul Bakker5121ce52009-01-03 21:22:43 +00001372 if( buflen > 0 )
Paul Bakker320a4b52009-03-28 18:52:39 +00001373 {
1374 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1375
Paul Bakker7d06ad22009-05-02 15:53:56 +00001376 if( crt->next == NULL )
1377 {
Paul Bakker320a4b52009-03-28 18:52:39 +00001378 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001379 return( 1 );
1380 }
Paul Bakker320a4b52009-03-28 18:52:39 +00001381
Paul Bakker7d06ad22009-05-02 15:53:56 +00001382 crt = crt->next;
1383 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001384
Paul Bakker5121ce52009-01-03 21:22:43 +00001385 return( x509parse_crt( crt, buf, buflen ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001386 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001387
1388 return( 0 );
1389}
1390
1391/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001392 * Parse one or more CRLs and add them to the chained list
1393 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001394int x509parse_crl( x509_crl *chain, const unsigned char *buf, int buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001395{
1396 int ret, len;
1397 unsigned char *s1, *s2;
1398 unsigned char *p, *end;
1399 x509_crl *crl;
1400
1401 crl = chain;
1402
1403 /*
1404 * Check for valid input
1405 */
1406 if( crl == NULL || buf == NULL )
1407 return( 1 );
1408
1409 while( crl->version != 0 && crl->next != NULL )
1410 crl = crl->next;
1411
1412 /*
1413 * Add new CRL on the end of the chain if needed.
1414 */
1415 if ( crl->version != 0 && crl->next == NULL)
1416 {
1417 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1418
Paul Bakker7d06ad22009-05-02 15:53:56 +00001419 if( crl->next == NULL )
1420 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001421 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001422 return( 1 );
1423 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001424
Paul Bakker7d06ad22009-05-02 15:53:56 +00001425 crl = crl->next;
1426 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001427 }
1428
1429 /*
1430 * check if the CRL is encoded in base64
1431 */
1432 s1 = (unsigned char *) strstr( (char *) buf,
1433 "-----BEGIN X509 CRL-----" );
1434
1435 if( s1 != NULL )
1436 {
1437 s2 = (unsigned char *) strstr( (char *) buf,
1438 "-----END X509 CRL-----" );
1439
1440 if( s2 == NULL || s2 <= s1 )
1441 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1442
1443 s1 += 24;
1444 if( *s1 == '\r' ) s1++;
1445 if( *s1 == '\n' ) s1++;
1446 else return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1447
1448 /*
1449 * get the DER data length and decode the buffer
1450 */
1451 len = 0;
1452 ret = base64_decode( NULL, &len, s1, s2 - s1 );
1453
1454 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
1455 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
1456
1457 if( ( p = (unsigned char *) malloc( len ) ) == NULL )
1458 return( 1 );
1459
1460 if( ( ret = base64_decode( p, &len, s1, s2 - s1 ) ) != 0 )
1461 {
1462 free( p );
1463 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
1464 }
1465
1466 /*
1467 * update the buffer size and offset
1468 */
1469 s2 += 22;
1470 if( *s2 == '\r' ) s2++;
1471 if( *s2 == '\n' ) s2++;
1472 else
1473 {
1474 free( p );
1475 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1476 }
1477
1478 buflen -= s2 - buf;
1479 buf = s2;
1480 }
1481 else
1482 {
1483 /*
1484 * nope, copy the raw DER data
1485 */
1486 p = (unsigned char *) malloc( len = buflen );
1487
1488 if( p == NULL )
1489 return( 1 );
1490
1491 memcpy( p, buf, buflen );
1492
1493 buflen = 0;
1494 }
1495
1496 crl->raw.p = p;
1497 crl->raw.len = len;
1498 end = p + len;
1499
1500 /*
1501 * CertificateList ::= SEQUENCE {
1502 * tbsCertList TBSCertList,
1503 * signatureAlgorithm AlgorithmIdentifier,
1504 * signatureValue BIT STRING }
1505 */
1506 if( ( ret = asn1_get_tag( &p, end, &len,
1507 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1508 {
1509 x509_crl_free( crl );
1510 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1511 }
1512
1513 if( len != (int) ( end - p ) )
1514 {
1515 x509_crl_free( crl );
1516 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1517 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1518 }
1519
1520 /*
1521 * TBSCertList ::= SEQUENCE {
1522 */
1523 crl->tbs.p = p;
1524
1525 if( ( ret = asn1_get_tag( &p, end, &len,
1526 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1527 {
1528 x509_crl_free( crl );
1529 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
1530 }
1531
1532 end = p + len;
1533 crl->tbs.len = end - crl->tbs.p;
1534
1535 /*
1536 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1537 * -- if present, MUST be v2
1538 *
1539 * signature AlgorithmIdentifier
1540 */
1541 if( ( ret = x509_get_version( &p, end, &crl->version ) ) != 0 ||
1542 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1543 {
1544 x509_crl_free( crl );
1545 return( ret );
1546 }
1547
1548 crl->version++;
1549
1550 if( crl->version > 2 )
1551 {
1552 x509_crl_free( crl );
1553 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1554 }
1555
Paul Bakker27d66162010-03-17 06:56:01 +00001556 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_alg ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001557 {
1558 x509_crl_free( crl );
1559 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1560 }
1561
1562 /*
1563 * issuer Name
1564 */
1565 crl->issuer_raw.p = p;
1566
1567 if( ( ret = asn1_get_tag( &p, end, &len,
1568 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1569 {
1570 x509_crl_free( crl );
1571 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
1572 }
1573
1574 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1575 {
1576 x509_crl_free( crl );
1577 return( ret );
1578 }
1579
1580 crl->issuer_raw.len = p - crl->issuer_raw.p;
1581
1582 /*
1583 * thisUpdate Time
1584 * nextUpdate Time OPTIONAL
1585 */
Paul Bakker91200182010-02-18 21:26:15 +00001586 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001587 {
1588 x509_crl_free( crl );
1589 return( ret );
1590 }
1591
Paul Bakker91200182010-02-18 21:26:15 +00001592 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001593 {
Paul Bakker635f4b42009-07-20 20:34:41 +00001594 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE |
Paul Bakker9be19372009-07-27 20:21:53 +00001595 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
1596 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE |
1597 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001598 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001599 x509_crl_free( crl );
1600 return( ret );
1601 }
1602 }
1603
1604 /*
1605 * revokedCertificates SEQUENCE OF SEQUENCE {
1606 * userCertificate CertificateSerialNumber,
1607 * revocationDate Time,
1608 * crlEntryExtensions Extensions OPTIONAL
1609 * -- if present, MUST be v2
1610 * } OPTIONAL
1611 */
1612 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1613 {
1614 x509_crl_free( crl );
1615 return( ret );
1616 }
1617
1618 /*
1619 * crlExtensions EXPLICIT Extensions OPTIONAL
1620 * -- if present, MUST be v2
1621 */
1622 if( crl->version == 2 )
1623 {
1624 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1625
1626 if( ret != 0 )
1627 {
1628 x509_crl_free( crl );
1629 return( ret );
1630 }
1631 }
1632
1633 if( p != end )
1634 {
1635 x509_crl_free( crl );
1636 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1637 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1638 }
1639
1640 end = crl->raw.p + crl->raw.len;
1641
1642 /*
1643 * signatureAlgorithm AlgorithmIdentifier,
1644 * signatureValue BIT STRING
1645 */
1646 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1647 {
1648 x509_crl_free( crl );
1649 return( ret );
1650 }
1651
1652 if( memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
1653 {
1654 x509_crl_free( crl );
1655 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1656 }
1657
1658 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1659 {
1660 x509_crl_free( crl );
1661 return( ret );
1662 }
1663
1664 if( p != end )
1665 {
1666 x509_crl_free( crl );
1667 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1668 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1669 }
1670
1671 if( buflen > 0 )
1672 {
1673 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1674
Paul Bakker7d06ad22009-05-02 15:53:56 +00001675 if( crl->next == NULL )
1676 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001677 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001678 return( 1 );
1679 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001680
Paul Bakker7d06ad22009-05-02 15:53:56 +00001681 crl = crl->next;
1682 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001683
1684 return( x509parse_crl( crl, buf, buflen ) );
1685 }
1686
1687 return( 0 );
1688}
1689
1690/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001691 * Load all data from a file into a given buffer.
1692 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001693int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001694{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001695 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001696
Paul Bakkerd98030e2009-05-02 15:13:40 +00001697 if( ( f = fopen( path, "rb" ) ) == NULL )
1698 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001699
Paul Bakkerd98030e2009-05-02 15:13:40 +00001700 fseek( f, 0, SEEK_END );
1701 *n = (size_t) ftell( f );
1702 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001703
Paul Bakkerd98030e2009-05-02 15:13:40 +00001704 if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
1705 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001706
Paul Bakkerd98030e2009-05-02 15:13:40 +00001707 if( fread( *buf, 1, *n, f ) != *n )
1708 {
1709 fclose( f );
1710 free( *buf );
1711 return( 1 );
1712 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001713
Paul Bakkerd98030e2009-05-02 15:13:40 +00001714 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001715
Paul Bakkerd98030e2009-05-02 15:13:40 +00001716 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001717
Paul Bakkerd98030e2009-05-02 15:13:40 +00001718 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001719}
1720
1721/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001722 * Load one or more certificates and add them to the chained list
1723 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001724int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001725{
1726 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001727 size_t n;
1728 unsigned char *buf;
1729
Paul Bakker2b245eb2009-04-19 18:44:26 +00001730 if ( load_file( path, &buf, &n ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001731 return( 1 );
1732
Paul Bakker5121ce52009-01-03 21:22:43 +00001733 ret = x509parse_crt( chain, buf, (int) n );
1734
1735 memset( buf, 0, n + 1 );
1736 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001737
1738 return( ret );
1739}
1740
Paul Bakkerd98030e2009-05-02 15:13:40 +00001741/*
1742 * Load one or more CRLs and add them to the chained list
1743 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001744int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001745{
1746 int ret;
1747 size_t n;
1748 unsigned char *buf;
1749
1750 if ( load_file( path, &buf, &n ) )
1751 return( 1 );
1752
1753 ret = x509parse_crl( chain, buf, (int) n );
1754
1755 memset( buf, 0, n + 1 );
1756 free( buf );
1757
1758 return( ret );
1759}
1760
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001761#if defined(POLARSSL_DES_C) && defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001762/*
1763 * Read a 16-byte hex string and convert it to binary
1764 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001765static int x509_get_iv( const unsigned char *s, unsigned char iv[8] )
Paul Bakker5121ce52009-01-03 21:22:43 +00001766{
1767 int i, j, k;
1768
1769 memset( iv, 0, 8 );
1770
1771 for( i = 0; i < 16; i++, s++ )
1772 {
1773 if( *s >= '0' && *s <= '9' ) j = *s - '0'; else
1774 if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else
1775 if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else
Paul Bakker40e46942009-01-03 21:51:57 +00001776 return( POLARSSL_ERR_X509_KEY_INVALID_ENC_IV );
Paul Bakker5121ce52009-01-03 21:22:43 +00001777
1778 k = ( ( i & 1 ) != 0 ) ? j : j << 4;
1779
1780 iv[i >> 1] = (unsigned char)( iv[i >> 1] | k );
1781 }
1782
1783 return( 0 );
1784}
1785
1786/*
1787 * Decrypt with 3DES-CBC, using PBKDF1 for key derivation
1788 */
1789static void x509_des3_decrypt( unsigned char des3_iv[8],
1790 unsigned char *buf, int buflen,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001791 const unsigned char *pwd, int pwdlen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001792{
1793 md5_context md5_ctx;
1794 des3_context des3_ctx;
1795 unsigned char md5sum[16];
1796 unsigned char des3_key[24];
1797
1798 /*
1799 * 3DES key[ 0..15] = MD5(pwd || IV)
1800 * key[16..23] = MD5(pwd || IV || 3DES key[ 0..15])
1801 */
1802 md5_starts( &md5_ctx );
1803 md5_update( &md5_ctx, pwd, pwdlen );
1804 md5_update( &md5_ctx, des3_iv, 8 );
1805 md5_finish( &md5_ctx, md5sum );
1806 memcpy( des3_key, md5sum, 16 );
1807
1808 md5_starts( &md5_ctx );
1809 md5_update( &md5_ctx, md5sum, 16 );
1810 md5_update( &md5_ctx, pwd, pwdlen );
1811 md5_update( &md5_ctx, des3_iv, 8 );
1812 md5_finish( &md5_ctx, md5sum );
1813 memcpy( des3_key + 16, md5sum, 8 );
1814
1815 des3_set3key_dec( &des3_ctx, des3_key );
1816 des3_crypt_cbc( &des3_ctx, DES_DECRYPT, buflen,
1817 des3_iv, buf, buf );
1818
1819 memset( &md5_ctx, 0, sizeof( md5_ctx ) );
1820 memset( &des3_ctx, 0, sizeof( des3_ctx ) );
1821 memset( md5sum, 0, 16 );
1822 memset( des3_key, 0, 24 );
1823}
1824#endif
1825
1826/*
1827 * Parse a private RSA key
1828 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001829int x509parse_key( rsa_context *rsa, const unsigned char *key, int keylen,
1830 const unsigned char *pwd, int pwdlen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001831{
1832 int ret, len, enc;
Paul Bakkerff60ee62010-03-16 21:09:09 +00001833 unsigned char *buf, *s1, *s2;
Paul Bakker5121ce52009-01-03 21:22:43 +00001834 unsigned char *p, *end;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001835#if defined(POLARSSL_DES_C) && defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001836 unsigned char des3_iv[8];
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001837#else
1838 ((void) pwd);
1839 ((void) pwdlen);
1840#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001841
Paul Bakkerff60ee62010-03-16 21:09:09 +00001842 s1 = (unsigned char *) strstr( (char *) key,
Paul Bakker5121ce52009-01-03 21:22:43 +00001843 "-----BEGIN RSA PRIVATE KEY-----" );
1844
1845 if( s1 != NULL )
1846 {
Paul Bakkerff60ee62010-03-16 21:09:09 +00001847 s2 = (unsigned char *) strstr( (char *) key,
Paul Bakker5121ce52009-01-03 21:22:43 +00001848 "-----END RSA PRIVATE KEY-----" );
1849
1850 if( s2 == NULL || s2 <= s1 )
Paul Bakker40e46942009-01-03 21:51:57 +00001851 return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001852
1853 s1 += 31;
1854 if( *s1 == '\r' ) s1++;
1855 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001856 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001857
1858 enc = 0;
1859
1860 if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
1861 {
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001862#if defined(POLARSSL_DES_C) && defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001863 enc++;
1864
1865 s1 += 22;
1866 if( *s1 == '\r' ) s1++;
1867 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001868 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001869
1870 if( memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001871 return( POLARSSL_ERR_X509_KEY_UNKNOWN_ENC_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +00001872
1873 s1 += 23;
1874 if( x509_get_iv( s1, des3_iv ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001875 return( POLARSSL_ERR_X509_KEY_INVALID_ENC_IV );
Paul Bakker5121ce52009-01-03 21:22:43 +00001876
1877 s1 += 16;
1878 if( *s1 == '\r' ) s1++;
1879 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001880 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001881#else
Paul Bakker40e46942009-01-03 21:51:57 +00001882 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001883#endif
1884 }
1885
1886 len = 0;
1887 ret = base64_decode( NULL, &len, s1, s2 - s1 );
1888
Paul Bakker40e46942009-01-03 21:51:57 +00001889 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
1890 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001891
1892 if( ( buf = (unsigned char *) malloc( len ) ) == NULL )
1893 return( 1 );
1894
1895 if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
1896 {
1897 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001898 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001899 }
1900
Paul Bakkerff60ee62010-03-16 21:09:09 +00001901 keylen = len;
Paul Bakker5121ce52009-01-03 21:22:43 +00001902
1903 if( enc != 0 )
1904 {
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001905#if defined(POLARSSL_DES_C) && defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001906 if( pwd == NULL )
1907 {
1908 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001909 return( POLARSSL_ERR_X509_KEY_PASSWORD_REQUIRED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001910 }
1911
Paul Bakkerff60ee62010-03-16 21:09:09 +00001912 x509_des3_decrypt( des3_iv, buf, keylen, pwd, pwdlen );
Paul Bakker5121ce52009-01-03 21:22:43 +00001913
1914 if( buf[0] != 0x30 || buf[1] != 0x82 ||
1915 buf[4] != 0x02 || buf[5] != 0x01 )
1916 {
1917 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001918 return( POLARSSL_ERR_X509_KEY_PASSWORD_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001919 }
1920#else
Paul Bakker40e46942009-01-03 21:51:57 +00001921 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001922#endif
1923 }
1924 }
Paul Bakkerff60ee62010-03-16 21:09:09 +00001925 else
1926 {
1927 buf = NULL;
1928 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001929
1930 memset( rsa, 0, sizeof( rsa_context ) );
1931
Paul Bakkerff60ee62010-03-16 21:09:09 +00001932 p = ( s1 != NULL ) ? buf : (unsigned char *) key;
1933 end = p + keylen;
Paul Bakker5121ce52009-01-03 21:22:43 +00001934
1935 /*
1936 * RSAPrivateKey ::= SEQUENCE {
1937 * version Version,
1938 * modulus INTEGER, -- n
1939 * publicExponent INTEGER, -- e
1940 * privateExponent INTEGER, -- d
1941 * prime1 INTEGER, -- p
1942 * prime2 INTEGER, -- q
1943 * exponent1 INTEGER, -- d mod (p-1)
1944 * exponent2 INTEGER, -- d mod (q-1)
1945 * coefficient INTEGER, -- (inverse of q) mod p
1946 * otherPrimeInfos OtherPrimeInfos OPTIONAL
1947 * }
1948 */
1949 if( ( ret = asn1_get_tag( &p, end, &len,
1950 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1951 {
1952 if( s1 != NULL )
1953 free( buf );
1954
1955 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001956 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001957 }
1958
1959 end = p + len;
1960
1961 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
1962 {
1963 if( s1 != NULL )
1964 free( buf );
1965
1966 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001967 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001968 }
1969
1970 if( rsa->ver != 0 )
1971 {
1972 if( s1 != NULL )
1973 free( buf );
1974
1975 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001976 return( ret | POLARSSL_ERR_X509_KEY_INVALID_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001977 }
1978
1979 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
1980 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
1981 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
1982 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
1983 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
1984 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
1985 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
1986 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
1987 {
1988 if( s1 != NULL )
1989 free( buf );
1990
1991 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001992 return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001993 }
1994
1995 rsa->len = mpi_size( &rsa->N );
1996
1997 if( p != end )
1998 {
1999 if( s1 != NULL )
2000 free( buf );
2001
2002 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00002003 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT |
2004 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002005 }
2006
2007 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2008 {
2009 if( s1 != NULL )
2010 free( buf );
2011
2012 rsa_free( rsa );
2013 return( ret );
2014 }
2015
2016 if( s1 != NULL )
2017 free( buf );
2018
2019 return( 0 );
2020}
2021
2022/*
2023 * Load and parse a private RSA key
2024 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002025int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
Paul Bakker5121ce52009-01-03 21:22:43 +00002026{
2027 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002028 size_t n;
2029 unsigned char *buf;
2030
Paul Bakker2b245eb2009-04-19 18:44:26 +00002031 if ( load_file( path, &buf, &n ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00002032 return( 1 );
2033
Paul Bakker5121ce52009-01-03 21:22:43 +00002034 if( pwd == NULL )
2035 ret = x509parse_key( rsa, buf, (int) n, NULL, 0 );
2036 else
2037 ret = x509parse_key( rsa, buf, (int) n,
2038 (unsigned char *) pwd, strlen( pwd ) );
2039
2040 memset( buf, 0, n + 1 );
2041 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00002042
2043 return( ret );
2044}
2045
Paul Bakker1b57b062011-01-06 15:48:19 +00002046/*
2047 * Parse DHM parameters
2048 */
2049int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, int dhminlen )
2050{
2051 int ret, len;
2052 unsigned char *buf, *s1, *s2;
2053 unsigned char *p, *end;
2054
2055 s1 = (unsigned char *) strstr( (char *) dhmin,
2056 "-----BEGIN DH PARAMETERS-----" );
2057
2058 if( s1 != NULL )
2059 {
2060 s2 = (unsigned char *) strstr( (char *) dhmin,
2061 "-----END DH PARAMETERS-----" );
2062
2063 if( s2 == NULL || s2 <= s1 )
2064 return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
2065
2066 s1 += 29;
2067 if( *s1 == '\r' ) s1++;
2068 if( *s1 == '\n' ) s1++;
2069 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
2070
2071 len = 0;
2072 ret = base64_decode( NULL, &len, s1, s2 - s1 );
2073
2074 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
2075 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
2076
2077 if( ( buf = (unsigned char *) malloc( len ) ) == NULL )
2078 return( 1 );
2079
2080 if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
2081 {
2082 free( buf );
2083 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
2084 }
2085
2086 dhminlen = len;
2087 }
2088 else
2089 {
2090 buf = NULL;
2091 }
2092
2093 memset( dhm, 0, sizeof( dhm_context ) );
2094
2095 p = ( s1 != NULL ) ? buf : (unsigned char *) dhmin;
2096 end = p + dhminlen;
2097
2098 /*
2099 * DHParams ::= SEQUENCE {
2100 * prime INTEGER, -- P
2101 * generator INTEGER, -- g
2102 * }
2103 */
2104 if( ( ret = asn1_get_tag( &p, end, &len,
2105 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2106 {
2107 if( s1 != NULL )
2108 free( buf );
2109
2110 dhm_free( dhm );
2111 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
2112 }
2113
2114 end = p + len;
2115
2116 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
2117 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
2118 {
2119 if( s1 != NULL )
2120 free( buf );
2121
2122 dhm_free( dhm );
2123 return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
2124 }
2125
2126 if( p != end )
2127 {
2128 if( s1 != NULL )
2129 free( buf );
2130
2131 dhm_free( dhm );
2132 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT |
2133 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
2134 }
2135
2136 if( s1 != NULL )
2137 free( buf );
2138
2139 return( 0 );
2140}
2141
2142/*
2143 * Load and parse a private RSA key
2144 */
2145int x509parse_dhmfile( dhm_context *dhm, const char *path )
2146{
2147 int ret;
2148 size_t n;
2149 unsigned char *buf;
2150
2151 if ( load_file( path, &buf, &n ) )
2152 return( 1 );
2153
2154 ret = x509parse_dhm( dhm, buf, (int) n);
2155
2156 memset( buf, 0, n + 1 );
2157 free( buf );
2158
2159 return( ret );
2160}
2161
Paul Bakker5121ce52009-01-03 21:22:43 +00002162#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002163#include <stdarg.h>
2164
2165#if !defined vsnprintf
2166#define vsnprintf _vsnprintf
2167#endif // vsnprintf
2168
2169/*
2170 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2171 * Result value is not size of buffer needed, but -1 if no fit is possible.
2172 *
2173 * This fuction tries to 'fix' this by at least suggesting enlarging the
2174 * size by 20.
2175 */
2176int compat_snprintf(char *str, size_t size, const char *format, ...)
2177{
2178 va_list ap;
2179 int res = -1;
2180
2181 va_start( ap, format );
2182
2183 res = vsnprintf( str, size, format, ap );
2184
2185 va_end( ap );
2186
2187 // No quick fix possible
2188 if ( res < 0 )
2189 return( size + 20 );
2190
2191 return res;
2192}
2193
2194#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002195#endif
2196
Paul Bakkerd98030e2009-05-02 15:13:40 +00002197#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2198
2199#define SAFE_SNPRINTF() \
2200{ \
2201 if( ret == -1 ) \
2202 return( -1 ); \
2203 \
2204 if ( ret > n ) { \
2205 p[n - 1] = '\0'; \
2206 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2207 } \
2208 \
2209 n -= ret; \
2210 p += ret; \
2211}
2212
Paul Bakker5121ce52009-01-03 21:22:43 +00002213/*
2214 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002215 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002216 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002217int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002218{
Paul Bakkerd98030e2009-05-02 15:13:40 +00002219 int i, ret, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002220 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002221 const x509_name *name;
Paul Bakker5121ce52009-01-03 21:22:43 +00002222 char s[128], *p;
2223
2224 memset( s, 0, sizeof( s ) );
2225
2226 name = dn;
2227 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002228 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002229
2230 while( name != NULL )
2231 {
Paul Bakker74111d32011-01-15 16:57:55 +00002232 if( name != dn )
2233 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002234 ret = snprintf( p, n, ", " );
2235 SAFE_SNPRINTF();
2236 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002237
2238 if( memcmp( name->oid.p, OID_X520, 2 ) == 0 )
2239 {
2240 switch( name->oid.p[2] )
2241 {
2242 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002243 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002244
2245 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002246 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002247
2248 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002249 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002250
2251 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002252 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002253
2254 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002255 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002256
2257 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002258 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002259
2260 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002261 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002262 name->oid.p[2] );
2263 break;
2264 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002265 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002266 }
2267 else if( memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
2268 {
2269 switch( name->oid.p[8] )
2270 {
2271 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002272 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002273
2274 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002275 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002276 name->oid.p[8] );
2277 break;
2278 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002279 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002280 }
2281 else
Paul Bakker74111d32011-01-15 16:57:55 +00002282 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002283 ret = snprintf( p, n, "\?\?=" );
Paul Bakker74111d32011-01-15 16:57:55 +00002284 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002285 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002286
2287 for( i = 0; i < name->val.len; i++ )
2288 {
2289 if( i >= (int) sizeof( s ) - 1 )
2290 break;
2291
2292 c = name->val.p[i];
2293 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2294 s[i] = '?';
2295 else s[i] = c;
2296 }
2297 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002298 ret = snprintf( p, n, "%s", s );
2299 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002300 name = name->next;
2301 }
2302
Paul Bakkerd98030e2009-05-02 15:13:40 +00002303 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002304}
2305
2306/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002307 * Store the serial in printable form into buf; no more
2308 * than size characters will be written
2309 */
2310int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2311{
2312 int i, ret, nr, n;
2313 char *p;
2314
2315 p = buf;
2316 n = size;
2317
2318 nr = ( serial->len <= 32 )
2319 ? serial->len : 32;
2320
2321 for( i = 0; i < nr; i++ )
2322 {
2323 ret = snprintf( p, n, "%02X%s",
2324 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2325 SAFE_SNPRINTF();
2326 }
2327
2328 return( size - n );
2329}
2330
2331/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002332 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002333 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002334int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2335 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002336{
Paul Bakkerdd476992011-01-16 21:34:59 +00002337 int n, ret;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002338 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00002339
2340 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002341 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002342
Paul Bakkerd98030e2009-05-02 15:13:40 +00002343 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002344 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002345 SAFE_SNPRINTF();
2346 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002347 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002348 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002349
Paul Bakkerdd476992011-01-16 21:34:59 +00002350 ret = x509parse_serial_gets( p, n, &crt->serial);
2351 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002352
Paul Bakkerd98030e2009-05-02 15:13:40 +00002353 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2354 SAFE_SNPRINTF();
2355 ret = x509parse_dn_gets( p, n, &crt->issuer );
2356 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002357
Paul Bakkerd98030e2009-05-02 15:13:40 +00002358 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2359 SAFE_SNPRINTF();
2360 ret = x509parse_dn_gets( p, n, &crt->subject );
2361 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002362
Paul Bakkerd98030e2009-05-02 15:13:40 +00002363 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002364 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2365 crt->valid_from.year, crt->valid_from.mon,
2366 crt->valid_from.day, crt->valid_from.hour,
2367 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002368 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002369
Paul Bakkerd98030e2009-05-02 15:13:40 +00002370 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002371 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2372 crt->valid_to.year, crt->valid_to.mon,
2373 crt->valid_to.day, crt->valid_to.hour,
2374 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002375 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002376
Paul Bakkerd98030e2009-05-02 15:13:40 +00002377 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2378 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002379
Paul Bakker27d66162010-03-17 06:56:01 +00002380 switch( crt->sig_alg )
Paul Bakker5121ce52009-01-03 21:22:43 +00002381 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002382 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2383 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2384 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2385 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2386 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2387 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2388 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2389 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2390 default: ret = snprintf( p, n, "???" ); break;
2391 }
2392 SAFE_SNPRINTF();
2393
2394 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
2395 crt->rsa.N.n * (int) sizeof( unsigned long ) * 8 );
2396 SAFE_SNPRINTF();
2397
2398 return( size - n );
2399}
2400
Paul Bakker74111d32011-01-15 16:57:55 +00002401/* Compare a given OID string with an OID x509_buf * */
2402#define OID_CMP(oid_str, oid_buf) \
2403 ( ( OID_SIZE(oid_str) == (oid_buf)->len ) && \
2404 memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0)
2405
2406/*
2407 * Return an informational string describing the given OID
2408 */
2409const char *x509_oid_get_description( x509_buf *oid )
2410{
2411 if ( oid == NULL )
2412 return ( NULL );
2413
2414 else if( OID_CMP( OID_SERVER_AUTH, oid ) )
2415 return( STRING_SERVER_AUTH );
2416
2417 else if( OID_CMP( OID_CLIENT_AUTH, oid ) )
2418 return( STRING_CLIENT_AUTH );
2419
2420 else if( OID_CMP( OID_CODE_SIGNING, oid ) )
2421 return( STRING_CODE_SIGNING );
2422
2423 else if( OID_CMP( OID_EMAIL_PROTECTION, oid ) )
2424 return( STRING_EMAIL_PROTECTION );
2425
2426 else if( OID_CMP( OID_TIME_STAMPING, oid ) )
2427 return( STRING_TIME_STAMPING );
2428
2429 else if( OID_CMP( OID_OCSP_SIGNING, oid ) )
2430 return( STRING_OCSP_SIGNING );
2431
2432 return( NULL );
2433}
2434
2435/* Return the x.y.z.... style numeric string for the given OID */
2436int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2437{
2438 int ret, n, i;
2439 unsigned int value;
2440 char *p;
2441
2442 p = buf;
2443 n = size;
2444
2445 /* First byte contains first two dots */
2446 if( oid->len > 0 )
2447 {
2448 ret = snprintf( p, n, "%d.%d", oid->p[0]/40, oid->p[0]%40 );
2449 SAFE_SNPRINTF();
2450 }
2451
2452 /* TODO: value can overflow in value. */
2453 value = 0;
2454 for( i=1; i < oid->len; i++ )
2455 {
2456 value <<= 7;
2457 value += oid->p[i] & 0x7F;
2458
2459 if( !( oid->p[i] & 0x80 ) )
2460 {
2461 /* Last byte */
2462 ret = snprintf( p, n, ".%d", value );
2463 SAFE_SNPRINTF();
2464 value = 0;
2465 }
2466 }
2467
2468 return( size - n );
2469}
2470
Paul Bakkerd98030e2009-05-02 15:13:40 +00002471/*
2472 * Return an informational string about the CRL.
2473 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002474int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2475 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002476{
2477 int i, n, nr, ret;
2478 char *p;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002479 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002480
2481 p = buf;
2482 n = size;
2483
2484 ret = snprintf( p, n, "%sCRL version : %d",
2485 prefix, crl->version );
2486 SAFE_SNPRINTF();
2487
2488 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2489 SAFE_SNPRINTF();
2490 ret = x509parse_dn_gets( p, n, &crl->issuer );
2491 SAFE_SNPRINTF();
2492
2493 ret = snprintf( p, n, "\n%sthis update : " \
2494 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2495 crl->this_update.year, crl->this_update.mon,
2496 crl->this_update.day, crl->this_update.hour,
2497 crl->this_update.min, crl->this_update.sec );
2498 SAFE_SNPRINTF();
2499
2500 ret = snprintf( p, n, "\n%snext update : " \
2501 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2502 crl->next_update.year, crl->next_update.mon,
2503 crl->next_update.day, crl->next_update.hour,
2504 crl->next_update.min, crl->next_update.sec );
2505 SAFE_SNPRINTF();
2506
2507 entry = &crl->entry;
2508
2509 ret = snprintf( p, n, "\n%sRevoked certificates:",
2510 prefix );
2511 SAFE_SNPRINTF();
2512
Paul Bakker9be19372009-07-27 20:21:53 +00002513 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002514 {
2515 ret = snprintf( p, n, "\n%sserial number: ",
2516 prefix );
2517 SAFE_SNPRINTF();
2518
2519 nr = ( entry->serial.len <= 32 )
2520 ? entry->serial.len : 32;
2521
Paul Bakker74111d32011-01-15 16:57:55 +00002522 for( i = 0; i < nr; i++ )
2523 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002524 ret = snprintf( p, n, "%02X%s",
2525 entry->serial.p[i], ( i < nr - 1 ) ? ":" : "" );
2526 SAFE_SNPRINTF();
2527 }
2528
2529 ret = snprintf( p, n, " revocation date: " \
2530 "%04d-%02d-%02d %02d:%02d:%02d",
2531 entry->revocation_date.year, entry->revocation_date.mon,
2532 entry->revocation_date.day, entry->revocation_date.hour,
2533 entry->revocation_date.min, entry->revocation_date.sec );
2534 SAFE_SNPRINTF();
2535
2536 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002537 }
2538
Paul Bakkerd98030e2009-05-02 15:13:40 +00002539 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2540 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002541
Paul Bakker27d66162010-03-17 06:56:01 +00002542 switch( crl->sig_alg )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002543 {
2544 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2545 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2546 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2547 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2548 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2549 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2550 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2551 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2552 default: ret = snprintf( p, n, "???" ); break;
2553 }
2554 SAFE_SNPRINTF();
2555
Paul Bakker1e27bb22009-07-19 20:25:25 +00002556 ret = snprintf( p, n, "\n" );
2557 SAFE_SNPRINTF();
2558
Paul Bakkerd98030e2009-05-02 15:13:40 +00002559 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002560}
2561
2562/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00002563 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00002564 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002565int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00002566{
2567 struct tm *lt;
2568 time_t tt;
2569
2570 tt = time( NULL );
2571 lt = localtime( &tt );
2572
Paul Bakker40ea7de2009-05-03 10:18:48 +00002573 if( lt->tm_year > to->year - 1900 )
2574 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002575
Paul Bakker40ea7de2009-05-03 10:18:48 +00002576 if( lt->tm_year == to->year - 1900 &&
2577 lt->tm_mon > to->mon - 1 )
2578 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002579
Paul Bakker40ea7de2009-05-03 10:18:48 +00002580 if( lt->tm_year == to->year - 1900 &&
2581 lt->tm_mon == to->mon - 1 &&
2582 lt->tm_mday > to->day )
2583 return( 1 );
2584
Paul Bakkerb6194992011-01-16 21:40:22 +00002585 if( lt->tm_year == to->year - 1900 &&
2586 lt->tm_mon == to->mon - 1 &&
2587 lt->tm_mday == to->day &&
2588 lt->tm_hour > to->hour - 1)
2589 return( 1 );
2590
2591 if( lt->tm_year == to->year - 1900 &&
2592 lt->tm_mon == to->mon - 1 &&
2593 lt->tm_mday == to->day &&
2594 lt->tm_hour == to->hour - 1 &&
2595 lt->tm_min > to->min - 1 )
2596 return( 1 );
2597
2598 if( lt->tm_year == to->year - 1900 &&
2599 lt->tm_mon == to->mon - 1 &&
2600 lt->tm_mday == to->day &&
2601 lt->tm_hour == to->hour - 1 &&
2602 lt->tm_min == to->min - 1 &&
2603 lt->tm_sec > to->sec - 1 )
2604 return( 1 );
2605
Paul Bakker40ea7de2009-05-03 10:18:48 +00002606 return( 0 );
2607}
2608
2609/*
2610 * Return 1 if the certificate is revoked, or 0 otherwise.
2611 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002612int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002613{
Paul Bakkerff60ee62010-03-16 21:09:09 +00002614 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00002615
2616 while( cur != NULL && cur->serial.len != 0 )
2617 {
Paul Bakkera056efc2011-01-16 21:38:35 +00002618 if( crt->serial.len == cur->serial.len &&
2619 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002620 {
2621 if( x509parse_time_expired( &cur->revocation_date ) )
2622 return( 1 );
2623 }
2624
2625 cur = cur->next;
2626 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002627
2628 return( 0 );
2629}
2630
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002631/*
2632 * Wrapper for x509 hashes.
2633 *
Paul Bakker0f5f72e2011-01-18 14:58:55 +00002634 * \param out Buffer to receive the hash (Should be at least 64 bytes)
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002635 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002636static void x509_hash( const unsigned char *in, int len, int alg,
Paul Bakker5121ce52009-01-03 21:22:43 +00002637 unsigned char *out )
2638{
2639 switch( alg )
2640 {
Paul Bakker40e46942009-01-03 21:51:57 +00002641#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002642 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002643#endif
Paul Bakker40e46942009-01-03 21:51:57 +00002644#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002645 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002646#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002647#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002648 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002649#endif
2650#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002651 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002652#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00002653#if defined(POLARSSL_SHA2_C)
2654 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
2655 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
2656#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00002657#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002658 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
2659 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
2660#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002661 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002662 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002663 break;
2664 }
2665}
2666
2667/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00002668 * Check that the given certificate is valid accoring to the CRL.
2669 */
2670static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
2671 x509_crl *crl_list)
2672{
2673 int flags = 0;
2674 int hash_id;
2675 unsigned char hash[64];
2676
2677 /*
2678 * TODO: What happens if no CRL is present?
2679 * Suggestion: Revocation state should be unknown if no CRL is present.
2680 * For backwards compatibility this is not yet implemented.
2681 */
2682
2683 while( ca != NULL && crl_list != NULL && crl_list->version != 0 )
2684 {
2685 if( crl_list->issuer_raw.len != ca->subject_raw.len ||
2686 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
2687 crl_list->issuer_raw.len ) != 0 )
2688 {
2689 crl_list = crl_list->next;
2690 continue;
2691 }
2692
2693 /*
2694 * Check if CRL is correctly signed by the trusted CA
2695 */
2696 hash_id = crl_list->sig_alg;
2697
2698 x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
2699
2700 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, hash_id,
2701 0, hash, crl_list->sig.p ) == 0 )
2702 {
2703 /*
2704 * CRL is not trusted
2705 */
2706 flags |= BADCRL_NOT_TRUSTED;
2707 break;
2708 }
2709
2710 /*
2711 * Check for validity of CRL (Do not drop out)
2712 */
2713 if( x509parse_time_expired( &crl_list->next_update ) )
2714 flags |= BADCRL_EXPIRED;
2715
2716 /*
2717 * Check if certificate is revoked
2718 */
2719 if( x509parse_revoked(crt, crl_list) )
2720 {
2721 flags |= BADCERT_REVOKED;
2722 break;
2723 }
2724
2725 crl_list = crl_list->next;
2726 }
2727 return flags;
2728}
2729
2730/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002731 * Verify the certificate validity
2732 */
2733int x509parse_verify( x509_cert *crt,
2734 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00002735 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002736 const char *cn, int *flags,
2737 int (*f_vrfy)(void *, x509_cert *, int, int),
2738 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00002739{
2740 int cn_len;
2741 int hash_id;
2742 int pathlen;
Paul Bakker76fd75a2011-01-16 21:12:10 +00002743 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00002744 x509_name *name;
Paul Bakker4593aea2009-02-09 22:32:35 +00002745 unsigned char hash[64];
Paul Bakker5121ce52009-01-03 21:22:43 +00002746
Paul Bakker40ea7de2009-05-03 10:18:48 +00002747 *flags = 0;
2748
2749 if( x509parse_time_expired( &crt->valid_to ) )
2750 *flags = BADCERT_EXPIRED;
Paul Bakker5121ce52009-01-03 21:22:43 +00002751
2752 if( cn != NULL )
2753 {
2754 name = &crt->subject;
2755 cn_len = strlen( cn );
2756
2757 while( name != NULL )
2758 {
2759 if( memcmp( name->oid.p, OID_CN, 3 ) == 0 &&
2760 memcmp( name->val.p, cn, cn_len ) == 0 &&
2761 name->val.len == cn_len )
2762 break;
2763
2764 name = name->next;
2765 }
2766
2767 if( name == NULL )
2768 *flags |= BADCERT_CN_MISMATCH;
2769 }
2770
Paul Bakker5121ce52009-01-03 21:22:43 +00002771 /*
2772 * Iterate upwards in the given cert chain,
2773 * ignoring any upper cert with CA != TRUE.
2774 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00002775 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002776
2777 pathlen = 1;
2778
Paul Bakker76fd75a2011-01-16 21:12:10 +00002779 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002780 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002781 if( parent->ca_istrue == 0 ||
2782 crt->issuer_raw.len != parent->subject_raw.len ||
2783 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00002784 crt->issuer_raw.len ) != 0 )
2785 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002786 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002787 continue;
2788 }
2789
Paul Bakker27d66162010-03-17 06:56:01 +00002790 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00002791
2792 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2793
Paul Bakker76fd75a2011-01-16 21:12:10 +00002794 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, hash_id, 0, hash,
2795 crt->sig.p ) != 0 )
2796 *flags |= BADCERT_NOT_TRUSTED;
2797
2798 /* Check trusted CA's CRL for the given crt */
2799 *flags |= x509parse_verifycrl(crt, parent, ca_crl);
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002800
2801 /* crt is verified to be a child of the parent cur, call verify callback */
Paul Bakker74111d32011-01-15 16:57:55 +00002802 if( NULL != f_vrfy )
2803 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002804 if( f_vrfy( p_vrfy, crt, pathlen - 1, ( *flags == 0 ) ) != 0 )
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002805 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker76fd75a2011-01-16 21:12:10 +00002806 else
2807 *flags = 0;
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002808 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00002809 else if( *flags != 0 )
2810 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002811
2812 pathlen++;
2813
Paul Bakker76fd75a2011-01-16 21:12:10 +00002814 crt = parent;
2815 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002816 }
2817
2818 /*
Paul Bakker76fd75a2011-01-16 21:12:10 +00002819 * Attempt to validate topmost cert with our CA chain.
Paul Bakker5121ce52009-01-03 21:22:43 +00002820 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00002821 *flags |= BADCERT_NOT_TRUSTED;
2822
Paul Bakker7c6d4a42009-03-28 20:35:47 +00002823 while( trust_ca != NULL && trust_ca->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002824 {
2825 if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
2826 memcmp( crt->issuer_raw.p, trust_ca->subject_raw.p,
2827 crt->issuer_raw.len ) != 0 )
2828 {
2829 trust_ca = trust_ca->next;
2830 continue;
2831 }
2832
2833 if( trust_ca->max_pathlen > 0 &&
2834 trust_ca->max_pathlen < pathlen )
2835 break;
2836
Paul Bakker27d66162010-03-17 06:56:01 +00002837 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00002838
2839 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2840
2841 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
2842 0, hash, crt->sig.p ) == 0 )
2843 {
2844 /*
2845 * cert. is signed by a trusted CA
2846 */
2847 *flags &= ~BADCERT_NOT_TRUSTED;
2848 break;
2849 }
2850
2851 trust_ca = trust_ca->next;
2852 }
2853
Paul Bakker76fd75a2011-01-16 21:12:10 +00002854 /* Check trusted CA's CRL for the given crt */
2855 *flags |= x509parse_verifycrl( crt, trust_ca, ca_crl );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002856
2857 /* Verification succeeded, call callback on top cert */
Paul Bakker74111d32011-01-15 16:57:55 +00002858 if( NULL != f_vrfy )
2859 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002860 if( f_vrfy(p_vrfy, crt, pathlen-1, ( *flags == 0 ) ) != 0 )
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002861 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker76fd75a2011-01-16 21:12:10 +00002862 else
2863 *flags = 0;
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002864 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00002865 else if( *flags != 0 )
2866 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002867
Paul Bakker5121ce52009-01-03 21:22:43 +00002868 return( 0 );
2869}
2870
2871/*
2872 * Unallocate all certificate data
2873 */
2874void x509_free( x509_cert *crt )
2875{
2876 x509_cert *cert_cur = crt;
2877 x509_cert *cert_prv;
2878 x509_name *name_cur;
2879 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00002880 x509_sequence *seq_cur;
2881 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00002882
2883 if( crt == NULL )
2884 return;
2885
2886 do
2887 {
2888 rsa_free( &cert_cur->rsa );
2889
2890 name_cur = cert_cur->issuer.next;
2891 while( name_cur != NULL )
2892 {
2893 name_prv = name_cur;
2894 name_cur = name_cur->next;
2895 memset( name_prv, 0, sizeof( x509_name ) );
2896 free( name_prv );
2897 }
2898
2899 name_cur = cert_cur->subject.next;
2900 while( name_cur != NULL )
2901 {
2902 name_prv = name_cur;
2903 name_cur = name_cur->next;
2904 memset( name_prv, 0, sizeof( x509_name ) );
2905 free( name_prv );
2906 }
2907
Paul Bakker74111d32011-01-15 16:57:55 +00002908 seq_cur = cert_cur->ext_key_usage.next;
2909 while( seq_cur != NULL )
2910 {
2911 seq_prv = seq_cur;
2912 seq_cur = seq_cur->next;
2913 memset( seq_prv, 0, sizeof( x509_sequence ) );
2914 free( seq_prv );
2915 }
2916
Paul Bakker5121ce52009-01-03 21:22:43 +00002917 if( cert_cur->raw.p != NULL )
2918 {
2919 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
2920 free( cert_cur->raw.p );
2921 }
2922
2923 cert_cur = cert_cur->next;
2924 }
2925 while( cert_cur != NULL );
2926
2927 cert_cur = crt;
2928 do
2929 {
2930 cert_prv = cert_cur;
2931 cert_cur = cert_cur->next;
2932
2933 memset( cert_prv, 0, sizeof( x509_cert ) );
2934 if( cert_prv != crt )
2935 free( cert_prv );
2936 }
2937 while( cert_cur != NULL );
2938}
2939
Paul Bakkerd98030e2009-05-02 15:13:40 +00002940/*
2941 * Unallocate all CRL data
2942 */
2943void x509_crl_free( x509_crl *crl )
2944{
2945 x509_crl *crl_cur = crl;
2946 x509_crl *crl_prv;
2947 x509_name *name_cur;
2948 x509_name *name_prv;
2949 x509_crl_entry *entry_cur;
2950 x509_crl_entry *entry_prv;
2951
2952 if( crl == NULL )
2953 return;
2954
2955 do
2956 {
2957 name_cur = crl_cur->issuer.next;
2958 while( name_cur != NULL )
2959 {
2960 name_prv = name_cur;
2961 name_cur = name_cur->next;
2962 memset( name_prv, 0, sizeof( x509_name ) );
2963 free( name_prv );
2964 }
2965
2966 entry_cur = crl_cur->entry.next;
2967 while( entry_cur != NULL )
2968 {
2969 entry_prv = entry_cur;
2970 entry_cur = entry_cur->next;
2971 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
2972 free( entry_prv );
2973 }
2974
2975 if( crl_cur->raw.p != NULL )
2976 {
2977 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
2978 free( crl_cur->raw.p );
2979 }
2980
2981 crl_cur = crl_cur->next;
2982 }
2983 while( crl_cur != NULL );
2984
2985 crl_cur = crl;
2986 do
2987 {
2988 crl_prv = crl_cur;
2989 crl_cur = crl_cur->next;
2990
2991 memset( crl_prv, 0, sizeof( x509_crl ) );
2992 if( crl_prv != crl )
2993 free( crl_prv );
2994 }
2995 while( crl_cur != NULL );
2996}
2997
Paul Bakker40e46942009-01-03 21:51:57 +00002998#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002999
Paul Bakker40e46942009-01-03 21:51:57 +00003000#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00003001
3002/*
3003 * Checkup routine
3004 */
3005int x509_self_test( int verbose )
3006{
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003007#if defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003008 int ret, i, j;
3009 x509_cert cacert;
3010 x509_cert clicert;
3011 rsa_context rsa;
Paul Bakker1b57b062011-01-06 15:48:19 +00003012 dhm_context dhm;
Paul Bakker5121ce52009-01-03 21:22:43 +00003013
3014 if( verbose != 0 )
3015 printf( " X.509 certificate load: " );
3016
3017 memset( &clicert, 0, sizeof( x509_cert ) );
3018
3019 ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
3020 strlen( test_cli_crt ) );
3021 if( ret != 0 )
3022 {
3023 if( verbose != 0 )
3024 printf( "failed\n" );
3025
3026 return( ret );
3027 }
3028
3029 memset( &cacert, 0, sizeof( x509_cert ) );
3030
3031 ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
3032 strlen( test_ca_crt ) );
3033 if( ret != 0 )
3034 {
3035 if( verbose != 0 )
3036 printf( "failed\n" );
3037
3038 return( ret );
3039 }
3040
3041 if( verbose != 0 )
3042 printf( "passed\n X.509 private key load: " );
3043
3044 i = strlen( test_ca_key );
3045 j = strlen( test_ca_pwd );
3046
3047 if( ( ret = x509parse_key( &rsa,
3048 (unsigned char *) test_ca_key, i,
3049 (unsigned char *) test_ca_pwd, j ) ) != 0 )
3050 {
3051 if( verbose != 0 )
3052 printf( "failed\n" );
3053
3054 return( ret );
3055 }
3056
3057 if( verbose != 0 )
3058 printf( "passed\n X.509 signature verify: ");
3059
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003060 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &i, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003061 if( ret != 0 )
3062 {
3063 if( verbose != 0 )
3064 printf( "failed\n" );
3065
3066 return( ret );
3067 }
3068
3069 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003070 printf( "passed\n X.509 DHM parameter load: " );
3071
3072 i = strlen( test_dhm_params );
3073 j = strlen( test_ca_pwd );
3074
3075 if( ( ret = x509parse_dhm( &dhm, (unsigned char *) test_dhm_params, i ) ) != 0 )
3076 {
3077 if( verbose != 0 )
3078 printf( "failed\n" );
3079
3080 return( ret );
3081 }
3082
3083 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003084 printf( "passed\n\n" );
3085
3086 x509_free( &cacert );
3087 x509_free( &clicert );
3088 rsa_free( &rsa );
Paul Bakker1b57b062011-01-06 15:48:19 +00003089 dhm_free( &dhm );
Paul Bakker5121ce52009-01-03 21:22:43 +00003090
3091 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003092#else
3093 ((void) verbose);
3094 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3095#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003096}
3097
3098#endif
3099
3100#endif