blob: df671eff555cf75aac4892aabbecb945f94f477f [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * X.509 certificate and private key decoding
3 *
Paul Bakker84f12b72010-07-18 10:13:04 +00004 * Copyright (C) 2006-2010, Brainspark B.V.
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
Paul Bakker84f12b72010-07-18 10:13:04 +00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakkerb96f1542010-07-18 20:36:00 +00008 *
Paul Bakker77b385e2009-07-28 17:23:11 +00009 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +000010 *
Paul Bakker5121ce52009-01-03 21:22:43 +000011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25/*
26 * The ITU-T X.509 standard defines a certificat format for PKI.
27 *
28 * http://www.ietf.org/rfc/rfc2459.txt
29 * http://www.ietf.org/rfc/rfc3279.txt
30 *
31 * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
32 *
33 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
34 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
35 */
36
Paul Bakker40e46942009-01-03 21:51:57 +000037#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000038
Paul Bakker40e46942009-01-03 21:51:57 +000039#if defined(POLARSSL_X509_PARSE_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000040
Paul Bakker40e46942009-01-03 21:51:57 +000041#include "polarssl/x509.h"
Paul Bakker96743fc2011-02-12 14:30:57 +000042#include "polarssl/pem.h"
Paul Bakker40e46942009-01-03 21:51:57 +000043#include "polarssl/des.h"
44#include "polarssl/md2.h"
45#include "polarssl/md4.h"
46#include "polarssl/md5.h"
47#include "polarssl/sha1.h"
Paul Bakker026c03b2009-03-28 17:53:03 +000048#include "polarssl/sha2.h"
49#include "polarssl/sha4.h"
Paul Bakker1b57b062011-01-06 15:48:19 +000050#include "polarssl/dhm.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000051
52#include <string.h>
53#include <stdlib.h>
54#include <stdio.h>
55#include <time.h>
56
57/*
58 * ASN.1 DER decoding routines
59 */
60static int asn1_get_len( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +000061 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +000062 int *len )
63{
64 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +000065 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000066
67 if( ( **p & 0x80 ) == 0 )
68 *len = *(*p)++;
69 else
70 {
71 switch( **p & 0x7F )
72 {
73 case 1:
74 if( ( end - *p ) < 2 )
Paul Bakker40e46942009-01-03 21:51:57 +000075 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000076
77 *len = (*p)[1];
78 (*p) += 2;
79 break;
80
81 case 2:
82 if( ( end - *p ) < 3 )
Paul Bakker40e46942009-01-03 21:51:57 +000083 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000084
85 *len = ( (*p)[1] << 8 ) | (*p)[2];
86 (*p) += 3;
87 break;
88
89 default:
Paul Bakker40e46942009-01-03 21:51:57 +000090 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +000091 break;
92 }
93 }
94
95 if( *len > (int) ( end - *p ) )
Paul Bakker40e46942009-01-03 21:51:57 +000096 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000097
98 return( 0 );
99}
100
101static int asn1_get_tag( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000102 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000103 int *len, int tag )
104{
105 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000106 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000107
108 if( **p != tag )
Paul Bakker40e46942009-01-03 21:51:57 +0000109 return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000110
111 (*p)++;
112
113 return( asn1_get_len( p, end, len ) );
114}
115
116static int asn1_get_bool( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000117 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000118 int *val )
119{
120 int ret, len;
121
122 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 )
123 return( ret );
124
125 if( len != 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000126 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000127
128 *val = ( **p != 0 ) ? 1 : 0;
129 (*p)++;
130
131 return( 0 );
132}
133
134static int asn1_get_int( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000135 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000136 int *val )
137{
138 int ret, len;
139
140 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
141 return( ret );
142
143 if( len > (int) sizeof( int ) || ( **p & 0x80 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000144 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000145
146 *val = 0;
147
148 while( len-- > 0 )
149 {
150 *val = ( *val << 8 ) | **p;
151 (*p)++;
152 }
153
154 return( 0 );
155}
156
157static int asn1_get_mpi( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000158 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000159 mpi *X )
160{
161 int ret, len;
162
163 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
164 return( ret );
165
166 ret = mpi_read_binary( X, *p, len );
167
168 *p += len;
169
170 return( ret );
171}
172
Paul Bakker74111d32011-01-15 16:57:55 +0000173static int asn1_get_bitstring( unsigned char **p, const unsigned char *end,
174 x509_bitstring *bs)
175{
176 int ret;
177
178 /* Certificate type is a single byte bitstring */
179 if( ( ret = asn1_get_tag( p, end, &bs->len, ASN1_BIT_STRING ) ) != 0 )
180 return( ret );
181
182 /* Check length, subtract one for actual bit string length */
183 if ( bs->len < 1 )
184 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
185 bs->len -= 1;
186
187 /* Get number of unused bits, ensure unused bits <= 7 */
188 bs->unused_bits = **p;
189 if( bs->unused_bits > 7 )
190 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
191 (*p)++;
192
193 /* Get actual bitstring */
194 bs->p = *p;
195 *p += bs->len;
196
197 if( *p != end )
198 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
199
200 return 0;
201}
202
203
204/*
205 * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
206 */
207static int asn1_get_sequence_of( unsigned char **p,
208 const unsigned char *end,
209 x509_sequence *cur,
210 int tag)
211{
212 int ret, len;
213 x509_buf *buf;
214
215 /* Get main sequence tag */
216 if( ( ret = asn1_get_tag( p, end, &len,
217 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
218 return( ret );
219
220 if( *p + len != end )
221 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
222
223 while( *p < end )
224 {
225 buf = &(cur->buf);
226 buf->tag = **p;
227
228 if( ( ret = asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
229 return( ret );
230
231 buf->p = *p;
232 *p += buf->len;
233
234 /* Allocate and assign next pointer */
235 if (*p < end)
236 {
237 cur->next = (x509_sequence *) malloc(
238 sizeof( x509_sequence ) );
239
240 if( cur->next == NULL )
241 return( 1 );
242
243 cur = cur->next;
244 }
245 }
246
247 /* Set final sequence entry's next pointer to NULL */
248 cur->next = NULL;
249
250 if( *p != end )
251 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
252
253 return( 0 );
254}
255
Paul Bakker5121ce52009-01-03 21:22:43 +0000256/*
257 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
258 */
259static int x509_get_version( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000260 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000261 int *ver )
262{
263 int ret, len;
264
265 if( ( ret = asn1_get_tag( p, end, &len,
266 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
267 {
Paul Bakker40e46942009-01-03 21:51:57 +0000268 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000269 return( *ver = 0 );
270
271 return( ret );
272 }
273
274 end = *p + len;
275
276 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000277 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000278
279 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000280 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION |
281 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000282
283 return( 0 );
284}
285
286/*
287 * CertificateSerialNumber ::= INTEGER
288 */
289static int x509_get_serial( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000290 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000291 x509_buf *serial )
292{
293 int ret;
294
295 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000296 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL |
297 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000298
299 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
300 **p != ASN1_INTEGER )
Paul Bakker40e46942009-01-03 21:51:57 +0000301 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL |
302 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000303
304 serial->tag = *(*p)++;
305
306 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000307 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000308
309 serial->p = *p;
310 *p += serial->len;
311
312 return( 0 );
313}
314
315/*
316 * AlgorithmIdentifier ::= SEQUENCE {
317 * algorithm OBJECT IDENTIFIER,
318 * parameters ANY DEFINED BY algorithm OPTIONAL }
319 */
320static int x509_get_alg( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000321 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000322 x509_buf *alg )
323{
324 int ret, len;
325
326 if( ( ret = asn1_get_tag( p, end, &len,
327 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000328 return( POLARSSL_ERR_X509_CERT_INVALID_ALG | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000329
330 end = *p + len;
331 alg->tag = **p;
332
333 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000334 return( POLARSSL_ERR_X509_CERT_INVALID_ALG | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000335
336 alg->p = *p;
337 *p += alg->len;
338
339 if( *p == end )
340 return( 0 );
341
342 /*
343 * assume the algorithm parameters must be NULL
344 */
345 if( ( ret = asn1_get_tag( p, end, &len, ASN1_NULL ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000346 return( POLARSSL_ERR_X509_CERT_INVALID_ALG | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000347
348 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000349 return( POLARSSL_ERR_X509_CERT_INVALID_ALG |
350 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000351
352 return( 0 );
353}
354
355/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000356 * AttributeTypeAndValue ::= SEQUENCE {
357 * type AttributeType,
358 * value AttributeValue }
359 *
360 * AttributeType ::= OBJECT IDENTIFIER
361 *
362 * AttributeValue ::= ANY DEFINED BY AttributeType
363 */
Paul Bakker400ff6f2011-02-20 10:40:16 +0000364static int x509_get_attr_type_value( unsigned char **p,
365 const unsigned char *end,
366 x509_name *cur )
Paul Bakker5121ce52009-01-03 21:22:43 +0000367{
368 int ret, len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000369 x509_buf *oid;
370 x509_buf *val;
371
372 if( ( ret = asn1_get_tag( p, end, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000373 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000374 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000375
Paul Bakker5121ce52009-01-03 21:22:43 +0000376 oid = &cur->oid;
377 oid->tag = **p;
378
379 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000380 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000381
382 oid->p = *p;
383 *p += oid->len;
384
385 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000386 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
387 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000388
389 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
390 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
391 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker40e46942009-01-03 21:51:57 +0000392 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
393 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000394
395 val = &cur->val;
396 val->tag = *(*p)++;
397
398 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000399 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000400
401 val->p = *p;
402 *p += val->len;
403
404 cur->next = NULL;
405
Paul Bakker400ff6f2011-02-20 10:40:16 +0000406 return( 0 );
407}
408
409/*
410 * RelativeDistinguishedName ::=
411 * SET OF AttributeTypeAndValue
412 *
413 * AttributeTypeAndValue ::= SEQUENCE {
414 * type AttributeType,
415 * value AttributeValue }
416 *
417 * AttributeType ::= OBJECT IDENTIFIER
418 *
419 * AttributeValue ::= ANY DEFINED BY AttributeType
420 */
421static int x509_get_name( unsigned char **p,
422 const unsigned char *end,
423 x509_name *cur )
424{
425 int ret, len;
426 const unsigned char *end2;
427 x509_name *use;
428
429 if( ( ret = asn1_get_tag( p, end, &len,
430 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
431 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
432
433 end2 = end;
434 end = *p + len;
435 use = cur;
436
437 do
438 {
439 if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
440 return( ret );
441
442 if( *p != end )
443 {
444 use->next = (x509_name *) malloc(
445 sizeof( x509_name ) );
446
447 if( use->next == NULL )
448 return( 1 );
449
450 memset( use->next, 0, sizeof( x509_name ) );
451
452 use = use->next;
453 }
454 }
455 while( *p != end );
Paul Bakker5121ce52009-01-03 21:22:43 +0000456
457 /*
458 * recurse until end of SEQUENCE is reached
459 */
460 if( *p == end2 )
461 return( 0 );
462
463 cur->next = (x509_name *) malloc(
464 sizeof( x509_name ) );
465
466 if( cur->next == NULL )
467 return( 1 );
468
469 return( x509_get_name( p, end2, cur->next ) );
470}
471
472/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000473 * Time ::= CHOICE {
474 * utcTime UTCTime,
475 * generalTime GeneralizedTime }
476 */
Paul Bakker91200182010-02-18 21:26:15 +0000477static int x509_get_time( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000478 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000479 x509_time *time )
480{
481 int ret, len;
482 char date[64];
Paul Bakker91200182010-02-18 21:26:15 +0000483 unsigned char tag;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000484
Paul Bakker91200182010-02-18 21:26:15 +0000485 if( ( end - *p ) < 1 )
486 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000487
Paul Bakker91200182010-02-18 21:26:15 +0000488 tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000489
Paul Bakker91200182010-02-18 21:26:15 +0000490 if ( tag == ASN1_UTC_TIME )
491 {
492 (*p)++;
493 ret = asn1_get_len( p, end, &len );
494
495 if( ret != 0 )
496 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000497
Paul Bakker91200182010-02-18 21:26:15 +0000498 memset( date, 0, sizeof( date ) );
499 memcpy( date, *p, ( len < (int) sizeof( date ) - 1 ) ?
500 len : (int) sizeof( date ) - 1 );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000501
Paul Bakker91200182010-02-18 21:26:15 +0000502 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
503 &time->year, &time->mon, &time->day,
504 &time->hour, &time->min, &time->sec ) < 5 )
505 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000506
Paul Bakker400ff6f2011-02-20 10:40:16 +0000507 time->year += 100 * ( time->year < 50 );
Paul Bakker91200182010-02-18 21:26:15 +0000508 time->year += 1900;
509
510 *p += len;
511
512 return( 0 );
513 }
514 else if ( tag == ASN1_GENERALIZED_TIME )
515 {
516 (*p)++;
517 ret = asn1_get_len( p, end, &len );
518
519 if( ret != 0 )
520 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret );
521
522 memset( date, 0, sizeof( date ) );
523 memcpy( date, *p, ( len < (int) sizeof( date ) - 1 ) ?
524 len : (int) sizeof( date ) - 1 );
525
526 if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
527 &time->year, &time->mon, &time->day,
528 &time->hour, &time->min, &time->sec ) < 5 )
529 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
530
531 *p += len;
532
533 return( 0 );
534 }
535 else
536 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000537}
538
539
540/*
541 * Validity ::= SEQUENCE {
542 * notBefore Time,
543 * notAfter Time }
544 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000545static int x509_get_dates( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000546 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000547 x509_time *from,
548 x509_time *to )
549{
550 int ret, len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000551
552 if( ( ret = asn1_get_tag( p, end, &len,
553 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000554 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000555
556 end = *p + len;
557
Paul Bakker91200182010-02-18 21:26:15 +0000558 if( ( ret = x509_get_time( p, end, from ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000559 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000560
Paul Bakker91200182010-02-18 21:26:15 +0000561 if( ( ret = x509_get_time( p, end, to ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000562 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000563
564 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000565 return( POLARSSL_ERR_X509_CERT_INVALID_DATE |
566 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000567
568 return( 0 );
569}
570
571/*
572 * SubjectPublicKeyInfo ::= SEQUENCE {
573 * algorithm AlgorithmIdentifier,
574 * subjectPublicKey BIT STRING }
575 */
576static int x509_get_pubkey( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000577 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000578 x509_buf *pk_alg_oid,
579 mpi *N, mpi *E )
580{
Paul Bakker400ff6f2011-02-20 10:40:16 +0000581 int ret, len, can_handle;
Paul Bakker5121ce52009-01-03 21:22:43 +0000582 unsigned char *end2;
583
584 if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 )
585 return( ret );
586
587 /*
588 * only RSA public keys handled at this time
589 */
Paul Bakker400ff6f2011-02-20 10:40:16 +0000590 can_handle = 0;
591
592 if( pk_alg_oid->len == 9 &&
593 memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) == 0 )
594 can_handle = 1;
595
596 if( pk_alg_oid->len == 9 &&
597 memcmp( pk_alg_oid->p, OID_PKCS1, 8 ) == 0 )
598 {
599 if( pk_alg_oid->p[8] >= 2 && pk_alg_oid->p[8] <= 5 )
600 can_handle = 1;
601
602 if ( pk_alg_oid->p[8] >= 11 && pk_alg_oid->p[8] <= 14 )
603 can_handle = 1;
604 }
605
606 if( pk_alg_oid->len == 5 &&
607 memcmp( pk_alg_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
608 can_handle = 1;
609
610 if( can_handle == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000611 return( POLARSSL_ERR_X509_CERT_UNKNOWN_PK_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000612
613 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000614 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000615
616 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000617 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY |
618 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000619
620 end2 = *p + len;
621
622 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000623 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000624
625 /*
626 * RSAPublicKey ::= SEQUENCE {
627 * modulus INTEGER, -- n
628 * publicExponent INTEGER -- e
629 * }
630 */
631 if( ( ret = asn1_get_tag( p, end2, &len,
632 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000633 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000634
635 if( *p + len != end2 )
Paul Bakker40e46942009-01-03 21:51:57 +0000636 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY |
637 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000638
639 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
640 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000641 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000642
643 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000644 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY |
645 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000646
647 return( 0 );
648}
649
650static int x509_get_sig( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000651 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000652 x509_buf *sig )
653{
654 int ret, len;
655
656 sig->tag = **p;
657
658 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000659 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000660
Paul Bakker74111d32011-01-15 16:57:55 +0000661
Paul Bakker5121ce52009-01-03 21:22:43 +0000662 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000663 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000664
665 sig->len = len;
666 sig->p = *p;
667
668 *p += len;
669
670 return( 0 );
671}
672
673/*
674 * X.509 v2/v3 unique identifier (not parsed)
675 */
676static int x509_get_uid( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000677 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000678 x509_buf *uid, int n )
679{
680 int ret;
681
682 if( *p == end )
683 return( 0 );
684
685 uid->tag = **p;
686
687 if( ( ret = asn1_get_tag( p, end, &uid->len,
688 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
689 {
Paul Bakker40e46942009-01-03 21:51:57 +0000690 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000691 return( 0 );
692
693 return( ret );
694 }
695
696 uid->p = *p;
697 *p += uid->len;
698
699 return( 0 );
700}
701
702/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000703 * X.509 Extensions (No parsing of extensions, pointer should
704 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000705 */
706static int x509_get_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000707 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000708 x509_buf *ext )
Paul Bakker5121ce52009-01-03 21:22:43 +0000709{
710 int ret, len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000711
712 if( *p == end )
713 return( 0 );
714
715 ext->tag = **p;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000716
Paul Bakker5121ce52009-01-03 21:22:43 +0000717 if( ( ret = asn1_get_tag( p, end, &ext->len,
718 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000719 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000720
721 ext->p = *p;
722 end = *p + ext->len;
723
724 /*
725 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
726 *
727 * Extension ::= SEQUENCE {
728 * extnID OBJECT IDENTIFIER,
729 * critical BOOLEAN DEFAULT FALSE,
730 * extnValue OCTET STRING }
731 */
732 if( ( ret = asn1_get_tag( p, end, &len,
733 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000734 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000735
736 if( end != *p + len )
Paul Bakker40e46942009-01-03 21:51:57 +0000737 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
738 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000739
Paul Bakkerd98030e2009-05-02 15:13:40 +0000740 return( 0 );
741}
742
743/*
744 * X.509 CRL v2 extensions (no extensions parsed yet.)
745 */
746static int x509_get_crl_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000747 const unsigned char *end,
748 x509_buf *ext )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000749{
750 int ret, len;
751
752 if( ( ret = x509_get_ext( p, end, ext ) ) != 0 )
753 {
754 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
755 return( 0 );
756
757 return( ret );
758 }
759
760 while( *p < end )
761 {
762 if( ( ret = asn1_get_tag( p, end, &len,
763 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
764 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
765
766 *p += len;
767 }
768
769 if( *p != end )
770 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
771 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
772
773 return( 0 );
774}
775
Paul Bakker74111d32011-01-15 16:57:55 +0000776static int x509_get_basic_constraints( unsigned char **p,
777 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000778 int *ca_istrue,
779 int *max_pathlen )
780{
781 int ret, len;
782
783 /*
784 * BasicConstraints ::= SEQUENCE {
785 * cA BOOLEAN DEFAULT FALSE,
786 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
787 */
Paul Bakker3cccddb2011-01-16 21:46:31 +0000788 *ca_istrue = 0; /* DEFAULT FALSE */
Paul Bakker74111d32011-01-15 16:57:55 +0000789 *max_pathlen = 0; /* endless */
790
791 if( ( ret = asn1_get_tag( p, end, &len,
792 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
793 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
794
795 if( *p == end )
796 return 0;
797
Paul Bakker3cccddb2011-01-16 21:46:31 +0000798 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000799 {
800 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker3cccddb2011-01-16 21:46:31 +0000801 ret = asn1_get_int( p, end, ca_istrue );
Paul Bakker74111d32011-01-15 16:57:55 +0000802
803 if( ret != 0 )
804 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
805
Paul Bakker3cccddb2011-01-16 21:46:31 +0000806 if( *ca_istrue != 0 )
807 *ca_istrue = 1;
Paul Bakker74111d32011-01-15 16:57:55 +0000808 }
809
810 if( *p == end )
811 return 0;
812
813 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
814 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
815
816 if( *p != end )
817 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
818 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
819
820 (*max_pathlen)++;
821
Paul Bakker74111d32011-01-15 16:57:55 +0000822 return 0;
823}
824
825static int x509_get_ns_cert_type( unsigned char **p,
826 const unsigned char *end,
827 unsigned char *ns_cert_type)
828{
829 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000830 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000831
832 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
833 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
834
835 if( bs.len != 1 )
836 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
837 POLARSSL_ERR_ASN1_INVALID_LENGTH );
838
839 /* Get actual bitstring */
840 *ns_cert_type = *bs.p;
841 return 0;
842}
843
844static int x509_get_key_usage( unsigned char **p,
845 const unsigned char *end,
846 unsigned char *key_usage)
847{
848 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000849 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000850
851 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
852 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
853
854 if( bs.len != 1 )
855 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
856 POLARSSL_ERR_ASN1_INVALID_LENGTH );
857
858 /* Get actual bitstring */
859 *key_usage = *bs.p;
860 return 0;
861}
862
Paul Bakkerd98030e2009-05-02 15:13:40 +0000863/*
Paul Bakker74111d32011-01-15 16:57:55 +0000864 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
865 *
866 * KeyPurposeId ::= OBJECT IDENTIFIER
867 */
868static int x509_get_ext_key_usage( unsigned char **p,
869 const unsigned char *end,
870 x509_sequence *ext_key_usage)
871{
872 int ret;
873
874 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
875 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
876
877 /* Sequence length must be >= 1 */
878 if( ext_key_usage->buf.p == NULL )
879 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
880 POLARSSL_ERR_ASN1_INVALID_LENGTH );
881
882 return 0;
883}
884
885/*
886 * X.509 v3 extensions
887 *
888 * TODO: Perform all of the basic constraints tests required by the RFC
889 * TODO: Set values for undetected extensions to a sane default?
890 *
Paul Bakkerd98030e2009-05-02 15:13:40 +0000891 */
892static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000893 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000894 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000895{
896 int ret, len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000897 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000898
Paul Bakker74111d32011-01-15 16:57:55 +0000899 if( ( ret = x509_get_ext( p, end, &crt->v3_ext ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000900 {
901 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
902 return( 0 );
903
904 return( ret );
905 }
906
Paul Bakker5121ce52009-01-03 21:22:43 +0000907 while( *p < end )
908 {
Paul Bakker74111d32011-01-15 16:57:55 +0000909 /*
910 * Extension ::= SEQUENCE {
911 * extnID OBJECT IDENTIFIER,
912 * critical BOOLEAN DEFAULT FALSE,
913 * extnValue OCTET STRING }
914 */
915 x509_buf extn_oid = {0, 0, NULL};
916 int is_critical = 0; /* DEFAULT FALSE */
917
Paul Bakker5121ce52009-01-03 21:22:43 +0000918 if( ( ret = asn1_get_tag( p, end, &len,
919 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000920 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000921
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000922 end_ext_data = *p + len;
923
Paul Bakker74111d32011-01-15 16:57:55 +0000924 /* Get extension ID */
925 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000926
Paul Bakker74111d32011-01-15 16:57:55 +0000927 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
928 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000929
Paul Bakker74111d32011-01-15 16:57:55 +0000930 extn_oid.p = *p;
931 *p += extn_oid.len;
932
933 if( ( end - *p ) < 1 )
934 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
935 POLARSSL_ERR_ASN1_OUT_OF_DATA );
936
937 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000938 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000939 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
940 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000941
Paul Bakker74111d32011-01-15 16:57:55 +0000942 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000943 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000944 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000945 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000946
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000947 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000948
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000949 if( end_ext_octet != end_ext_data )
950 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
951 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000952
Paul Bakker74111d32011-01-15 16:57:55 +0000953 /*
954 * Detect supported extensions
955 */
956 if( ( OID_SIZE( OID_BASIC_CONSTRAINTS ) == extn_oid.len ) &&
957 memcmp( extn_oid.p, OID_BASIC_CONSTRAINTS, extn_oid.len ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000958 {
Paul Bakker74111d32011-01-15 16:57:55 +0000959 /* Parse basic constraints */
960 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
Paul Bakker3cccddb2011-01-16 21:46:31 +0000961 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000962 return ( ret );
963 crt->ext_types |= EXT_BASIC_CONSTRAINTS;
Paul Bakker5121ce52009-01-03 21:22:43 +0000964 }
Paul Bakker74111d32011-01-15 16:57:55 +0000965 else if( ( OID_SIZE( OID_NS_CERT_TYPE ) == extn_oid.len ) &&
966 memcmp( extn_oid.p, OID_NS_CERT_TYPE, extn_oid.len ) == 0 )
967 {
968 /* Parse netscape certificate type */
969 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
970 &crt->ns_cert_type ) ) != 0 )
971 return ( ret );
972 crt->ext_types |= EXT_NS_CERT_TYPE;
973 }
974 else if( ( OID_SIZE( OID_KEY_USAGE ) == extn_oid.len ) &&
975 memcmp( extn_oid.p, OID_KEY_USAGE, extn_oid.len ) == 0 )
976 {
977 /* Parse key usage */
978 if( ( ret = x509_get_key_usage( p, end_ext_octet,
979 &crt->key_usage ) ) != 0 )
980 return ( ret );
981 crt->ext_types |= EXT_KEY_USAGE;
982 }
983 else if( ( OID_SIZE( OID_EXTENDED_KEY_USAGE ) == extn_oid.len ) &&
984 memcmp( extn_oid.p, OID_EXTENDED_KEY_USAGE, extn_oid.len ) == 0 )
985 {
986 /* Parse extended key usage */
987 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
988 &crt->ext_key_usage ) ) != 0 )
989 return ( ret );
990 crt->ext_types |= EXT_EXTENDED_KEY_USAGE;
991 }
992 else
993 {
994 /* No parser found, skip extension */
995 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +0000996
Paul Bakker74111d32011-01-15 16:57:55 +0000997 if( is_critical )
998 {
999 /* Data is marked as critical: fail */
1000 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
1001 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
1002 }
1003 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001004 }
1005
1006 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +00001007 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
1008 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001009
Paul Bakker5121ce52009-01-03 21:22:43 +00001010 return( 0 );
1011}
1012
1013/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001014 * X.509 CRL Entries
1015 */
1016static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001017 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001018 x509_crl_entry *entry )
1019{
Paul Bakker9be19372009-07-27 20:21:53 +00001020 int ret, entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001021 x509_crl_entry *cur_entry = entry;
1022
1023 if( *p == end )
1024 return( 0 );
1025
Paul Bakker9be19372009-07-27 20:21:53 +00001026 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001027 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1028 {
1029 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
1030 return( 0 );
1031
1032 return( ret );
1033 }
1034
Paul Bakker9be19372009-07-27 20:21:53 +00001035 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001036
1037 while( *p < end )
1038 {
1039 int len2;
1040
1041 if( ( ret = asn1_get_tag( p, end, &len2,
1042 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1043 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001044 return( ret );
1045 }
1046
Paul Bakker9be19372009-07-27 20:21:53 +00001047 cur_entry->raw.tag = **p;
1048 cur_entry->raw.p = *p;
1049 cur_entry->raw.len = len2;
1050
Paul Bakkerd98030e2009-05-02 15:13:40 +00001051 if( ( ret = x509_get_serial( p, end, &cur_entry->serial ) ) != 0 )
1052 return( ret );
1053
Paul Bakker91200182010-02-18 21:26:15 +00001054 if( ( ret = x509_get_time( p, end, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001055 return( ret );
1056
1057 if( ( ret = x509_get_crl_ext( p, end, &cur_entry->entry_ext ) ) != 0 )
1058 return( ret );
1059
Paul Bakker74111d32011-01-15 16:57:55 +00001060 if ( *p < end )
1061 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001062 cur_entry->next = malloc( sizeof( x509_crl_entry ) );
1063 cur_entry = cur_entry->next;
1064 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
1065 }
1066 }
1067
1068 return( 0 );
1069}
1070
Paul Bakker27d66162010-03-17 06:56:01 +00001071static int x509_get_sig_alg( const x509_buf *sig_oid, int *sig_alg )
1072{
1073 if( sig_oid->len == 9 &&
1074 memcmp( sig_oid->p, OID_PKCS1, 8 ) == 0 )
1075 {
1076 if( sig_oid->p[8] >= 2 && sig_oid->p[8] <= 5 )
1077 {
1078 *sig_alg = sig_oid->p[8];
1079 return( 0 );
1080 }
1081
1082 if ( sig_oid->p[8] >= 11 && sig_oid->p[8] <= 14 )
1083 {
1084 *sig_alg = sig_oid->p[8];
1085 return( 0 );
1086 }
1087
1088 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1089 }
Paul Bakker400ff6f2011-02-20 10:40:16 +00001090 if( sig_oid->len == 5 &&
1091 memcmp( sig_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
1092 {
1093 *sig_alg = SIG_RSA_SHA1;
1094 return( 0 );
1095 }
Paul Bakker27d66162010-03-17 06:56:01 +00001096
1097 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1098}
1099
Paul Bakkerd98030e2009-05-02 15:13:40 +00001100/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001101 * Parse one or more certificates and add them to the chained list
1102 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001103int x509parse_crt( x509_cert *chain, const unsigned char *buf, int buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001104{
Paul Bakker96743fc2011-02-12 14:30:57 +00001105 int ret, len, use_len;
Paul Bakker5121ce52009-01-03 21:22:43 +00001106 unsigned char *p, *end;
1107 x509_cert *crt;
Paul Bakker96743fc2011-02-12 14:30:57 +00001108#if defined(POLARSSL_PEM_C)
1109 pem_context pem;
1110#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001111
1112 crt = chain;
1113
Paul Bakker320a4b52009-03-28 18:52:39 +00001114 /*
1115 * Check for valid input
1116 */
1117 if( crt == NULL || buf == NULL )
1118 return( 1 );
1119
Paul Bakkere9581d62009-03-28 20:29:25 +00001120 while( crt->version != 0 && crt->next != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00001121 crt = crt->next;
1122
1123 /*
Paul Bakker320a4b52009-03-28 18:52:39 +00001124 * Add new certificate on the end of the chain if needed.
1125 */
Paul Bakkere9581d62009-03-28 20:29:25 +00001126 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001127 {
1128 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1129
Paul Bakker7d06ad22009-05-02 15:53:56 +00001130 if( crt->next == NULL )
1131 {
Paul Bakker320a4b52009-03-28 18:52:39 +00001132 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001133 return( 1 );
1134 }
Paul Bakker320a4b52009-03-28 18:52:39 +00001135
Paul Bakker7d06ad22009-05-02 15:53:56 +00001136 crt = crt->next;
1137 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001138 }
1139
Paul Bakker96743fc2011-02-12 14:30:57 +00001140#if defined(POLARSSL_PEM_C)
1141 pem_init( &pem );
1142 ret = pem_read_buffer( &pem,
1143 "-----BEGIN CERTIFICATE-----",
1144 "-----END CERTIFICATE-----",
1145 buf, NULL, 0, &use_len );
Paul Bakker5121ce52009-01-03 21:22:43 +00001146
Paul Bakker96743fc2011-02-12 14:30:57 +00001147 if( ret == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001148 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001149 /*
1150 * Was PEM encoded
1151 */
1152 buflen -= use_len;
1153 buf += use_len;
Paul Bakker5121ce52009-01-03 21:22:43 +00001154
1155 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001156 * Steal PEM buffer
Paul Bakker5121ce52009-01-03 21:22:43 +00001157 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001158 p = pem.buf;
1159 pem.buf = NULL;
1160 len = pem.buflen;
1161 pem_free( &pem );
1162 }
1163 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
1164 {
1165 pem_free( &pem );
1166 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001167 }
1168 else
1169 {
1170 /*
1171 * nope, copy the raw DER data
1172 */
1173 p = (unsigned char *) malloc( len = buflen );
1174
1175 if( p == NULL )
1176 return( 1 );
1177
1178 memcpy( p, buf, buflen );
1179
1180 buflen = 0;
1181 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001182#else
1183 p = (unsigned char *) malloc( len = buflen );
1184
1185 if( p == NULL )
1186 return( 1 );
1187
1188 memcpy( p, buf, buflen );
1189
1190 buflen = 0;
1191#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001192
1193 crt->raw.p = p;
1194 crt->raw.len = len;
1195 end = p + len;
1196
1197 /*
1198 * Certificate ::= SEQUENCE {
1199 * tbsCertificate TBSCertificate,
1200 * signatureAlgorithm AlgorithmIdentifier,
1201 * signatureValue BIT STRING }
1202 */
1203 if( ( ret = asn1_get_tag( &p, end, &len,
1204 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
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_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001208 }
1209
1210 if( len != (int) ( end - p ) )
1211 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001212 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001213 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1214 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001215 }
1216
1217 /*
1218 * TBSCertificate ::= SEQUENCE {
1219 */
1220 crt->tbs.p = p;
1221
1222 if( ( ret = asn1_get_tag( &p, end, &len,
1223 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1224 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001225 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001226 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001227 }
1228
1229 end = p + len;
1230 crt->tbs.len = end - crt->tbs.p;
1231
1232 /*
1233 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1234 *
1235 * CertificateSerialNumber ::= INTEGER
1236 *
1237 * signature AlgorithmIdentifier
1238 */
1239 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1240 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1241 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
1242 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001243 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001244 return( ret );
1245 }
1246
1247 crt->version++;
1248
1249 if( crt->version > 3 )
1250 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001251 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001252 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001253 }
1254
Paul Bakker27d66162010-03-17 06:56:01 +00001255 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_alg ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001256 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001257 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001258 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001259 }
1260
1261 /*
1262 * issuer Name
1263 */
1264 crt->issuer_raw.p = p;
1265
1266 if( ( ret = asn1_get_tag( &p, end, &len,
1267 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1268 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001269 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001270 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001271 }
1272
1273 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1274 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001275 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001276 return( ret );
1277 }
1278
1279 crt->issuer_raw.len = p - crt->issuer_raw.p;
1280
1281 /*
1282 * Validity ::= SEQUENCE {
1283 * notBefore Time,
1284 * notAfter Time }
1285 *
1286 */
1287 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1288 &crt->valid_to ) ) != 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 /*
1295 * subject Name
1296 */
1297 crt->subject_raw.p = p;
1298
1299 if( ( ret = asn1_get_tag( &p, end, &len,
1300 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1301 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001302 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001303 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001304 }
1305
1306 if( ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
1307 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001308 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001309 return( ret );
1310 }
1311
1312 crt->subject_raw.len = p - crt->subject_raw.p;
1313
1314 /*
1315 * SubjectPublicKeyInfo ::= SEQUENCE
1316 * algorithm AlgorithmIdentifier,
1317 * subjectPublicKey BIT STRING }
1318 */
1319 if( ( ret = asn1_get_tag( &p, end, &len,
1320 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1321 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001322 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001323 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001324 }
1325
1326 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1327 &crt->rsa.N, &crt->rsa.E ) ) != 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 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1334 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001335 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001336 return( ret );
1337 }
1338
1339 crt->rsa.len = mpi_size( &crt->rsa.N );
1340
1341 /*
1342 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1343 * -- If present, version shall be v2 or v3
1344 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1345 * -- If present, version shall be v2 or v3
1346 * extensions [3] EXPLICIT Extensions OPTIONAL
1347 * -- If present, version shall be v3
1348 */
1349 if( crt->version == 2 || crt->version == 3 )
1350 {
1351 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1352 if( ret != 0 )
1353 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001354 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001355 return( ret );
1356 }
1357 }
1358
1359 if( crt->version == 2 || crt->version == 3 )
1360 {
1361 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1362 if( ret != 0 )
1363 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001364 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001365 return( ret );
1366 }
1367 }
1368
1369 if( crt->version == 3 )
1370 {
Paul Bakker74111d32011-01-15 16:57:55 +00001371 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001372 if( ret != 0 )
1373 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001374 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001375 return( ret );
1376 }
1377 }
1378
1379 if( p != end )
1380 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001381 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001382 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1383 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001384 }
1385
1386 end = crt->raw.p + crt->raw.len;
1387
1388 /*
1389 * signatureAlgorithm AlgorithmIdentifier,
1390 * signatureValue BIT STRING
1391 */
1392 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1393 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001394 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001395 return( ret );
1396 }
1397
Paul Bakker320a4b52009-03-28 18:52:39 +00001398 if( memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001399 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001400 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001401 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001402 }
1403
1404 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1405 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001406 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001407 return( ret );
1408 }
1409
1410 if( p != end )
1411 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001412 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001413 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1414 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001415 }
1416
Paul Bakker5121ce52009-01-03 21:22:43 +00001417 if( buflen > 0 )
Paul Bakker320a4b52009-03-28 18:52:39 +00001418 {
1419 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1420
Paul Bakker7d06ad22009-05-02 15:53:56 +00001421 if( crt->next == NULL )
1422 {
Paul Bakker320a4b52009-03-28 18:52:39 +00001423 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001424 return( 1 );
1425 }
Paul Bakker320a4b52009-03-28 18:52:39 +00001426
Paul Bakker7d06ad22009-05-02 15:53:56 +00001427 crt = crt->next;
1428 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001429
Paul Bakker5121ce52009-01-03 21:22:43 +00001430 return( x509parse_crt( crt, buf, buflen ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001431 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001432
1433 return( 0 );
1434}
1435
1436/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001437 * Parse one or more CRLs and add them to the chained list
1438 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001439int x509parse_crl( x509_crl *chain, const unsigned char *buf, int buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001440{
Paul Bakker96743fc2011-02-12 14:30:57 +00001441 int ret, len, use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001442 unsigned char *p, *end;
1443 x509_crl *crl;
Paul Bakker96743fc2011-02-12 14:30:57 +00001444#if defined(POLARSSL_PEM_C)
1445 pem_context pem;
1446#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001447
1448 crl = chain;
1449
1450 /*
1451 * Check for valid input
1452 */
1453 if( crl == NULL || buf == NULL )
1454 return( 1 );
1455
1456 while( crl->version != 0 && crl->next != NULL )
1457 crl = crl->next;
1458
1459 /*
1460 * Add new CRL on the end of the chain if needed.
1461 */
1462 if ( crl->version != 0 && crl->next == NULL)
1463 {
1464 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1465
Paul Bakker7d06ad22009-05-02 15:53:56 +00001466 if( crl->next == NULL )
1467 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001468 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001469 return( 1 );
1470 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001471
Paul Bakker7d06ad22009-05-02 15:53:56 +00001472 crl = crl->next;
1473 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001474 }
1475
Paul Bakker96743fc2011-02-12 14:30:57 +00001476#if defined(POLARSSL_PEM_C)
1477 pem_init( &pem );
1478 ret = pem_read_buffer( &pem,
1479 "-----BEGIN X509 CRL-----",
1480 "-----END X509 CRL-----",
1481 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001482
Paul Bakker96743fc2011-02-12 14:30:57 +00001483 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001484 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001485 /*
1486 * Was PEM encoded
1487 */
1488 buflen -= use_len;
1489 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001490
1491 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001492 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001493 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001494 p = pem.buf;
1495 pem.buf = NULL;
1496 len = pem.buflen;
1497 pem_free( &pem );
1498 }
1499 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
1500 {
1501 pem_free( &pem );
1502 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001503 }
1504 else
1505 {
1506 /*
1507 * nope, copy the raw DER data
1508 */
1509 p = (unsigned char *) malloc( len = buflen );
1510
1511 if( p == NULL )
1512 return( 1 );
1513
1514 memcpy( p, buf, buflen );
1515
1516 buflen = 0;
1517 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001518#else
1519 p = (unsigned char *) malloc( len = buflen );
1520
1521 if( p == NULL )
1522 return( 1 );
1523
1524 memcpy( p, buf, buflen );
1525
1526 buflen = 0;
1527#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001528
1529 crl->raw.p = p;
1530 crl->raw.len = len;
1531 end = p + len;
1532
1533 /*
1534 * CertificateList ::= SEQUENCE {
1535 * tbsCertList TBSCertList,
1536 * signatureAlgorithm AlgorithmIdentifier,
1537 * signatureValue BIT STRING }
1538 */
1539 if( ( ret = asn1_get_tag( &p, end, &len,
1540 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1541 {
1542 x509_crl_free( crl );
1543 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1544 }
1545
1546 if( len != (int) ( end - p ) )
1547 {
1548 x509_crl_free( crl );
1549 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1550 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1551 }
1552
1553 /*
1554 * TBSCertList ::= SEQUENCE {
1555 */
1556 crl->tbs.p = p;
1557
1558 if( ( ret = asn1_get_tag( &p, end, &len,
1559 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1560 {
1561 x509_crl_free( crl );
1562 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
1563 }
1564
1565 end = p + len;
1566 crl->tbs.len = end - crl->tbs.p;
1567
1568 /*
1569 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1570 * -- if present, MUST be v2
1571 *
1572 * signature AlgorithmIdentifier
1573 */
1574 if( ( ret = x509_get_version( &p, end, &crl->version ) ) != 0 ||
1575 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1576 {
1577 x509_crl_free( crl );
1578 return( ret );
1579 }
1580
1581 crl->version++;
1582
1583 if( crl->version > 2 )
1584 {
1585 x509_crl_free( crl );
1586 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1587 }
1588
Paul Bakker27d66162010-03-17 06:56:01 +00001589 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_alg ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001590 {
1591 x509_crl_free( crl );
1592 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1593 }
1594
1595 /*
1596 * issuer Name
1597 */
1598 crl->issuer_raw.p = p;
1599
1600 if( ( ret = asn1_get_tag( &p, end, &len,
1601 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1602 {
1603 x509_crl_free( crl );
1604 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
1605 }
1606
1607 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1608 {
1609 x509_crl_free( crl );
1610 return( ret );
1611 }
1612
1613 crl->issuer_raw.len = p - crl->issuer_raw.p;
1614
1615 /*
1616 * thisUpdate Time
1617 * nextUpdate Time OPTIONAL
1618 */
Paul Bakker91200182010-02-18 21:26:15 +00001619 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001620 {
1621 x509_crl_free( crl );
1622 return( ret );
1623 }
1624
Paul Bakker91200182010-02-18 21:26:15 +00001625 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001626 {
Paul Bakker635f4b42009-07-20 20:34:41 +00001627 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE |
Paul Bakker9be19372009-07-27 20:21:53 +00001628 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
1629 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE |
1630 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001631 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001632 x509_crl_free( crl );
1633 return( ret );
1634 }
1635 }
1636
1637 /*
1638 * revokedCertificates SEQUENCE OF SEQUENCE {
1639 * userCertificate CertificateSerialNumber,
1640 * revocationDate Time,
1641 * crlEntryExtensions Extensions OPTIONAL
1642 * -- if present, MUST be v2
1643 * } OPTIONAL
1644 */
1645 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1646 {
1647 x509_crl_free( crl );
1648 return( ret );
1649 }
1650
1651 /*
1652 * crlExtensions EXPLICIT Extensions OPTIONAL
1653 * -- if present, MUST be v2
1654 */
1655 if( crl->version == 2 )
1656 {
1657 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1658
1659 if( ret != 0 )
1660 {
1661 x509_crl_free( crl );
1662 return( ret );
1663 }
1664 }
1665
1666 if( p != end )
1667 {
1668 x509_crl_free( crl );
1669 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1670 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1671 }
1672
1673 end = crl->raw.p + crl->raw.len;
1674
1675 /*
1676 * signatureAlgorithm AlgorithmIdentifier,
1677 * signatureValue BIT STRING
1678 */
1679 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1680 {
1681 x509_crl_free( crl );
1682 return( ret );
1683 }
1684
1685 if( memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
1686 {
1687 x509_crl_free( crl );
1688 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1689 }
1690
1691 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1692 {
1693 x509_crl_free( crl );
1694 return( ret );
1695 }
1696
1697 if( p != end )
1698 {
1699 x509_crl_free( crl );
1700 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1701 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1702 }
1703
1704 if( buflen > 0 )
1705 {
1706 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1707
Paul Bakker7d06ad22009-05-02 15:53:56 +00001708 if( crl->next == NULL )
1709 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001710 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001711 return( 1 );
1712 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001713
Paul Bakker7d06ad22009-05-02 15:53:56 +00001714 crl = crl->next;
1715 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001716
1717 return( x509parse_crl( crl, buf, buflen ) );
1718 }
1719
1720 return( 0 );
1721}
1722
1723/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001724 * Load all data from a file into a given buffer.
1725 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001726int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001727{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001728 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001729
Paul Bakkerd98030e2009-05-02 15:13:40 +00001730 if( ( f = fopen( path, "rb" ) ) == NULL )
1731 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001732
Paul Bakkerd98030e2009-05-02 15:13:40 +00001733 fseek( f, 0, SEEK_END );
1734 *n = (size_t) ftell( f );
1735 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001736
Paul Bakkerd98030e2009-05-02 15:13:40 +00001737 if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
1738 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001739
Paul Bakkerd98030e2009-05-02 15:13:40 +00001740 if( fread( *buf, 1, *n, f ) != *n )
1741 {
1742 fclose( f );
1743 free( *buf );
1744 return( 1 );
1745 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001746
Paul Bakkerd98030e2009-05-02 15:13:40 +00001747 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001748
Paul Bakkerd98030e2009-05-02 15:13:40 +00001749 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001750
Paul Bakkerd98030e2009-05-02 15:13:40 +00001751 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001752}
1753
1754/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001755 * Load one or more certificates and add them to the chained list
1756 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001757int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001758{
1759 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001760 size_t n;
1761 unsigned char *buf;
1762
Paul Bakker2b245eb2009-04-19 18:44:26 +00001763 if ( load_file( path, &buf, &n ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001764 return( 1 );
1765
Paul Bakker5121ce52009-01-03 21:22:43 +00001766 ret = x509parse_crt( chain, buf, (int) n );
1767
1768 memset( buf, 0, n + 1 );
1769 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001770
1771 return( ret );
1772}
1773
Paul Bakkerd98030e2009-05-02 15:13:40 +00001774/*
1775 * Load one or more CRLs and add them to the chained list
1776 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001777int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001778{
1779 int ret;
1780 size_t n;
1781 unsigned char *buf;
1782
1783 if ( load_file( path, &buf, &n ) )
1784 return( 1 );
1785
1786 ret = x509parse_crl( chain, buf, (int) n );
1787
1788 memset( buf, 0, n + 1 );
1789 free( buf );
1790
1791 return( ret );
1792}
1793
Paul Bakker5121ce52009-01-03 21:22:43 +00001794/*
1795 * Parse a private RSA key
1796 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001797int x509parse_key( rsa_context *rsa, const unsigned char *key, int keylen,
1798 const unsigned char *pwd, int pwdlen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001799{
Paul Bakker96743fc2011-02-12 14:30:57 +00001800 int ret, len;
Paul Bakker5121ce52009-01-03 21:22:43 +00001801 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00001802#if defined(POLARSSL_PEM_C)
1803 pem_context pem;
Paul Bakker5121ce52009-01-03 21:22:43 +00001804
Paul Bakker96743fc2011-02-12 14:30:57 +00001805 pem_init( &pem );
1806 ret = pem_read_buffer( &pem,
1807 "-----BEGIN RSA PRIVATE KEY-----",
1808 "-----END RSA PRIVATE KEY-----",
1809 key, pwd, pwdlen, &len );
Paul Bakker5121ce52009-01-03 21:22:43 +00001810
Paul Bakker96743fc2011-02-12 14:30:57 +00001811 if( ret == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001812 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001813 /*
1814 * Was PEM encoded
1815 */
1816 keylen = pem.buflen;
Paul Bakker5121ce52009-01-03 21:22:43 +00001817 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001818 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
Paul Bakkerff60ee62010-03-16 21:09:09 +00001819 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001820 pem_free( &pem );
1821 return( ret );
Paul Bakkerff60ee62010-03-16 21:09:09 +00001822 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001823
Paul Bakker96743fc2011-02-12 14:30:57 +00001824 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
1825#else
1826 p = (unsigned char *) key;
1827#endif
1828 end = p + keylen;
1829
Paul Bakker5121ce52009-01-03 21:22:43 +00001830 /*
1831 * RSAPrivateKey ::= SEQUENCE {
1832 * version Version,
1833 * modulus INTEGER, -- n
1834 * publicExponent INTEGER, -- e
1835 * privateExponent INTEGER, -- d
1836 * prime1 INTEGER, -- p
1837 * prime2 INTEGER, -- q
1838 * exponent1 INTEGER, -- d mod (p-1)
1839 * exponent2 INTEGER, -- d mod (q-1)
1840 * coefficient INTEGER, -- (inverse of q) mod p
1841 * otherPrimeInfos OtherPrimeInfos OPTIONAL
1842 * }
1843 */
1844 if( ( ret = asn1_get_tag( &p, end, &len,
1845 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1846 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001847#if defined(POLARSSL_PEM_C)
1848 pem_free( &pem );
1849#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001850 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001851 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001852 }
1853
1854 end = p + len;
1855
1856 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
1857 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001858#if defined(POLARSSL_PEM_C)
1859 pem_free( &pem );
1860#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001861 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001862 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001863 }
1864
1865 if( rsa->ver != 0 )
1866 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001867#if defined(POLARSSL_PEM_C)
1868 pem_free( &pem );
1869#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001870 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001871 return( ret | POLARSSL_ERR_X509_KEY_INVALID_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001872 }
1873
1874 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
1875 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
1876 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
1877 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
1878 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
1879 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
1880 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
1881 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
1882 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001883#if defined(POLARSSL_PEM_C)
1884 pem_free( &pem );
1885#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001886 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001887 return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001888 }
1889
1890 rsa->len = mpi_size( &rsa->N );
1891
1892 if( p != end )
1893 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001894#if defined(POLARSSL_PEM_C)
1895 pem_free( &pem );
1896#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001897 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001898 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT |
1899 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001900 }
1901
1902 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
1903 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001904#if defined(POLARSSL_PEM_C)
1905 pem_free( &pem );
1906#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001907 rsa_free( rsa );
1908 return( ret );
1909 }
1910
Paul Bakker96743fc2011-02-12 14:30:57 +00001911#if defined(POLARSSL_PEM_C)
1912 pem_free( &pem );
1913#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001914
1915 return( 0 );
1916}
1917
1918/*
1919 * Load and parse a private RSA key
1920 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001921int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
Paul Bakker5121ce52009-01-03 21:22:43 +00001922{
1923 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001924 size_t n;
1925 unsigned char *buf;
1926
Paul Bakker2b245eb2009-04-19 18:44:26 +00001927 if ( load_file( path, &buf, &n ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001928 return( 1 );
1929
Paul Bakker5121ce52009-01-03 21:22:43 +00001930 if( pwd == NULL )
1931 ret = x509parse_key( rsa, buf, (int) n, NULL, 0 );
1932 else
1933 ret = x509parse_key( rsa, buf, (int) n,
1934 (unsigned char *) pwd, strlen( pwd ) );
1935
1936 memset( buf, 0, n + 1 );
1937 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001938
1939 return( ret );
1940}
1941
Paul Bakker1b57b062011-01-06 15:48:19 +00001942/*
Paul Bakker53019ae2011-03-25 13:58:48 +00001943 * Parse a public RSA key
1944 */
1945int x509parse_public_key( rsa_context *rsa, const unsigned char *key, int keylen )
1946{
1947 int ret, len;
1948 unsigned char *p, *end;
1949 x509_buf alg_oid;
1950#if defined(POLARSSL_PEM_C)
1951 pem_context pem;
1952
1953 pem_init( &pem );
1954 ret = pem_read_buffer( &pem,
1955 "-----BEGIN PUBLIC KEY-----",
1956 "-----END PUBLIC KEY-----",
1957 key, NULL, 0, &len );
1958
1959 if( ret == 0 )
1960 {
1961 /*
1962 * Was PEM encoded
1963 */
1964 keylen = pem.buflen;
1965 }
1966 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
1967 {
1968 pem_free( &pem );
1969 return( ret );
1970 }
1971
1972 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
1973#else
1974 p = (unsigned char *) key;
1975#endif
1976 end = p + keylen;
1977
1978 /*
1979 * PublicKeyInfo ::= SEQUENCE {
1980 * algorithm AlgorithmIdentifier,
1981 * PublicKey BIT STRING
1982 * }
1983 *
1984 * AlgorithmIdentifier ::= SEQUENCE {
1985 * algorithm OBJECT IDENTIFIER,
1986 * parameters ANY DEFINED BY algorithm OPTIONAL
1987 * }
1988 *
1989 * RSAPublicKey ::= SEQUENCE {
1990 * modulus INTEGER, -- n
1991 * publicExponent INTEGER -- e
1992 * }
1993 */
1994
1995 if( ( ret = asn1_get_tag( &p, end, &len,
1996 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1997 {
1998#if defined(POLARSSL_PEM_C)
1999 pem_free( &pem );
2000#endif
2001 rsa_free( rsa );
2002 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
2003 }
2004
2005 if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
2006 {
2007#if defined(POLARSSL_PEM_C)
2008 pem_free( &pem );
2009#endif
2010 rsa_free( rsa );
2011 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
2012 }
2013
2014 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
2015 {
2016#if defined(POLARSSL_PEM_C)
2017 pem_free( &pem );
2018#endif
2019 rsa_free( rsa );
2020 return( ret );
2021 }
2022
2023 rsa->len = mpi_size( &rsa->N );
2024
2025#if defined(POLARSSL_PEM_C)
2026 pem_free( &pem );
2027#endif
2028
2029 return( 0 );
2030}
2031
2032/*
2033 * Load and parse a public RSA key
2034 */
2035int x509parse_public_keyfile( rsa_context *rsa, const char *path )
2036{
2037 int ret;
2038 size_t n;
2039 unsigned char *buf;
2040
2041 if ( load_file( path, &buf, &n ) )
2042 return( 1 );
2043
2044 ret = x509parse_public_key( rsa, buf, (int) n );
2045
2046 memset( buf, 0, n + 1 );
2047 free( buf );
2048
2049 return( ret );
2050}
2051
2052/*
Paul Bakker1b57b062011-01-06 15:48:19 +00002053 * Parse DHM parameters
2054 */
2055int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, int dhminlen )
2056{
2057 int ret, len;
Paul Bakker1b57b062011-01-06 15:48:19 +00002058 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00002059#if defined(POLARSSL_PEM_C)
2060 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00002061
Paul Bakker96743fc2011-02-12 14:30:57 +00002062 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00002063
Paul Bakker96743fc2011-02-12 14:30:57 +00002064 ret = pem_read_buffer( &pem,
2065 "-----BEGIN DH PARAMETERS-----",
2066 "-----END DH PARAMETERS-----",
2067 dhmin, NULL, 0, &dhminlen );
2068
2069 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00002070 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002071 /*
2072 * Was PEM encoded
2073 */
2074 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00002075 }
Paul Bakker96743fc2011-02-12 14:30:57 +00002076 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00002077 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002078 pem_free( &pem );
2079 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002080 }
2081
Paul Bakker96743fc2011-02-12 14:30:57 +00002082 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
2083#else
2084 p = (unsigned char *) dhmin;
2085#endif
2086 end = p + dhminlen;
2087
Paul Bakker1b57b062011-01-06 15:48:19 +00002088 memset( dhm, 0, sizeof( dhm_context ) );
2089
Paul Bakker1b57b062011-01-06 15:48:19 +00002090 /*
2091 * DHParams ::= SEQUENCE {
2092 * prime INTEGER, -- P
2093 * generator INTEGER, -- g
2094 * }
2095 */
2096 if( ( ret = asn1_get_tag( &p, end, &len,
2097 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2098 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002099#if defined(POLARSSL_PEM_C)
2100 pem_free( &pem );
2101#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002102 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
2103 }
2104
2105 end = p + len;
2106
2107 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
2108 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
2109 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002110#if defined(POLARSSL_PEM_C)
2111 pem_free( &pem );
2112#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002113 dhm_free( dhm );
2114 return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
2115 }
2116
2117 if( p != end )
2118 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002119#if defined(POLARSSL_PEM_C)
2120 pem_free( &pem );
2121#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002122 dhm_free( dhm );
2123 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT |
2124 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
2125 }
2126
Paul Bakker96743fc2011-02-12 14:30:57 +00002127#if defined(POLARSSL_PEM_C)
2128 pem_free( &pem );
2129#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002130
2131 return( 0 );
2132}
2133
2134/*
2135 * Load and parse a private RSA key
2136 */
2137int x509parse_dhmfile( dhm_context *dhm, const char *path )
2138{
2139 int ret;
2140 size_t n;
2141 unsigned char *buf;
2142
2143 if ( load_file( path, &buf, &n ) )
2144 return( 1 );
2145
2146 ret = x509parse_dhm( dhm, buf, (int) n);
2147
2148 memset( buf, 0, n + 1 );
2149 free( buf );
2150
2151 return( ret );
2152}
2153
Paul Bakker5121ce52009-01-03 21:22:43 +00002154#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002155#include <stdarg.h>
2156
2157#if !defined vsnprintf
2158#define vsnprintf _vsnprintf
2159#endif // vsnprintf
2160
2161/*
2162 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2163 * Result value is not size of buffer needed, but -1 if no fit is possible.
2164 *
2165 * This fuction tries to 'fix' this by at least suggesting enlarging the
2166 * size by 20.
2167 */
2168int compat_snprintf(char *str, size_t size, const char *format, ...)
2169{
2170 va_list ap;
2171 int res = -1;
2172
2173 va_start( ap, format );
2174
2175 res = vsnprintf( str, size, format, ap );
2176
2177 va_end( ap );
2178
2179 // No quick fix possible
2180 if ( res < 0 )
2181 return( size + 20 );
2182
2183 return res;
2184}
2185
2186#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002187#endif
2188
Paul Bakkerd98030e2009-05-02 15:13:40 +00002189#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2190
2191#define SAFE_SNPRINTF() \
2192{ \
2193 if( ret == -1 ) \
2194 return( -1 ); \
2195 \
2196 if ( ret > n ) { \
2197 p[n - 1] = '\0'; \
2198 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2199 } \
2200 \
2201 n -= ret; \
2202 p += ret; \
2203}
2204
Paul Bakker5121ce52009-01-03 21:22:43 +00002205/*
2206 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002207 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002208 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002209int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002210{
Paul Bakkerd98030e2009-05-02 15:13:40 +00002211 int i, ret, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002212 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002213 const x509_name *name;
Paul Bakker5121ce52009-01-03 21:22:43 +00002214 char s[128], *p;
2215
2216 memset( s, 0, sizeof( s ) );
2217
2218 name = dn;
2219 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002220 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002221
2222 while( name != NULL )
2223 {
Paul Bakker74111d32011-01-15 16:57:55 +00002224 if( name != dn )
2225 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002226 ret = snprintf( p, n, ", " );
2227 SAFE_SNPRINTF();
2228 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002229
2230 if( memcmp( name->oid.p, OID_X520, 2 ) == 0 )
2231 {
2232 switch( name->oid.p[2] )
2233 {
2234 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002235 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002236
2237 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002238 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002239
2240 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002241 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002242
2243 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002244 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002245
2246 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002247 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002248
2249 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002250 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002251
2252 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002253 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002254 name->oid.p[2] );
2255 break;
2256 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002257 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002258 }
2259 else if( memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
2260 {
2261 switch( name->oid.p[8] )
2262 {
2263 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002264 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002265
2266 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002267 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002268 name->oid.p[8] );
2269 break;
2270 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002271 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002272 }
2273 else
Paul Bakker74111d32011-01-15 16:57:55 +00002274 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002275 ret = snprintf( p, n, "\?\?=" );
Paul Bakker74111d32011-01-15 16:57:55 +00002276 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002277 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002278
2279 for( i = 0; i < name->val.len; i++ )
2280 {
2281 if( i >= (int) sizeof( s ) - 1 )
2282 break;
2283
2284 c = name->val.p[i];
2285 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2286 s[i] = '?';
2287 else s[i] = c;
2288 }
2289 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002290 ret = snprintf( p, n, "%s", s );
2291 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002292 name = name->next;
2293 }
2294
Paul Bakkerd98030e2009-05-02 15:13:40 +00002295 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002296}
2297
2298/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002299 * Store the serial in printable form into buf; no more
2300 * than size characters will be written
2301 */
2302int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2303{
2304 int i, ret, nr, n;
2305 char *p;
2306
2307 p = buf;
2308 n = size;
2309
2310 nr = ( serial->len <= 32 )
2311 ? serial->len : 32;
2312
2313 for( i = 0; i < nr; i++ )
2314 {
2315 ret = snprintf( p, n, "%02X%s",
2316 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2317 SAFE_SNPRINTF();
2318 }
2319
2320 return( size - n );
2321}
2322
2323/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002324 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002325 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002326int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2327 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002328{
Paul Bakkerdd476992011-01-16 21:34:59 +00002329 int n, ret;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002330 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00002331
2332 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002333 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002334
Paul Bakkerd98030e2009-05-02 15:13:40 +00002335 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002336 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002337 SAFE_SNPRINTF();
2338 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002339 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002340 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002341
Paul Bakkerdd476992011-01-16 21:34:59 +00002342 ret = x509parse_serial_gets( p, n, &crt->serial);
2343 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002344
Paul Bakkerd98030e2009-05-02 15:13:40 +00002345 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2346 SAFE_SNPRINTF();
2347 ret = x509parse_dn_gets( p, n, &crt->issuer );
2348 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002349
Paul Bakkerd98030e2009-05-02 15:13:40 +00002350 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2351 SAFE_SNPRINTF();
2352 ret = x509parse_dn_gets( p, n, &crt->subject );
2353 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002354
Paul Bakkerd98030e2009-05-02 15:13:40 +00002355 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002356 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2357 crt->valid_from.year, crt->valid_from.mon,
2358 crt->valid_from.day, crt->valid_from.hour,
2359 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002360 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002361
Paul Bakkerd98030e2009-05-02 15:13:40 +00002362 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002363 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2364 crt->valid_to.year, crt->valid_to.mon,
2365 crt->valid_to.day, crt->valid_to.hour,
2366 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002367 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002368
Paul Bakkerd98030e2009-05-02 15:13:40 +00002369 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2370 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002371
Paul Bakker27d66162010-03-17 06:56:01 +00002372 switch( crt->sig_alg )
Paul Bakker5121ce52009-01-03 21:22:43 +00002373 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002374 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2375 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2376 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2377 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2378 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2379 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2380 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2381 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2382 default: ret = snprintf( p, n, "???" ); break;
2383 }
2384 SAFE_SNPRINTF();
2385
2386 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
2387 crt->rsa.N.n * (int) sizeof( unsigned long ) * 8 );
2388 SAFE_SNPRINTF();
2389
2390 return( size - n );
2391}
2392
Paul Bakker74111d32011-01-15 16:57:55 +00002393/* Compare a given OID string with an OID x509_buf * */
2394#define OID_CMP(oid_str, oid_buf) \
2395 ( ( OID_SIZE(oid_str) == (oid_buf)->len ) && \
2396 memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0)
2397
2398/*
2399 * Return an informational string describing the given OID
2400 */
2401const char *x509_oid_get_description( x509_buf *oid )
2402{
2403 if ( oid == NULL )
2404 return ( NULL );
2405
2406 else if( OID_CMP( OID_SERVER_AUTH, oid ) )
2407 return( STRING_SERVER_AUTH );
2408
2409 else if( OID_CMP( OID_CLIENT_AUTH, oid ) )
2410 return( STRING_CLIENT_AUTH );
2411
2412 else if( OID_CMP( OID_CODE_SIGNING, oid ) )
2413 return( STRING_CODE_SIGNING );
2414
2415 else if( OID_CMP( OID_EMAIL_PROTECTION, oid ) )
2416 return( STRING_EMAIL_PROTECTION );
2417
2418 else if( OID_CMP( OID_TIME_STAMPING, oid ) )
2419 return( STRING_TIME_STAMPING );
2420
2421 else if( OID_CMP( OID_OCSP_SIGNING, oid ) )
2422 return( STRING_OCSP_SIGNING );
2423
2424 return( NULL );
2425}
2426
2427/* Return the x.y.z.... style numeric string for the given OID */
2428int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2429{
2430 int ret, n, i;
2431 unsigned int value;
2432 char *p;
2433
2434 p = buf;
2435 n = size;
2436
2437 /* First byte contains first two dots */
2438 if( oid->len > 0 )
2439 {
2440 ret = snprintf( p, n, "%d.%d", oid->p[0]/40, oid->p[0]%40 );
2441 SAFE_SNPRINTF();
2442 }
2443
2444 /* TODO: value can overflow in value. */
2445 value = 0;
2446 for( i=1; i < oid->len; i++ )
2447 {
2448 value <<= 7;
2449 value += oid->p[i] & 0x7F;
2450
2451 if( !( oid->p[i] & 0x80 ) )
2452 {
2453 /* Last byte */
2454 ret = snprintf( p, n, ".%d", value );
2455 SAFE_SNPRINTF();
2456 value = 0;
2457 }
2458 }
2459
2460 return( size - n );
2461}
2462
Paul Bakkerd98030e2009-05-02 15:13:40 +00002463/*
2464 * Return an informational string about the CRL.
2465 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002466int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2467 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002468{
2469 int i, n, nr, ret;
2470 char *p;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002471 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002472
2473 p = buf;
2474 n = size;
2475
2476 ret = snprintf( p, n, "%sCRL version : %d",
2477 prefix, crl->version );
2478 SAFE_SNPRINTF();
2479
2480 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2481 SAFE_SNPRINTF();
2482 ret = x509parse_dn_gets( p, n, &crl->issuer );
2483 SAFE_SNPRINTF();
2484
2485 ret = snprintf( p, n, "\n%sthis update : " \
2486 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2487 crl->this_update.year, crl->this_update.mon,
2488 crl->this_update.day, crl->this_update.hour,
2489 crl->this_update.min, crl->this_update.sec );
2490 SAFE_SNPRINTF();
2491
2492 ret = snprintf( p, n, "\n%snext update : " \
2493 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2494 crl->next_update.year, crl->next_update.mon,
2495 crl->next_update.day, crl->next_update.hour,
2496 crl->next_update.min, crl->next_update.sec );
2497 SAFE_SNPRINTF();
2498
2499 entry = &crl->entry;
2500
2501 ret = snprintf( p, n, "\n%sRevoked certificates:",
2502 prefix );
2503 SAFE_SNPRINTF();
2504
Paul Bakker9be19372009-07-27 20:21:53 +00002505 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002506 {
2507 ret = snprintf( p, n, "\n%sserial number: ",
2508 prefix );
2509 SAFE_SNPRINTF();
2510
2511 nr = ( entry->serial.len <= 32 )
2512 ? entry->serial.len : 32;
2513
Paul Bakker74111d32011-01-15 16:57:55 +00002514 for( i = 0; i < nr; i++ )
2515 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002516 ret = snprintf( p, n, "%02X%s",
2517 entry->serial.p[i], ( i < nr - 1 ) ? ":" : "" );
2518 SAFE_SNPRINTF();
2519 }
2520
2521 ret = snprintf( p, n, " revocation date: " \
2522 "%04d-%02d-%02d %02d:%02d:%02d",
2523 entry->revocation_date.year, entry->revocation_date.mon,
2524 entry->revocation_date.day, entry->revocation_date.hour,
2525 entry->revocation_date.min, entry->revocation_date.sec );
2526 SAFE_SNPRINTF();
2527
2528 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002529 }
2530
Paul Bakkerd98030e2009-05-02 15:13:40 +00002531 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2532 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002533
Paul Bakker27d66162010-03-17 06:56:01 +00002534 switch( crl->sig_alg )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002535 {
2536 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2537 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2538 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2539 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2540 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2541 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2542 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2543 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2544 default: ret = snprintf( p, n, "???" ); break;
2545 }
2546 SAFE_SNPRINTF();
2547
Paul Bakker1e27bb22009-07-19 20:25:25 +00002548 ret = snprintf( p, n, "\n" );
2549 SAFE_SNPRINTF();
2550
Paul Bakkerd98030e2009-05-02 15:13:40 +00002551 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002552}
2553
2554/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00002555 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00002556 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002557int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00002558{
2559 struct tm *lt;
2560 time_t tt;
2561
2562 tt = time( NULL );
2563 lt = localtime( &tt );
2564
Paul Bakker40ea7de2009-05-03 10:18:48 +00002565 if( lt->tm_year > to->year - 1900 )
2566 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002567
Paul Bakker40ea7de2009-05-03 10:18:48 +00002568 if( lt->tm_year == to->year - 1900 &&
2569 lt->tm_mon > to->mon - 1 )
2570 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002571
Paul Bakker40ea7de2009-05-03 10:18:48 +00002572 if( lt->tm_year == to->year - 1900 &&
2573 lt->tm_mon == to->mon - 1 &&
2574 lt->tm_mday > to->day )
2575 return( 1 );
2576
Paul Bakkerb6194992011-01-16 21:40:22 +00002577 if( lt->tm_year == to->year - 1900 &&
2578 lt->tm_mon == to->mon - 1 &&
2579 lt->tm_mday == to->day &&
2580 lt->tm_hour > to->hour - 1)
2581 return( 1 );
2582
2583 if( lt->tm_year == to->year - 1900 &&
2584 lt->tm_mon == to->mon - 1 &&
2585 lt->tm_mday == to->day &&
2586 lt->tm_hour == to->hour - 1 &&
2587 lt->tm_min > to->min - 1 )
2588 return( 1 );
2589
2590 if( lt->tm_year == to->year - 1900 &&
2591 lt->tm_mon == to->mon - 1 &&
2592 lt->tm_mday == to->day &&
2593 lt->tm_hour == to->hour - 1 &&
2594 lt->tm_min == to->min - 1 &&
2595 lt->tm_sec > to->sec - 1 )
2596 return( 1 );
2597
Paul Bakker40ea7de2009-05-03 10:18:48 +00002598 return( 0 );
2599}
2600
2601/*
2602 * Return 1 if the certificate is revoked, or 0 otherwise.
2603 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002604int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002605{
Paul Bakkerff60ee62010-03-16 21:09:09 +00002606 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00002607
2608 while( cur != NULL && cur->serial.len != 0 )
2609 {
Paul Bakkera056efc2011-01-16 21:38:35 +00002610 if( crt->serial.len == cur->serial.len &&
2611 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002612 {
2613 if( x509parse_time_expired( &cur->revocation_date ) )
2614 return( 1 );
2615 }
2616
2617 cur = cur->next;
2618 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002619
2620 return( 0 );
2621}
2622
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002623/*
2624 * Wrapper for x509 hashes.
2625 *
Paul Bakker0f5f72e2011-01-18 14:58:55 +00002626 * \param out Buffer to receive the hash (Should be at least 64 bytes)
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002627 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002628static void x509_hash( const unsigned char *in, int len, int alg,
Paul Bakker5121ce52009-01-03 21:22:43 +00002629 unsigned char *out )
2630{
2631 switch( alg )
2632 {
Paul Bakker40e46942009-01-03 21:51:57 +00002633#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002634 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002635#endif
Paul Bakker40e46942009-01-03 21:51:57 +00002636#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002637 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002638#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002639#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002640 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002641#endif
2642#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002643 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002644#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00002645#if defined(POLARSSL_SHA2_C)
2646 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
2647 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
2648#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00002649#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002650 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
2651 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
2652#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002653 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002654 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002655 break;
2656 }
2657}
2658
2659/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00002660 * Check that the given certificate is valid accoring to the CRL.
2661 */
2662static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
2663 x509_crl *crl_list)
2664{
2665 int flags = 0;
2666 int hash_id;
2667 unsigned char hash[64];
2668
2669 /*
2670 * TODO: What happens if no CRL is present?
2671 * Suggestion: Revocation state should be unknown if no CRL is present.
2672 * For backwards compatibility this is not yet implemented.
2673 */
2674
2675 while( ca != NULL && crl_list != NULL && crl_list->version != 0 )
2676 {
2677 if( crl_list->issuer_raw.len != ca->subject_raw.len ||
2678 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
2679 crl_list->issuer_raw.len ) != 0 )
2680 {
2681 crl_list = crl_list->next;
2682 continue;
2683 }
2684
2685 /*
2686 * Check if CRL is correctly signed by the trusted CA
2687 */
2688 hash_id = crl_list->sig_alg;
2689
2690 x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
2691
2692 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, hash_id,
2693 0, hash, crl_list->sig.p ) == 0 )
2694 {
2695 /*
2696 * CRL is not trusted
2697 */
2698 flags |= BADCRL_NOT_TRUSTED;
2699 break;
2700 }
2701
2702 /*
2703 * Check for validity of CRL (Do not drop out)
2704 */
2705 if( x509parse_time_expired( &crl_list->next_update ) )
2706 flags |= BADCRL_EXPIRED;
2707
2708 /*
2709 * Check if certificate is revoked
2710 */
2711 if( x509parse_revoked(crt, crl_list) )
2712 {
2713 flags |= BADCERT_REVOKED;
2714 break;
2715 }
2716
2717 crl_list = crl_list->next;
2718 }
2719 return flags;
2720}
2721
2722/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002723 * Verify the certificate validity
2724 */
2725int x509parse_verify( x509_cert *crt,
2726 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00002727 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002728 const char *cn, int *flags,
2729 int (*f_vrfy)(void *, x509_cert *, int, int),
2730 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00002731{
2732 int cn_len;
2733 int hash_id;
2734 int pathlen;
Paul Bakker76fd75a2011-01-16 21:12:10 +00002735 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00002736 x509_name *name;
Paul Bakker4593aea2009-02-09 22:32:35 +00002737 unsigned char hash[64];
Paul Bakker5121ce52009-01-03 21:22:43 +00002738
Paul Bakker40ea7de2009-05-03 10:18:48 +00002739 *flags = 0;
2740
2741 if( x509parse_time_expired( &crt->valid_to ) )
2742 *flags = BADCERT_EXPIRED;
Paul Bakker5121ce52009-01-03 21:22:43 +00002743
2744 if( cn != NULL )
2745 {
2746 name = &crt->subject;
2747 cn_len = strlen( cn );
2748
2749 while( name != NULL )
2750 {
2751 if( memcmp( name->oid.p, OID_CN, 3 ) == 0 &&
2752 memcmp( name->val.p, cn, cn_len ) == 0 &&
2753 name->val.len == cn_len )
2754 break;
2755
2756 name = name->next;
2757 }
2758
2759 if( name == NULL )
2760 *flags |= BADCERT_CN_MISMATCH;
2761 }
2762
Paul Bakker5121ce52009-01-03 21:22:43 +00002763 /*
2764 * Iterate upwards in the given cert chain,
2765 * ignoring any upper cert with CA != TRUE.
2766 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00002767 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002768
2769 pathlen = 1;
2770
Paul Bakker76fd75a2011-01-16 21:12:10 +00002771 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002772 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002773 if( parent->ca_istrue == 0 ||
2774 crt->issuer_raw.len != parent->subject_raw.len ||
2775 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00002776 crt->issuer_raw.len ) != 0 )
2777 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002778 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002779 continue;
2780 }
2781
Paul Bakker27d66162010-03-17 06:56:01 +00002782 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00002783
2784 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2785
Paul Bakker76fd75a2011-01-16 21:12:10 +00002786 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, hash_id, 0, hash,
2787 crt->sig.p ) != 0 )
2788 *flags |= BADCERT_NOT_TRUSTED;
2789
2790 /* Check trusted CA's CRL for the given crt */
2791 *flags |= x509parse_verifycrl(crt, parent, ca_crl);
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002792
2793 /* crt is verified to be a child of the parent cur, call verify callback */
Paul Bakker74111d32011-01-15 16:57:55 +00002794 if( NULL != f_vrfy )
2795 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002796 if( f_vrfy( p_vrfy, crt, pathlen - 1, ( *flags == 0 ) ) != 0 )
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002797 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker76fd75a2011-01-16 21:12:10 +00002798 else
2799 *flags = 0;
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002800 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00002801 else if( *flags != 0 )
2802 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002803
2804 pathlen++;
2805
Paul Bakker76fd75a2011-01-16 21:12:10 +00002806 crt = parent;
2807 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002808 }
2809
2810 /*
Paul Bakker76fd75a2011-01-16 21:12:10 +00002811 * Attempt to validate topmost cert with our CA chain.
Paul Bakker5121ce52009-01-03 21:22:43 +00002812 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00002813 *flags |= BADCERT_NOT_TRUSTED;
2814
Paul Bakker7c6d4a42009-03-28 20:35:47 +00002815 while( trust_ca != NULL && trust_ca->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002816 {
2817 if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
2818 memcmp( crt->issuer_raw.p, trust_ca->subject_raw.p,
2819 crt->issuer_raw.len ) != 0 )
2820 {
2821 trust_ca = trust_ca->next;
2822 continue;
2823 }
2824
2825 if( trust_ca->max_pathlen > 0 &&
2826 trust_ca->max_pathlen < pathlen )
2827 break;
2828
Paul Bakker27d66162010-03-17 06:56:01 +00002829 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00002830
2831 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2832
2833 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
2834 0, hash, crt->sig.p ) == 0 )
2835 {
2836 /*
2837 * cert. is signed by a trusted CA
2838 */
2839 *flags &= ~BADCERT_NOT_TRUSTED;
2840 break;
2841 }
2842
2843 trust_ca = trust_ca->next;
2844 }
2845
Paul Bakker76fd75a2011-01-16 21:12:10 +00002846 /* Check trusted CA's CRL for the given crt */
2847 *flags |= x509parse_verifycrl( crt, trust_ca, ca_crl );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002848
2849 /* Verification succeeded, call callback on top cert */
Paul Bakker74111d32011-01-15 16:57:55 +00002850 if( NULL != f_vrfy )
2851 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002852 if( f_vrfy(p_vrfy, crt, pathlen-1, ( *flags == 0 ) ) != 0 )
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002853 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker76fd75a2011-01-16 21:12:10 +00002854 else
2855 *flags = 0;
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002856 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00002857 else if( *flags != 0 )
2858 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002859
Paul Bakker5121ce52009-01-03 21:22:43 +00002860 return( 0 );
2861}
2862
2863/*
2864 * Unallocate all certificate data
2865 */
2866void x509_free( x509_cert *crt )
2867{
2868 x509_cert *cert_cur = crt;
2869 x509_cert *cert_prv;
2870 x509_name *name_cur;
2871 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00002872 x509_sequence *seq_cur;
2873 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00002874
2875 if( crt == NULL )
2876 return;
2877
2878 do
2879 {
2880 rsa_free( &cert_cur->rsa );
2881
2882 name_cur = cert_cur->issuer.next;
2883 while( name_cur != NULL )
2884 {
2885 name_prv = name_cur;
2886 name_cur = name_cur->next;
2887 memset( name_prv, 0, sizeof( x509_name ) );
2888 free( name_prv );
2889 }
2890
2891 name_cur = cert_cur->subject.next;
2892 while( name_cur != NULL )
2893 {
2894 name_prv = name_cur;
2895 name_cur = name_cur->next;
2896 memset( name_prv, 0, sizeof( x509_name ) );
2897 free( name_prv );
2898 }
2899
Paul Bakker74111d32011-01-15 16:57:55 +00002900 seq_cur = cert_cur->ext_key_usage.next;
2901 while( seq_cur != NULL )
2902 {
2903 seq_prv = seq_cur;
2904 seq_cur = seq_cur->next;
2905 memset( seq_prv, 0, sizeof( x509_sequence ) );
2906 free( seq_prv );
2907 }
2908
Paul Bakker5121ce52009-01-03 21:22:43 +00002909 if( cert_cur->raw.p != NULL )
2910 {
2911 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
2912 free( cert_cur->raw.p );
2913 }
2914
2915 cert_cur = cert_cur->next;
2916 }
2917 while( cert_cur != NULL );
2918
2919 cert_cur = crt;
2920 do
2921 {
2922 cert_prv = cert_cur;
2923 cert_cur = cert_cur->next;
2924
2925 memset( cert_prv, 0, sizeof( x509_cert ) );
2926 if( cert_prv != crt )
2927 free( cert_prv );
2928 }
2929 while( cert_cur != NULL );
2930}
2931
Paul Bakkerd98030e2009-05-02 15:13:40 +00002932/*
2933 * Unallocate all CRL data
2934 */
2935void x509_crl_free( x509_crl *crl )
2936{
2937 x509_crl *crl_cur = crl;
2938 x509_crl *crl_prv;
2939 x509_name *name_cur;
2940 x509_name *name_prv;
2941 x509_crl_entry *entry_cur;
2942 x509_crl_entry *entry_prv;
2943
2944 if( crl == NULL )
2945 return;
2946
2947 do
2948 {
2949 name_cur = crl_cur->issuer.next;
2950 while( name_cur != NULL )
2951 {
2952 name_prv = name_cur;
2953 name_cur = name_cur->next;
2954 memset( name_prv, 0, sizeof( x509_name ) );
2955 free( name_prv );
2956 }
2957
2958 entry_cur = crl_cur->entry.next;
2959 while( entry_cur != NULL )
2960 {
2961 entry_prv = entry_cur;
2962 entry_cur = entry_cur->next;
2963 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
2964 free( entry_prv );
2965 }
2966
2967 if( crl_cur->raw.p != NULL )
2968 {
2969 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
2970 free( crl_cur->raw.p );
2971 }
2972
2973 crl_cur = crl_cur->next;
2974 }
2975 while( crl_cur != NULL );
2976
2977 crl_cur = crl;
2978 do
2979 {
2980 crl_prv = crl_cur;
2981 crl_cur = crl_cur->next;
2982
2983 memset( crl_prv, 0, sizeof( x509_crl ) );
2984 if( crl_prv != crl )
2985 free( crl_prv );
2986 }
2987 while( crl_cur != NULL );
2988}
2989
Paul Bakker40e46942009-01-03 21:51:57 +00002990#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002991
Paul Bakker40e46942009-01-03 21:51:57 +00002992#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00002993
2994/*
2995 * Checkup routine
2996 */
2997int x509_self_test( int verbose )
2998{
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002999#if defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003000 int ret, i, j;
3001 x509_cert cacert;
3002 x509_cert clicert;
3003 rsa_context rsa;
Paul Bakker1b57b062011-01-06 15:48:19 +00003004 dhm_context dhm;
Paul Bakker5121ce52009-01-03 21:22:43 +00003005
3006 if( verbose != 0 )
3007 printf( " X.509 certificate load: " );
3008
3009 memset( &clicert, 0, sizeof( x509_cert ) );
3010
3011 ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
3012 strlen( test_cli_crt ) );
3013 if( ret != 0 )
3014 {
3015 if( verbose != 0 )
3016 printf( "failed\n" );
3017
3018 return( ret );
3019 }
3020
3021 memset( &cacert, 0, sizeof( x509_cert ) );
3022
3023 ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
3024 strlen( test_ca_crt ) );
3025 if( ret != 0 )
3026 {
3027 if( verbose != 0 )
3028 printf( "failed\n" );
3029
3030 return( ret );
3031 }
3032
3033 if( verbose != 0 )
3034 printf( "passed\n X.509 private key load: " );
3035
3036 i = strlen( test_ca_key );
3037 j = strlen( test_ca_pwd );
3038
3039 if( ( ret = x509parse_key( &rsa,
3040 (unsigned char *) test_ca_key, i,
3041 (unsigned char *) test_ca_pwd, j ) ) != 0 )
3042 {
3043 if( verbose != 0 )
3044 printf( "failed\n" );
3045
3046 return( ret );
3047 }
3048
3049 if( verbose != 0 )
3050 printf( "passed\n X.509 signature verify: ");
3051
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003052 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &i, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003053 if( ret != 0 )
3054 {
Paul Bakker400ff6f2011-02-20 10:40:16 +00003055 printf("%02x", i);
Paul Bakker5121ce52009-01-03 21:22:43 +00003056 if( verbose != 0 )
3057 printf( "failed\n" );
3058
3059 return( ret );
3060 }
3061
3062 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003063 printf( "passed\n X.509 DHM parameter load: " );
3064
3065 i = strlen( test_dhm_params );
3066 j = strlen( test_ca_pwd );
3067
3068 if( ( ret = x509parse_dhm( &dhm, (unsigned char *) test_dhm_params, i ) ) != 0 )
3069 {
3070 if( verbose != 0 )
3071 printf( "failed\n" );
3072
3073 return( ret );
3074 }
3075
3076 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003077 printf( "passed\n\n" );
3078
3079 x509_free( &cacert );
3080 x509_free( &clicert );
3081 rsa_free( &rsa );
Paul Bakker1b57b062011-01-06 15:48:19 +00003082 dhm_free( &dhm );
Paul Bakker5121ce52009-01-03 21:22:43 +00003083
3084 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003085#else
3086 ((void) verbose);
3087 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3088#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003089}
3090
3091#endif
3092
3093#endif