blob: 9d0ebd29479c999ef166e206be528f03ec8c4b7a [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
Paul Bakkereaa89f82011-04-04 21:36:15 +00002052#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00002053/*
Paul Bakker1b57b062011-01-06 15:48:19 +00002054 * Parse DHM parameters
2055 */
2056int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, int dhminlen )
2057{
2058 int ret, len;
Paul Bakker1b57b062011-01-06 15:48:19 +00002059 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00002060#if defined(POLARSSL_PEM_C)
2061 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00002062
Paul Bakker96743fc2011-02-12 14:30:57 +00002063 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00002064
Paul Bakker96743fc2011-02-12 14:30:57 +00002065 ret = pem_read_buffer( &pem,
2066 "-----BEGIN DH PARAMETERS-----",
2067 "-----END DH PARAMETERS-----",
2068 dhmin, NULL, 0, &dhminlen );
2069
2070 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00002071 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002072 /*
2073 * Was PEM encoded
2074 */
2075 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00002076 }
Paul Bakker96743fc2011-02-12 14:30:57 +00002077 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00002078 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002079 pem_free( &pem );
2080 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002081 }
2082
Paul Bakker96743fc2011-02-12 14:30:57 +00002083 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
2084#else
2085 p = (unsigned char *) dhmin;
2086#endif
2087 end = p + dhminlen;
2088
Paul Bakker1b57b062011-01-06 15:48:19 +00002089 memset( dhm, 0, sizeof( dhm_context ) );
2090
Paul Bakker1b57b062011-01-06 15:48:19 +00002091 /*
2092 * DHParams ::= SEQUENCE {
2093 * prime INTEGER, -- P
2094 * generator INTEGER, -- g
2095 * }
2096 */
2097 if( ( ret = asn1_get_tag( &p, end, &len,
2098 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2099 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002100#if defined(POLARSSL_PEM_C)
2101 pem_free( &pem );
2102#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002103 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
2104 }
2105
2106 end = p + len;
2107
2108 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
2109 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
2110 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002111#if defined(POLARSSL_PEM_C)
2112 pem_free( &pem );
2113#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002114 dhm_free( dhm );
2115 return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
2116 }
2117
2118 if( p != end )
2119 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002120#if defined(POLARSSL_PEM_C)
2121 pem_free( &pem );
2122#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002123 dhm_free( dhm );
2124 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT |
2125 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
2126 }
2127
Paul Bakker96743fc2011-02-12 14:30:57 +00002128#if defined(POLARSSL_PEM_C)
2129 pem_free( &pem );
2130#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002131
2132 return( 0 );
2133}
2134
2135/*
2136 * Load and parse a private RSA key
2137 */
2138int x509parse_dhmfile( dhm_context *dhm, const char *path )
2139{
2140 int ret;
2141 size_t n;
2142 unsigned char *buf;
2143
2144 if ( load_file( path, &buf, &n ) )
2145 return( 1 );
2146
2147 ret = x509parse_dhm( dhm, buf, (int) n);
2148
2149 memset( buf, 0, n + 1 );
2150 free( buf );
2151
2152 return( ret );
2153}
Paul Bakkereaa89f82011-04-04 21:36:15 +00002154#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00002155
Paul Bakker5121ce52009-01-03 21:22:43 +00002156#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002157#include <stdarg.h>
2158
2159#if !defined vsnprintf
2160#define vsnprintf _vsnprintf
2161#endif // vsnprintf
2162
2163/*
2164 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2165 * Result value is not size of buffer needed, but -1 if no fit is possible.
2166 *
2167 * This fuction tries to 'fix' this by at least suggesting enlarging the
2168 * size by 20.
2169 */
2170int compat_snprintf(char *str, size_t size, const char *format, ...)
2171{
2172 va_list ap;
2173 int res = -1;
2174
2175 va_start( ap, format );
2176
2177 res = vsnprintf( str, size, format, ap );
2178
2179 va_end( ap );
2180
2181 // No quick fix possible
2182 if ( res < 0 )
2183 return( size + 20 );
2184
2185 return res;
2186}
2187
2188#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002189#endif
2190
Paul Bakkerd98030e2009-05-02 15:13:40 +00002191#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2192
2193#define SAFE_SNPRINTF() \
2194{ \
2195 if( ret == -1 ) \
2196 return( -1 ); \
2197 \
2198 if ( ret > n ) { \
2199 p[n - 1] = '\0'; \
2200 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2201 } \
2202 \
2203 n -= ret; \
2204 p += ret; \
2205}
2206
Paul Bakker5121ce52009-01-03 21:22:43 +00002207/*
2208 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002209 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002210 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002211int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002212{
Paul Bakkerd98030e2009-05-02 15:13:40 +00002213 int i, ret, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002214 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002215 const x509_name *name;
Paul Bakker5121ce52009-01-03 21:22:43 +00002216 char s[128], *p;
2217
2218 memset( s, 0, sizeof( s ) );
2219
2220 name = dn;
2221 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002222 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002223
2224 while( name != NULL )
2225 {
Paul Bakker74111d32011-01-15 16:57:55 +00002226 if( name != dn )
2227 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002228 ret = snprintf( p, n, ", " );
2229 SAFE_SNPRINTF();
2230 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002231
2232 if( memcmp( name->oid.p, OID_X520, 2 ) == 0 )
2233 {
2234 switch( name->oid.p[2] )
2235 {
2236 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002237 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002238
2239 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002240 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002241
2242 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002243 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002244
2245 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002246 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002247
2248 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002249 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002250
2251 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002252 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002253
2254 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002255 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002256 name->oid.p[2] );
2257 break;
2258 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002259 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002260 }
2261 else if( memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
2262 {
2263 switch( name->oid.p[8] )
2264 {
2265 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002266 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002267
2268 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002269 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002270 name->oid.p[8] );
2271 break;
2272 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002273 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002274 }
2275 else
Paul Bakker74111d32011-01-15 16:57:55 +00002276 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002277 ret = snprintf( p, n, "\?\?=" );
Paul Bakker74111d32011-01-15 16:57:55 +00002278 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002279 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002280
2281 for( i = 0; i < name->val.len; i++ )
2282 {
2283 if( i >= (int) sizeof( s ) - 1 )
2284 break;
2285
2286 c = name->val.p[i];
2287 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2288 s[i] = '?';
2289 else s[i] = c;
2290 }
2291 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002292 ret = snprintf( p, n, "%s", s );
2293 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002294 name = name->next;
2295 }
2296
Paul Bakkerd98030e2009-05-02 15:13:40 +00002297 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002298}
2299
2300/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002301 * Store the serial in printable form into buf; no more
2302 * than size characters will be written
2303 */
2304int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2305{
2306 int i, ret, nr, n;
2307 char *p;
2308
2309 p = buf;
2310 n = size;
2311
2312 nr = ( serial->len <= 32 )
2313 ? serial->len : 32;
2314
2315 for( i = 0; i < nr; i++ )
2316 {
2317 ret = snprintf( p, n, "%02X%s",
2318 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2319 SAFE_SNPRINTF();
2320 }
2321
2322 return( size - n );
2323}
2324
2325/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002326 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002327 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002328int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2329 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002330{
Paul Bakkerdd476992011-01-16 21:34:59 +00002331 int n, ret;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002332 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00002333
2334 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002335 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002336
Paul Bakkerd98030e2009-05-02 15:13:40 +00002337 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002338 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002339 SAFE_SNPRINTF();
2340 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002341 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002342 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002343
Paul Bakkerdd476992011-01-16 21:34:59 +00002344 ret = x509parse_serial_gets( p, n, &crt->serial);
2345 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002346
Paul Bakkerd98030e2009-05-02 15:13:40 +00002347 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2348 SAFE_SNPRINTF();
2349 ret = x509parse_dn_gets( p, n, &crt->issuer );
2350 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002351
Paul Bakkerd98030e2009-05-02 15:13:40 +00002352 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2353 SAFE_SNPRINTF();
2354 ret = x509parse_dn_gets( p, n, &crt->subject );
2355 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002356
Paul Bakkerd98030e2009-05-02 15:13:40 +00002357 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002358 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2359 crt->valid_from.year, crt->valid_from.mon,
2360 crt->valid_from.day, crt->valid_from.hour,
2361 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002362 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002363
Paul Bakkerd98030e2009-05-02 15:13:40 +00002364 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002365 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2366 crt->valid_to.year, crt->valid_to.mon,
2367 crt->valid_to.day, crt->valid_to.hour,
2368 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002369 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002370
Paul Bakkerd98030e2009-05-02 15:13:40 +00002371 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2372 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002373
Paul Bakker27d66162010-03-17 06:56:01 +00002374 switch( crt->sig_alg )
Paul Bakker5121ce52009-01-03 21:22:43 +00002375 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002376 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2377 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2378 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2379 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2380 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2381 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2382 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2383 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2384 default: ret = snprintf( p, n, "???" ); break;
2385 }
2386 SAFE_SNPRINTF();
2387
2388 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
2389 crt->rsa.N.n * (int) sizeof( unsigned long ) * 8 );
2390 SAFE_SNPRINTF();
2391
2392 return( size - n );
2393}
2394
Paul Bakker74111d32011-01-15 16:57:55 +00002395/* Compare a given OID string with an OID x509_buf * */
2396#define OID_CMP(oid_str, oid_buf) \
2397 ( ( OID_SIZE(oid_str) == (oid_buf)->len ) && \
2398 memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0)
2399
2400/*
2401 * Return an informational string describing the given OID
2402 */
2403const char *x509_oid_get_description( x509_buf *oid )
2404{
2405 if ( oid == NULL )
2406 return ( NULL );
2407
2408 else if( OID_CMP( OID_SERVER_AUTH, oid ) )
2409 return( STRING_SERVER_AUTH );
2410
2411 else if( OID_CMP( OID_CLIENT_AUTH, oid ) )
2412 return( STRING_CLIENT_AUTH );
2413
2414 else if( OID_CMP( OID_CODE_SIGNING, oid ) )
2415 return( STRING_CODE_SIGNING );
2416
2417 else if( OID_CMP( OID_EMAIL_PROTECTION, oid ) )
2418 return( STRING_EMAIL_PROTECTION );
2419
2420 else if( OID_CMP( OID_TIME_STAMPING, oid ) )
2421 return( STRING_TIME_STAMPING );
2422
2423 else if( OID_CMP( OID_OCSP_SIGNING, oid ) )
2424 return( STRING_OCSP_SIGNING );
2425
2426 return( NULL );
2427}
2428
2429/* Return the x.y.z.... style numeric string for the given OID */
2430int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2431{
2432 int ret, n, i;
2433 unsigned int value;
2434 char *p;
2435
2436 p = buf;
2437 n = size;
2438
2439 /* First byte contains first two dots */
2440 if( oid->len > 0 )
2441 {
2442 ret = snprintf( p, n, "%d.%d", oid->p[0]/40, oid->p[0]%40 );
2443 SAFE_SNPRINTF();
2444 }
2445
2446 /* TODO: value can overflow in value. */
2447 value = 0;
2448 for( i=1; i < oid->len; i++ )
2449 {
2450 value <<= 7;
2451 value += oid->p[i] & 0x7F;
2452
2453 if( !( oid->p[i] & 0x80 ) )
2454 {
2455 /* Last byte */
2456 ret = snprintf( p, n, ".%d", value );
2457 SAFE_SNPRINTF();
2458 value = 0;
2459 }
2460 }
2461
2462 return( size - n );
2463}
2464
Paul Bakkerd98030e2009-05-02 15:13:40 +00002465/*
2466 * Return an informational string about the CRL.
2467 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002468int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2469 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002470{
2471 int i, n, nr, ret;
2472 char *p;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002473 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002474
2475 p = buf;
2476 n = size;
2477
2478 ret = snprintf( p, n, "%sCRL version : %d",
2479 prefix, crl->version );
2480 SAFE_SNPRINTF();
2481
2482 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2483 SAFE_SNPRINTF();
2484 ret = x509parse_dn_gets( p, n, &crl->issuer );
2485 SAFE_SNPRINTF();
2486
2487 ret = snprintf( p, n, "\n%sthis update : " \
2488 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2489 crl->this_update.year, crl->this_update.mon,
2490 crl->this_update.day, crl->this_update.hour,
2491 crl->this_update.min, crl->this_update.sec );
2492 SAFE_SNPRINTF();
2493
2494 ret = snprintf( p, n, "\n%snext update : " \
2495 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2496 crl->next_update.year, crl->next_update.mon,
2497 crl->next_update.day, crl->next_update.hour,
2498 crl->next_update.min, crl->next_update.sec );
2499 SAFE_SNPRINTF();
2500
2501 entry = &crl->entry;
2502
2503 ret = snprintf( p, n, "\n%sRevoked certificates:",
2504 prefix );
2505 SAFE_SNPRINTF();
2506
Paul Bakker9be19372009-07-27 20:21:53 +00002507 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002508 {
2509 ret = snprintf( p, n, "\n%sserial number: ",
2510 prefix );
2511 SAFE_SNPRINTF();
2512
2513 nr = ( entry->serial.len <= 32 )
2514 ? entry->serial.len : 32;
2515
Paul Bakker74111d32011-01-15 16:57:55 +00002516 for( i = 0; i < nr; i++ )
2517 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002518 ret = snprintf( p, n, "%02X%s",
2519 entry->serial.p[i], ( i < nr - 1 ) ? ":" : "" );
2520 SAFE_SNPRINTF();
2521 }
2522
2523 ret = snprintf( p, n, " revocation date: " \
2524 "%04d-%02d-%02d %02d:%02d:%02d",
2525 entry->revocation_date.year, entry->revocation_date.mon,
2526 entry->revocation_date.day, entry->revocation_date.hour,
2527 entry->revocation_date.min, entry->revocation_date.sec );
2528 SAFE_SNPRINTF();
2529
2530 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002531 }
2532
Paul Bakkerd98030e2009-05-02 15:13:40 +00002533 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2534 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002535
Paul Bakker27d66162010-03-17 06:56:01 +00002536 switch( crl->sig_alg )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002537 {
2538 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2539 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2540 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2541 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2542 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2543 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2544 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2545 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2546 default: ret = snprintf( p, n, "???" ); break;
2547 }
2548 SAFE_SNPRINTF();
2549
Paul Bakker1e27bb22009-07-19 20:25:25 +00002550 ret = snprintf( p, n, "\n" );
2551 SAFE_SNPRINTF();
2552
Paul Bakkerd98030e2009-05-02 15:13:40 +00002553 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002554}
2555
2556/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00002557 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00002558 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002559int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00002560{
2561 struct tm *lt;
2562 time_t tt;
2563
2564 tt = time( NULL );
2565 lt = localtime( &tt );
2566
Paul Bakker40ea7de2009-05-03 10:18:48 +00002567 if( lt->tm_year > to->year - 1900 )
2568 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002569
Paul Bakker40ea7de2009-05-03 10:18:48 +00002570 if( lt->tm_year == to->year - 1900 &&
2571 lt->tm_mon > to->mon - 1 )
2572 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002573
Paul Bakker40ea7de2009-05-03 10:18:48 +00002574 if( lt->tm_year == to->year - 1900 &&
2575 lt->tm_mon == to->mon - 1 &&
2576 lt->tm_mday > to->day )
2577 return( 1 );
2578
Paul Bakkerb6194992011-01-16 21:40:22 +00002579 if( lt->tm_year == to->year - 1900 &&
2580 lt->tm_mon == to->mon - 1 &&
2581 lt->tm_mday == to->day &&
2582 lt->tm_hour > to->hour - 1)
2583 return( 1 );
2584
2585 if( lt->tm_year == to->year - 1900 &&
2586 lt->tm_mon == to->mon - 1 &&
2587 lt->tm_mday == to->day &&
2588 lt->tm_hour == to->hour - 1 &&
2589 lt->tm_min > to->min - 1 )
2590 return( 1 );
2591
2592 if( lt->tm_year == to->year - 1900 &&
2593 lt->tm_mon == to->mon - 1 &&
2594 lt->tm_mday == to->day &&
2595 lt->tm_hour == to->hour - 1 &&
2596 lt->tm_min == to->min - 1 &&
2597 lt->tm_sec > to->sec - 1 )
2598 return( 1 );
2599
Paul Bakker40ea7de2009-05-03 10:18:48 +00002600 return( 0 );
2601}
2602
2603/*
2604 * Return 1 if the certificate is revoked, or 0 otherwise.
2605 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002606int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002607{
Paul Bakkerff60ee62010-03-16 21:09:09 +00002608 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00002609
2610 while( cur != NULL && cur->serial.len != 0 )
2611 {
Paul Bakkera056efc2011-01-16 21:38:35 +00002612 if( crt->serial.len == cur->serial.len &&
2613 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002614 {
2615 if( x509parse_time_expired( &cur->revocation_date ) )
2616 return( 1 );
2617 }
2618
2619 cur = cur->next;
2620 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002621
2622 return( 0 );
2623}
2624
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002625/*
2626 * Wrapper for x509 hashes.
2627 *
Paul Bakker0f5f72e2011-01-18 14:58:55 +00002628 * \param out Buffer to receive the hash (Should be at least 64 bytes)
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002629 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002630static void x509_hash( const unsigned char *in, int len, int alg,
Paul Bakker5121ce52009-01-03 21:22:43 +00002631 unsigned char *out )
2632{
2633 switch( alg )
2634 {
Paul Bakker40e46942009-01-03 21:51:57 +00002635#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002636 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002637#endif
Paul Bakker40e46942009-01-03 21:51:57 +00002638#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002639 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002640#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002641#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002642 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002643#endif
2644#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002645 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002646#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00002647#if defined(POLARSSL_SHA2_C)
2648 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
2649 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
2650#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00002651#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002652 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
2653 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
2654#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002655 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002656 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002657 break;
2658 }
2659}
2660
2661/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00002662 * Check that the given certificate is valid accoring to the CRL.
2663 */
2664static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
2665 x509_crl *crl_list)
2666{
2667 int flags = 0;
2668 int hash_id;
2669 unsigned char hash[64];
2670
2671 /*
2672 * TODO: What happens if no CRL is present?
2673 * Suggestion: Revocation state should be unknown if no CRL is present.
2674 * For backwards compatibility this is not yet implemented.
2675 */
2676
2677 while( ca != NULL && crl_list != NULL && crl_list->version != 0 )
2678 {
2679 if( crl_list->issuer_raw.len != ca->subject_raw.len ||
2680 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
2681 crl_list->issuer_raw.len ) != 0 )
2682 {
2683 crl_list = crl_list->next;
2684 continue;
2685 }
2686
2687 /*
2688 * Check if CRL is correctly signed by the trusted CA
2689 */
2690 hash_id = crl_list->sig_alg;
2691
2692 x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
2693
2694 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, hash_id,
2695 0, hash, crl_list->sig.p ) == 0 )
2696 {
2697 /*
2698 * CRL is not trusted
2699 */
2700 flags |= BADCRL_NOT_TRUSTED;
2701 break;
2702 }
2703
2704 /*
2705 * Check for validity of CRL (Do not drop out)
2706 */
2707 if( x509parse_time_expired( &crl_list->next_update ) )
2708 flags |= BADCRL_EXPIRED;
2709
2710 /*
2711 * Check if certificate is revoked
2712 */
2713 if( x509parse_revoked(crt, crl_list) )
2714 {
2715 flags |= BADCERT_REVOKED;
2716 break;
2717 }
2718
2719 crl_list = crl_list->next;
2720 }
2721 return flags;
2722}
2723
2724/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002725 * Verify the certificate validity
2726 */
2727int x509parse_verify( x509_cert *crt,
2728 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00002729 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002730 const char *cn, int *flags,
2731 int (*f_vrfy)(void *, x509_cert *, int, int),
2732 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00002733{
2734 int cn_len;
2735 int hash_id;
2736 int pathlen;
Paul Bakker76fd75a2011-01-16 21:12:10 +00002737 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00002738 x509_name *name;
Paul Bakker4593aea2009-02-09 22:32:35 +00002739 unsigned char hash[64];
Paul Bakker5121ce52009-01-03 21:22:43 +00002740
Paul Bakker40ea7de2009-05-03 10:18:48 +00002741 *flags = 0;
2742
2743 if( x509parse_time_expired( &crt->valid_to ) )
2744 *flags = BADCERT_EXPIRED;
Paul Bakker5121ce52009-01-03 21:22:43 +00002745
2746 if( cn != NULL )
2747 {
2748 name = &crt->subject;
2749 cn_len = strlen( cn );
2750
2751 while( name != NULL )
2752 {
2753 if( memcmp( name->oid.p, OID_CN, 3 ) == 0 &&
2754 memcmp( name->val.p, cn, cn_len ) == 0 &&
2755 name->val.len == cn_len )
2756 break;
2757
2758 name = name->next;
2759 }
2760
2761 if( name == NULL )
2762 *flags |= BADCERT_CN_MISMATCH;
2763 }
2764
Paul Bakker5121ce52009-01-03 21:22:43 +00002765 /*
2766 * Iterate upwards in the given cert chain,
2767 * ignoring any upper cert with CA != TRUE.
2768 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00002769 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002770
2771 pathlen = 1;
2772
Paul Bakker76fd75a2011-01-16 21:12:10 +00002773 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002774 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002775 if( parent->ca_istrue == 0 ||
2776 crt->issuer_raw.len != parent->subject_raw.len ||
2777 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00002778 crt->issuer_raw.len ) != 0 )
2779 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002780 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002781 continue;
2782 }
2783
Paul Bakker27d66162010-03-17 06:56:01 +00002784 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00002785
2786 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2787
Paul Bakker76fd75a2011-01-16 21:12:10 +00002788 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, hash_id, 0, hash,
2789 crt->sig.p ) != 0 )
2790 *flags |= BADCERT_NOT_TRUSTED;
2791
2792 /* Check trusted CA's CRL for the given crt */
2793 *flags |= x509parse_verifycrl(crt, parent, ca_crl);
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002794
2795 /* crt is verified to be a child of the parent cur, call verify callback */
Paul Bakker74111d32011-01-15 16:57:55 +00002796 if( NULL != f_vrfy )
2797 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002798 if( f_vrfy( p_vrfy, crt, pathlen - 1, ( *flags == 0 ) ) != 0 )
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002799 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker76fd75a2011-01-16 21:12:10 +00002800 else
2801 *flags = 0;
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002802 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00002803 else if( *flags != 0 )
2804 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002805
2806 pathlen++;
2807
Paul Bakker76fd75a2011-01-16 21:12:10 +00002808 crt = parent;
2809 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002810 }
2811
2812 /*
Paul Bakker76fd75a2011-01-16 21:12:10 +00002813 * Attempt to validate topmost cert with our CA chain.
Paul Bakker5121ce52009-01-03 21:22:43 +00002814 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00002815 *flags |= BADCERT_NOT_TRUSTED;
2816
Paul Bakker7c6d4a42009-03-28 20:35:47 +00002817 while( trust_ca != NULL && trust_ca->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002818 {
2819 if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
2820 memcmp( crt->issuer_raw.p, trust_ca->subject_raw.p,
2821 crt->issuer_raw.len ) != 0 )
2822 {
2823 trust_ca = trust_ca->next;
2824 continue;
2825 }
2826
2827 if( trust_ca->max_pathlen > 0 &&
2828 trust_ca->max_pathlen < pathlen )
2829 break;
2830
Paul Bakker27d66162010-03-17 06:56:01 +00002831 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00002832
2833 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2834
2835 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
2836 0, hash, crt->sig.p ) == 0 )
2837 {
2838 /*
2839 * cert. is signed by a trusted CA
2840 */
2841 *flags &= ~BADCERT_NOT_TRUSTED;
2842 break;
2843 }
2844
2845 trust_ca = trust_ca->next;
2846 }
2847
Paul Bakker76fd75a2011-01-16 21:12:10 +00002848 /* Check trusted CA's CRL for the given crt */
2849 *flags |= x509parse_verifycrl( crt, trust_ca, ca_crl );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002850
2851 /* Verification succeeded, call callback on top cert */
Paul Bakker74111d32011-01-15 16:57:55 +00002852 if( NULL != f_vrfy )
2853 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002854 if( f_vrfy(p_vrfy, crt, pathlen-1, ( *flags == 0 ) ) != 0 )
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002855 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker76fd75a2011-01-16 21:12:10 +00002856 else
2857 *flags = 0;
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002858 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00002859 else if( *flags != 0 )
2860 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002861
Paul Bakker5121ce52009-01-03 21:22:43 +00002862 return( 0 );
2863}
2864
2865/*
2866 * Unallocate all certificate data
2867 */
2868void x509_free( x509_cert *crt )
2869{
2870 x509_cert *cert_cur = crt;
2871 x509_cert *cert_prv;
2872 x509_name *name_cur;
2873 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00002874 x509_sequence *seq_cur;
2875 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00002876
2877 if( crt == NULL )
2878 return;
2879
2880 do
2881 {
2882 rsa_free( &cert_cur->rsa );
2883
2884 name_cur = cert_cur->issuer.next;
2885 while( name_cur != NULL )
2886 {
2887 name_prv = name_cur;
2888 name_cur = name_cur->next;
2889 memset( name_prv, 0, sizeof( x509_name ) );
2890 free( name_prv );
2891 }
2892
2893 name_cur = cert_cur->subject.next;
2894 while( name_cur != NULL )
2895 {
2896 name_prv = name_cur;
2897 name_cur = name_cur->next;
2898 memset( name_prv, 0, sizeof( x509_name ) );
2899 free( name_prv );
2900 }
2901
Paul Bakker74111d32011-01-15 16:57:55 +00002902 seq_cur = cert_cur->ext_key_usage.next;
2903 while( seq_cur != NULL )
2904 {
2905 seq_prv = seq_cur;
2906 seq_cur = seq_cur->next;
2907 memset( seq_prv, 0, sizeof( x509_sequence ) );
2908 free( seq_prv );
2909 }
2910
Paul Bakker5121ce52009-01-03 21:22:43 +00002911 if( cert_cur->raw.p != NULL )
2912 {
2913 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
2914 free( cert_cur->raw.p );
2915 }
2916
2917 cert_cur = cert_cur->next;
2918 }
2919 while( cert_cur != NULL );
2920
2921 cert_cur = crt;
2922 do
2923 {
2924 cert_prv = cert_cur;
2925 cert_cur = cert_cur->next;
2926
2927 memset( cert_prv, 0, sizeof( x509_cert ) );
2928 if( cert_prv != crt )
2929 free( cert_prv );
2930 }
2931 while( cert_cur != NULL );
2932}
2933
Paul Bakkerd98030e2009-05-02 15:13:40 +00002934/*
2935 * Unallocate all CRL data
2936 */
2937void x509_crl_free( x509_crl *crl )
2938{
2939 x509_crl *crl_cur = crl;
2940 x509_crl *crl_prv;
2941 x509_name *name_cur;
2942 x509_name *name_prv;
2943 x509_crl_entry *entry_cur;
2944 x509_crl_entry *entry_prv;
2945
2946 if( crl == NULL )
2947 return;
2948
2949 do
2950 {
2951 name_cur = crl_cur->issuer.next;
2952 while( name_cur != NULL )
2953 {
2954 name_prv = name_cur;
2955 name_cur = name_cur->next;
2956 memset( name_prv, 0, sizeof( x509_name ) );
2957 free( name_prv );
2958 }
2959
2960 entry_cur = crl_cur->entry.next;
2961 while( entry_cur != NULL )
2962 {
2963 entry_prv = entry_cur;
2964 entry_cur = entry_cur->next;
2965 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
2966 free( entry_prv );
2967 }
2968
2969 if( crl_cur->raw.p != NULL )
2970 {
2971 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
2972 free( crl_cur->raw.p );
2973 }
2974
2975 crl_cur = crl_cur->next;
2976 }
2977 while( crl_cur != NULL );
2978
2979 crl_cur = crl;
2980 do
2981 {
2982 crl_prv = crl_cur;
2983 crl_cur = crl_cur->next;
2984
2985 memset( crl_prv, 0, sizeof( x509_crl ) );
2986 if( crl_prv != crl )
2987 free( crl_prv );
2988 }
2989 while( crl_cur != NULL );
2990}
2991
Paul Bakker40e46942009-01-03 21:51:57 +00002992#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002993
Paul Bakker40e46942009-01-03 21:51:57 +00002994#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00002995
2996/*
2997 * Checkup routine
2998 */
2999int x509_self_test( int verbose )
3000{
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003001#if defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003002 int ret, i, j;
3003 x509_cert cacert;
3004 x509_cert clicert;
3005 rsa_context rsa;
Paul Bakker1b57b062011-01-06 15:48:19 +00003006 dhm_context dhm;
Paul Bakker5121ce52009-01-03 21:22:43 +00003007
3008 if( verbose != 0 )
3009 printf( " X.509 certificate load: " );
3010
3011 memset( &clicert, 0, sizeof( x509_cert ) );
3012
3013 ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
3014 strlen( test_cli_crt ) );
3015 if( ret != 0 )
3016 {
3017 if( verbose != 0 )
3018 printf( "failed\n" );
3019
3020 return( ret );
3021 }
3022
3023 memset( &cacert, 0, sizeof( x509_cert ) );
3024
3025 ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
3026 strlen( test_ca_crt ) );
3027 if( ret != 0 )
3028 {
3029 if( verbose != 0 )
3030 printf( "failed\n" );
3031
3032 return( ret );
3033 }
3034
3035 if( verbose != 0 )
3036 printf( "passed\n X.509 private key load: " );
3037
3038 i = strlen( test_ca_key );
3039 j = strlen( test_ca_pwd );
3040
Paul Bakker66b78b22011-03-25 14:22:50 +00003041 rsa_init( &rsa, RSA_PKCS_V15, 0 );
3042
Paul Bakker5121ce52009-01-03 21:22:43 +00003043 if( ( ret = x509parse_key( &rsa,
3044 (unsigned char *) test_ca_key, i,
3045 (unsigned char *) test_ca_pwd, j ) ) != 0 )
3046 {
3047 if( verbose != 0 )
3048 printf( "failed\n" );
3049
3050 return( ret );
3051 }
3052
3053 if( verbose != 0 )
3054 printf( "passed\n X.509 signature verify: ");
3055
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003056 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &i, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003057 if( ret != 0 )
3058 {
Paul Bakker400ff6f2011-02-20 10:40:16 +00003059 printf("%02x", i);
Paul Bakker5121ce52009-01-03 21:22:43 +00003060 if( verbose != 0 )
3061 printf( "failed\n" );
3062
3063 return( ret );
3064 }
3065
3066 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003067 printf( "passed\n X.509 DHM parameter load: " );
3068
3069 i = strlen( test_dhm_params );
3070 j = strlen( test_ca_pwd );
3071
3072 if( ( ret = x509parse_dhm( &dhm, (unsigned char *) test_dhm_params, i ) ) != 0 )
3073 {
3074 if( verbose != 0 )
3075 printf( "failed\n" );
3076
3077 return( ret );
3078 }
3079
3080 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003081 printf( "passed\n\n" );
3082
3083 x509_free( &cacert );
3084 x509_free( &clicert );
3085 rsa_free( &rsa );
Paul Bakker1b57b062011-01-06 15:48:19 +00003086 dhm_free( &dhm );
Paul Bakker5121ce52009-01-03 21:22:43 +00003087
3088 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003089#else
3090 ((void) verbose);
3091 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3092#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003093}
3094
3095#endif
3096
3097#endif