blob: 31cfe34e89aaba2b963618b439061970b0b23656 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * X.509 certificate and private key decoding
3 *
Paul Bakker84f12b72010-07-18 10:13:04 +00004 * Copyright (C) 2006-2010, Brainspark B.V.
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
Paul Bakker84f12b72010-07-18 10:13:04 +00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakkerb96f1542010-07-18 20:36:00 +00008 *
Paul Bakker77b385e2009-07-28 17:23:11 +00009 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +000010 *
Paul Bakker5121ce52009-01-03 21:22:43 +000011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25/*
26 * The ITU-T X.509 standard defines a certificat format for PKI.
27 *
28 * http://www.ietf.org/rfc/rfc2459.txt
29 * http://www.ietf.org/rfc/rfc3279.txt
30 *
31 * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
32 *
33 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
34 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
35 */
36
Paul Bakker40e46942009-01-03 21:51:57 +000037#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000038
Paul Bakker40e46942009-01-03 21:51:57 +000039#if defined(POLARSSL_X509_PARSE_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000040
Paul Bakker40e46942009-01-03 21:51:57 +000041#include "polarssl/x509.h"
42#include "polarssl/base64.h"
43#include "polarssl/des.h"
44#include "polarssl/md2.h"
45#include "polarssl/md4.h"
46#include "polarssl/md5.h"
47#include "polarssl/sha1.h"
Paul Bakker026c03b2009-03-28 17:53:03 +000048#include "polarssl/sha2.h"
49#include "polarssl/sha4.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000050
51#include <string.h>
52#include <stdlib.h>
53#include <stdio.h>
54#include <time.h>
55
56/*
57 * ASN.1 DER decoding routines
58 */
59static int asn1_get_len( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +000060 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +000061 int *len )
62{
63 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +000064 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000065
66 if( ( **p & 0x80 ) == 0 )
67 *len = *(*p)++;
68 else
69 {
70 switch( **p & 0x7F )
71 {
72 case 1:
73 if( ( end - *p ) < 2 )
Paul Bakker40e46942009-01-03 21:51:57 +000074 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000075
76 *len = (*p)[1];
77 (*p) += 2;
78 break;
79
80 case 2:
81 if( ( end - *p ) < 3 )
Paul Bakker40e46942009-01-03 21:51:57 +000082 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000083
84 *len = ( (*p)[1] << 8 ) | (*p)[2];
85 (*p) += 3;
86 break;
87
88 default:
Paul Bakker40e46942009-01-03 21:51:57 +000089 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +000090 break;
91 }
92 }
93
94 if( *len > (int) ( end - *p ) )
Paul Bakker40e46942009-01-03 21:51:57 +000095 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000096
97 return( 0 );
98}
99
100static int asn1_get_tag( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000101 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000102 int *len, int tag )
103{
104 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000105 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000106
107 if( **p != tag )
Paul Bakker40e46942009-01-03 21:51:57 +0000108 return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000109
110 (*p)++;
111
112 return( asn1_get_len( p, end, len ) );
113}
114
115static int asn1_get_bool( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000116 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000117 int *val )
118{
119 int ret, len;
120
121 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 )
122 return( ret );
123
124 if( len != 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000125 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000126
127 *val = ( **p != 0 ) ? 1 : 0;
128 (*p)++;
129
130 return( 0 );
131}
132
133static int asn1_get_int( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000134 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000135 int *val )
136{
137 int ret, len;
138
139 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
140 return( ret );
141
142 if( len > (int) sizeof( int ) || ( **p & 0x80 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000143 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000144
145 *val = 0;
146
147 while( len-- > 0 )
148 {
149 *val = ( *val << 8 ) | **p;
150 (*p)++;
151 }
152
153 return( 0 );
154}
155
156static int asn1_get_mpi( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000157 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000158 mpi *X )
159{
160 int ret, len;
161
162 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
163 return( ret );
164
165 ret = mpi_read_binary( X, *p, len );
166
167 *p += len;
168
169 return( ret );
170}
171
172/*
173 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
174 */
175static int x509_get_version( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000176 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000177 int *ver )
178{
179 int ret, len;
180
181 if( ( ret = asn1_get_tag( p, end, &len,
182 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
183 {
Paul Bakker40e46942009-01-03 21:51:57 +0000184 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000185 return( *ver = 0 );
186
187 return( ret );
188 }
189
190 end = *p + len;
191
192 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000193 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000194
195 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000196 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION |
197 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000198
199 return( 0 );
200}
201
202/*
203 * CertificateSerialNumber ::= INTEGER
204 */
205static int x509_get_serial( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000206 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000207 x509_buf *serial )
208{
209 int ret;
210
211 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000212 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL |
213 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000214
215 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
216 **p != ASN1_INTEGER )
Paul Bakker40e46942009-01-03 21:51:57 +0000217 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL |
218 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000219
220 serial->tag = *(*p)++;
221
222 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000223 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000224
225 serial->p = *p;
226 *p += serial->len;
227
228 return( 0 );
229}
230
231/*
232 * AlgorithmIdentifier ::= SEQUENCE {
233 * algorithm OBJECT IDENTIFIER,
234 * parameters ANY DEFINED BY algorithm OPTIONAL }
235 */
236static int x509_get_alg( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000237 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000238 x509_buf *alg )
239{
240 int ret, len;
241
242 if( ( ret = asn1_get_tag( p, end, &len,
243 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000244 return( POLARSSL_ERR_X509_CERT_INVALID_ALG | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000245
246 end = *p + len;
247 alg->tag = **p;
248
249 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000250 return( POLARSSL_ERR_X509_CERT_INVALID_ALG | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000251
252 alg->p = *p;
253 *p += alg->len;
254
255 if( *p == end )
256 return( 0 );
257
258 /*
259 * assume the algorithm parameters must be NULL
260 */
261 if( ( ret = asn1_get_tag( p, end, &len, ASN1_NULL ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000262 return( POLARSSL_ERR_X509_CERT_INVALID_ALG | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000263
264 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000265 return( POLARSSL_ERR_X509_CERT_INVALID_ALG |
266 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000267
268 return( 0 );
269}
270
271/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000272 * AttributeTypeAndValue ::= SEQUENCE {
273 * type AttributeType,
274 * value AttributeValue }
275 *
276 * AttributeType ::= OBJECT IDENTIFIER
277 *
278 * AttributeValue ::= ANY DEFINED BY AttributeType
279 */
Paul Bakker02710262011-02-22 16:26:47 +0000280static int x509_get_attr_type_value( unsigned char **p,
281 const unsigned char *end,
282 x509_name *cur )
Paul Bakker5121ce52009-01-03 21:22:43 +0000283{
284 int ret, len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000285 x509_buf *oid;
286 x509_buf *val;
287
288 if( ( ret = asn1_get_tag( p, end, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000289 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000290 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000291
Paul Bakker5121ce52009-01-03 21:22:43 +0000292 oid = &cur->oid;
293 oid->tag = **p;
294
295 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000296 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000297
298 oid->p = *p;
299 *p += oid->len;
300
301 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000302 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
303 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000304
305 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
306 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
307 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker40e46942009-01-03 21:51:57 +0000308 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
309 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000310
311 val = &cur->val;
312 val->tag = *(*p)++;
313
314 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000315 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000316
317 val->p = *p;
318 *p += val->len;
319
320 cur->next = NULL;
321
Paul Bakker02710262011-02-22 16:26:47 +0000322 return( 0 );
323}
324
325/*
326 * RelativeDistinguishedName ::=
327 * SET OF AttributeTypeAndValue
328 *
329 * AttributeTypeAndValue ::= SEQUENCE {
330 * type AttributeType,
331 * value AttributeValue }
332 *
333 * AttributeType ::= OBJECT IDENTIFIER
334 *
335 * AttributeValue ::= ANY DEFINED BY AttributeType
336 */
337static int x509_get_name( unsigned char **p,
338 const unsigned char *end,
339 x509_name *cur )
340{
341 int ret, len;
342 const unsigned char *end2;
343 x509_name *use;
344
345 if( ( ret = asn1_get_tag( p, end, &len,
346 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
347 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
348
349 end2 = end;
350 end = *p + len;
351 use = cur;
352
353 do
354 {
355 if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
356 return( ret );
357
358 if( *p != end )
359 {
360 use->next = (x509_name *) malloc(
361 sizeof( x509_name ) );
362
363 if( use->next == NULL )
364 return( 1 );
365
366 memset( use->next, 0, sizeof( x509_name ) );
367
368 use = use->next;
369 }
370 }
371 while( *p != end );
Paul Bakker5121ce52009-01-03 21:22:43 +0000372
373 /*
374 * recurse until end of SEQUENCE is reached
375 */
376 if( *p == end2 )
377 return( 0 );
378
379 cur->next = (x509_name *) malloc(
380 sizeof( x509_name ) );
381
382 if( cur->next == NULL )
383 return( 1 );
384
385 return( x509_get_name( p, end2, cur->next ) );
386}
387
388/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000389 * Time ::= CHOICE {
390 * utcTime UTCTime,
391 * generalTime GeneralizedTime }
392 */
Paul Bakker91200182010-02-18 21:26:15 +0000393static int x509_get_time( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000394 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000395 x509_time *time )
396{
397 int ret, len;
398 char date[64];
Paul Bakker91200182010-02-18 21:26:15 +0000399 unsigned char tag;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000400
Paul Bakker91200182010-02-18 21:26:15 +0000401 if( ( end - *p ) < 1 )
402 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000403
Paul Bakker91200182010-02-18 21:26:15 +0000404 tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000405
Paul Bakker91200182010-02-18 21:26:15 +0000406 if ( tag == ASN1_UTC_TIME )
407 {
408 (*p)++;
409 ret = asn1_get_len( p, end, &len );
410
411 if( ret != 0 )
412 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000413
Paul Bakker91200182010-02-18 21:26:15 +0000414 memset( date, 0, sizeof( date ) );
415 memcpy( date, *p, ( len < (int) sizeof( date ) - 1 ) ?
416 len : (int) sizeof( date ) - 1 );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000417
Paul Bakker91200182010-02-18 21:26:15 +0000418 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
419 &time->year, &time->mon, &time->day,
420 &time->hour, &time->min, &time->sec ) < 5 )
421 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000422
Paul Bakker02710262011-02-22 16:26:47 +0000423 time->year += 100 * ( time->year < 50 );
Paul Bakker91200182010-02-18 21:26:15 +0000424 time->year += 1900;
425
426 *p += len;
427
428 return( 0 );
429 }
430 else if ( tag == ASN1_GENERALIZED_TIME )
431 {
432 (*p)++;
433 ret = asn1_get_len( p, end, &len );
434
435 if( ret != 0 )
436 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret );
437
438 memset( date, 0, sizeof( date ) );
439 memcpy( date, *p, ( len < (int) sizeof( date ) - 1 ) ?
440 len : (int) sizeof( date ) - 1 );
441
442 if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
443 &time->year, &time->mon, &time->day,
444 &time->hour, &time->min, &time->sec ) < 5 )
445 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
446
447 *p += len;
448
449 return( 0 );
450 }
451 else
452 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000453}
454
455
456/*
457 * Validity ::= SEQUENCE {
458 * notBefore Time,
459 * notAfter Time }
460 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000461static int x509_get_dates( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000462 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000463 x509_time *from,
464 x509_time *to )
465{
466 int ret, len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000467
468 if( ( ret = asn1_get_tag( p, end, &len,
469 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000470 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000471
472 end = *p + len;
473
Paul Bakker91200182010-02-18 21:26:15 +0000474 if( ( ret = x509_get_time( p, end, from ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000475 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000476
Paul Bakker91200182010-02-18 21:26:15 +0000477 if( ( ret = x509_get_time( p, end, to ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000478 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000479
480 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000481 return( POLARSSL_ERR_X509_CERT_INVALID_DATE |
482 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000483
484 return( 0 );
485}
486
487/*
488 * SubjectPublicKeyInfo ::= SEQUENCE {
489 * algorithm AlgorithmIdentifier,
490 * subjectPublicKey BIT STRING }
491 */
492static int x509_get_pubkey( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000493 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000494 x509_buf *pk_alg_oid,
495 mpi *N, mpi *E )
496{
Paul Bakker02710262011-02-22 16:26:47 +0000497 int ret, len, can_handle;
Paul Bakker5121ce52009-01-03 21:22:43 +0000498 unsigned char *end2;
499
500 if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 )
501 return( ret );
502
503 /*
504 * only RSA public keys handled at this time
505 */
Paul Bakker02710262011-02-22 16:26:47 +0000506 can_handle = 0;
507
508 if( pk_alg_oid->len == 9 &&
509 memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) == 0 )
510 can_handle = 1;
511
512 if( pk_alg_oid->len == 9 &&
513 memcmp( pk_alg_oid->p, OID_PKCS1, 8 ) == 0 )
514 {
515 if( pk_alg_oid->p[8] >= 2 && pk_alg_oid->p[8] <= 5 )
516 can_handle = 1;
517
518 if ( pk_alg_oid->p[8] >= 11 && pk_alg_oid->p[8] <= 14 )
519 can_handle = 1;
520 }
521
522 if( pk_alg_oid->len == 5 &&
523 memcmp( pk_alg_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
524 can_handle = 1;
525
526 if( can_handle == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000527 return( POLARSSL_ERR_X509_CERT_UNKNOWN_PK_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000528
529 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000530 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000531
532 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000533 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY |
534 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000535
536 end2 = *p + len;
537
538 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000539 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000540
541 /*
542 * RSAPublicKey ::= SEQUENCE {
543 * modulus INTEGER, -- n
544 * publicExponent INTEGER -- e
545 * }
546 */
547 if( ( ret = asn1_get_tag( p, end2, &len,
548 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000549 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000550
551 if( *p + len != end2 )
Paul Bakker40e46942009-01-03 21:51:57 +0000552 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY |
553 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000554
555 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
556 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000557 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000558
559 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000560 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY |
561 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000562
563 return( 0 );
564}
565
566static int x509_get_sig( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000567 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000568 x509_buf *sig )
569{
570 int ret, len;
571
572 sig->tag = **p;
573
574 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000575 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000576
577 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000578 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000579
580 sig->len = len;
581 sig->p = *p;
582
583 *p += len;
584
585 return( 0 );
586}
587
588/*
589 * X.509 v2/v3 unique identifier (not parsed)
590 */
591static int x509_get_uid( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000592 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000593 x509_buf *uid, int n )
594{
595 int ret;
596
597 if( *p == end )
598 return( 0 );
599
600 uid->tag = **p;
601
602 if( ( ret = asn1_get_tag( p, end, &uid->len,
603 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
604 {
Paul Bakker40e46942009-01-03 21:51:57 +0000605 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000606 return( 0 );
607
608 return( ret );
609 }
610
611 uid->p = *p;
612 *p += uid->len;
613
614 return( 0 );
615}
616
617/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000618 * X.509 Extensions (No parsing of extensions, pointer should
619 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000620 */
621static int x509_get_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000622 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000623 x509_buf *ext )
Paul Bakker5121ce52009-01-03 21:22:43 +0000624{
625 int ret, len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000626
627 if( *p == end )
628 return( 0 );
629
630 ext->tag = **p;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000631
Paul Bakker5121ce52009-01-03 21:22:43 +0000632 if( ( ret = asn1_get_tag( p, end, &ext->len,
633 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000634 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000635
636 ext->p = *p;
637 end = *p + ext->len;
638
639 /*
640 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
641 *
642 * Extension ::= SEQUENCE {
643 * extnID OBJECT IDENTIFIER,
644 * critical BOOLEAN DEFAULT FALSE,
645 * extnValue OCTET STRING }
646 */
647 if( ( ret = asn1_get_tag( p, end, &len,
648 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000649 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000650
651 if( end != *p + len )
Paul Bakker40e46942009-01-03 21:51:57 +0000652 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
653 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000654
Paul Bakkerd98030e2009-05-02 15:13:40 +0000655 return( 0 );
656}
657
658/*
659 * X.509 CRL v2 extensions (no extensions parsed yet.)
660 */
661static int x509_get_crl_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000662 const unsigned char *end,
663 x509_buf *ext )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000664{
665 int ret, len;
666
667 if( ( ret = x509_get_ext( p, end, ext ) ) != 0 )
668 {
669 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
670 return( 0 );
671
672 return( ret );
673 }
674
675 while( *p < end )
676 {
677 if( ( ret = asn1_get_tag( p, end, &len,
678 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
679 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
680
681 *p += len;
682 }
683
684 if( *p != end )
685 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
686 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
687
688 return( 0 );
689}
690
691/*
692 * X.509 v3 extensions (only BasicConstraints are parsed)
693 */
694static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000695 const unsigned char *end,
696 x509_buf *ext,
697 int *ca_istrue,
698 int *max_pathlen )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000699{
700 int ret, len;
701 int is_critical = 1;
702 int is_cacert = 0;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000703 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000704
705 if( ( ret = x509_get_ext( p, end, ext ) ) != 0 )
706 {
707 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
708 return( 0 );
709
710 return( ret );
711 }
712
Paul Bakker5121ce52009-01-03 21:22:43 +0000713 while( *p < end )
714 {
715 if( ( ret = asn1_get_tag( p, end, &len,
716 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000717 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000718
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000719 end_ext_data = *p + len;
720
Paul Bakker5121ce52009-01-03 21:22:43 +0000721 if( memcmp( *p, "\x06\x03\x55\x1D\x13", 5 ) != 0 )
722 {
723 *p += len;
724 continue;
725 }
726
727 *p += 5;
728
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000729 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000730 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
731 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000732
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000733 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000734 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000735 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000736
737 /*
738 * BasicConstraints ::= SEQUENCE {
739 * cA BOOLEAN DEFAULT FALSE,
740 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
741 */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000742 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000743
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000744 if( end_ext_octet != end_ext_data )
745 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
746 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000747
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000748 if( ( ret = asn1_get_tag( p, end_ext_octet, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000749 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000750 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000751
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000752 if( *p == end_ext_octet )
Paul Bakker5121ce52009-01-03 21:22:43 +0000753 continue;
754
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000755 if( ( ret = asn1_get_bool( p, end_ext_octet, &is_cacert ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000756 {
Paul Bakker40e46942009-01-03 21:51:57 +0000757 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000758 ret = asn1_get_int( p, end_ext_octet, &is_cacert );
Paul Bakker5121ce52009-01-03 21:22:43 +0000759
760 if( ret != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000761 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000762
763 if( is_cacert != 0 )
764 is_cacert = 1;
765 }
766
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000767 if( *p == end_ext_octet )
Paul Bakker5121ce52009-01-03 21:22:43 +0000768 continue;
769
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000770 if( ( ret = asn1_get_int( p, end_ext_octet, max_pathlen ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000771 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000772
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000773 if( *p != end_ext_octet )
Paul Bakker40e46942009-01-03 21:51:57 +0000774 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
775 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000776
777 max_pathlen++;
778 }
779
780 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000781 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
782 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000783
784 *ca_istrue = is_critical & is_cacert;
785
786 return( 0 );
787}
788
789/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000790 * X.509 CRL Entries
791 */
792static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000793 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000794 x509_crl_entry *entry )
795{
Paul Bakker9be19372009-07-27 20:21:53 +0000796 int ret, entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000797 x509_crl_entry *cur_entry = entry;
798
799 if( *p == end )
800 return( 0 );
801
Paul Bakker9be19372009-07-27 20:21:53 +0000802 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000803 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
804 {
805 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
806 return( 0 );
807
808 return( ret );
809 }
810
Paul Bakker9be19372009-07-27 20:21:53 +0000811 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000812
813 while( *p < end )
814 {
815 int len2;
816
817 if( ( ret = asn1_get_tag( p, end, &len2,
818 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
819 {
Paul Bakkerd98030e2009-05-02 15:13:40 +0000820 return( ret );
821 }
822
Paul Bakker9be19372009-07-27 20:21:53 +0000823 cur_entry->raw.tag = **p;
824 cur_entry->raw.p = *p;
825 cur_entry->raw.len = len2;
826
Paul Bakkerd98030e2009-05-02 15:13:40 +0000827 if( ( ret = x509_get_serial( p, end, &cur_entry->serial ) ) != 0 )
828 return( ret );
829
Paul Bakker91200182010-02-18 21:26:15 +0000830 if( ( ret = x509_get_time( p, end, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000831 return( ret );
832
833 if( ( ret = x509_get_crl_ext( p, end, &cur_entry->entry_ext ) ) != 0 )
834 return( ret );
835
836 if ( *p < end ) {
837 cur_entry->next = malloc( sizeof( x509_crl_entry ) );
838 cur_entry = cur_entry->next;
839 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
840 }
841 }
842
843 return( 0 );
844}
845
Paul Bakker27d66162010-03-17 06:56:01 +0000846static int x509_get_sig_alg( const x509_buf *sig_oid, int *sig_alg )
847{
848 if( sig_oid->len == 9 &&
849 memcmp( sig_oid->p, OID_PKCS1, 8 ) == 0 )
850 {
851 if( sig_oid->p[8] >= 2 && sig_oid->p[8] <= 5 )
852 {
853 *sig_alg = sig_oid->p[8];
854 return( 0 );
855 }
856
857 if ( sig_oid->p[8] >= 11 && sig_oid->p[8] <= 14 )
858 {
859 *sig_alg = sig_oid->p[8];
860 return( 0 );
861 }
862
863 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
864 }
Paul Bakker02710262011-02-22 16:26:47 +0000865 if( sig_oid->len == 5 &&
866 memcmp( sig_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
867 {
868 *sig_alg = SIG_RSA_SHA1;
869 return( 0 );
870 }
Paul Bakker27d66162010-03-17 06:56:01 +0000871
872 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
873}
874
Paul Bakkerd98030e2009-05-02 15:13:40 +0000875/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000876 * Parse one or more certificates and add them to the chained list
877 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000878int x509parse_crt( x509_cert *chain, const unsigned char *buf, int buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000879{
880 int ret, len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000881 const unsigned char *s1, *s2;
Paul Bakker5121ce52009-01-03 21:22:43 +0000882 unsigned char *p, *end;
883 x509_cert *crt;
884
885 crt = chain;
886
Paul Bakker320a4b52009-03-28 18:52:39 +0000887 /*
888 * Check for valid input
889 */
890 if( crt == NULL || buf == NULL )
891 return( 1 );
892
Paul Bakkere9581d62009-03-28 20:29:25 +0000893 while( crt->version != 0 && crt->next != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +0000894 crt = crt->next;
895
896 /*
Paul Bakker320a4b52009-03-28 18:52:39 +0000897 * Add new certificate on the end of the chain if needed.
898 */
Paul Bakkere9581d62009-03-28 20:29:25 +0000899 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +0000900 {
901 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
902
Paul Bakker7d06ad22009-05-02 15:53:56 +0000903 if( crt->next == NULL )
904 {
Paul Bakker320a4b52009-03-28 18:52:39 +0000905 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +0000906 return( 1 );
907 }
Paul Bakker320a4b52009-03-28 18:52:39 +0000908
Paul Bakker7d06ad22009-05-02 15:53:56 +0000909 crt = crt->next;
910 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +0000911 }
912
913 /*
Paul Bakker5121ce52009-01-03 21:22:43 +0000914 * check if the certificate is encoded in base64
915 */
916 s1 = (unsigned char *) strstr( (char *) buf,
917 "-----BEGIN CERTIFICATE-----" );
918
919 if( s1 != NULL )
920 {
921 s2 = (unsigned char *) strstr( (char *) buf,
922 "-----END CERTIFICATE-----" );
923
924 if( s2 == NULL || s2 <= s1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000925 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +0000926
927 s1 += 27;
928 if( *s1 == '\r' ) s1++;
929 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +0000930 else return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +0000931
932 /*
933 * get the DER data length and decode the buffer
934 */
935 len = 0;
936 ret = base64_decode( NULL, &len, s1, s2 - s1 );
937
Paul Bakker40e46942009-01-03 21:51:57 +0000938 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
939 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000940
941 if( ( p = (unsigned char *) malloc( len ) ) == NULL )
942 return( 1 );
943
944 if( ( ret = base64_decode( p, &len, s1, s2 - s1 ) ) != 0 )
945 {
946 free( p );
Paul Bakker40e46942009-01-03 21:51:57 +0000947 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000948 }
949
950 /*
951 * update the buffer size and offset
952 */
953 s2 += 25;
954 if( *s2 == '\r' ) s2++;
955 if( *s2 == '\n' ) s2++;
956 else
957 {
958 free( p );
Paul Bakker40e46942009-01-03 21:51:57 +0000959 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +0000960 }
961
962 buflen -= s2 - buf;
963 buf = s2;
964 }
965 else
966 {
967 /*
968 * nope, copy the raw DER data
969 */
970 p = (unsigned char *) malloc( len = buflen );
971
972 if( p == NULL )
973 return( 1 );
974
975 memcpy( p, buf, buflen );
976
977 buflen = 0;
978 }
979
980 crt->raw.p = p;
981 crt->raw.len = len;
982 end = p + len;
983
984 /*
985 * Certificate ::= SEQUENCE {
986 * tbsCertificate TBSCertificate,
987 * signatureAlgorithm AlgorithmIdentifier,
988 * signatureValue BIT STRING }
989 */
990 if( ( ret = asn1_get_tag( &p, end, &len,
991 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
992 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000993 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000994 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +0000995 }
996
997 if( len != (int) ( end - p ) )
998 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000999 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001000 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1001 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001002 }
1003
1004 /*
1005 * TBSCertificate ::= SEQUENCE {
1006 */
1007 crt->tbs.p = p;
1008
1009 if( ( ret = asn1_get_tag( &p, end, &len,
1010 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1011 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001012 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001013 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001014 }
1015
1016 end = p + len;
1017 crt->tbs.len = end - crt->tbs.p;
1018
1019 /*
1020 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1021 *
1022 * CertificateSerialNumber ::= INTEGER
1023 *
1024 * signature AlgorithmIdentifier
1025 */
1026 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1027 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1028 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
1029 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001030 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001031 return( ret );
1032 }
1033
1034 crt->version++;
1035
1036 if( crt->version > 3 )
1037 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001038 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001039 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001040 }
1041
Paul Bakker27d66162010-03-17 06:56:01 +00001042 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_alg ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001043 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001044 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001045 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001046 }
1047
1048 /*
1049 * issuer Name
1050 */
1051 crt->issuer_raw.p = p;
1052
1053 if( ( ret = asn1_get_tag( &p, end, &len,
1054 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1055 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001056 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001057 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001058 }
1059
1060 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1061 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001062 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001063 return( ret );
1064 }
1065
1066 crt->issuer_raw.len = p - crt->issuer_raw.p;
1067
1068 /*
1069 * Validity ::= SEQUENCE {
1070 * notBefore Time,
1071 * notAfter Time }
1072 *
1073 */
1074 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1075 &crt->valid_to ) ) != 0 )
1076 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001077 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001078 return( ret );
1079 }
1080
1081 /*
1082 * subject Name
1083 */
1084 crt->subject_raw.p = p;
1085
1086 if( ( ret = asn1_get_tag( &p, end, &len,
1087 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1088 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001089 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001090 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001091 }
1092
1093 if( ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
1094 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001095 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001096 return( ret );
1097 }
1098
1099 crt->subject_raw.len = p - crt->subject_raw.p;
1100
1101 /*
1102 * SubjectPublicKeyInfo ::= SEQUENCE
1103 * algorithm AlgorithmIdentifier,
1104 * subjectPublicKey BIT STRING }
1105 */
1106 if( ( ret = asn1_get_tag( &p, end, &len,
1107 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1108 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001109 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001110 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001111 }
1112
1113 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1114 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1115 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001116 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001117 return( ret );
1118 }
1119
1120 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1121 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001122 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001123 return( ret );
1124 }
1125
1126 crt->rsa.len = mpi_size( &crt->rsa.N );
1127
1128 /*
1129 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1130 * -- If present, version shall be v2 or v3
1131 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1132 * -- If present, version shall be v2 or v3
1133 * extensions [3] EXPLICIT Extensions OPTIONAL
1134 * -- If present, version shall be v3
1135 */
1136 if( crt->version == 2 || crt->version == 3 )
1137 {
1138 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1139 if( ret != 0 )
1140 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001141 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001142 return( ret );
1143 }
1144 }
1145
1146 if( crt->version == 2 || crt->version == 3 )
1147 {
1148 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1149 if( ret != 0 )
1150 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001151 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001152 return( ret );
1153 }
1154 }
1155
1156 if( crt->version == 3 )
1157 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001158 ret = x509_get_crt_ext( &p, end, &crt->v3_ext,
Paul Bakker5121ce52009-01-03 21:22:43 +00001159 &crt->ca_istrue, &crt->max_pathlen );
1160 if( ret != 0 )
1161 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001162 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001163 return( ret );
1164 }
1165 }
1166
1167 if( p != end )
1168 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001169 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001170 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1171 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001172 }
1173
1174 end = crt->raw.p + crt->raw.len;
1175
1176 /*
1177 * signatureAlgorithm AlgorithmIdentifier,
1178 * signatureValue BIT STRING
1179 */
1180 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1181 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001182 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001183 return( ret );
1184 }
1185
Paul Bakker320a4b52009-03-28 18:52:39 +00001186 if( memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001187 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001188 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001189 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001190 }
1191
1192 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1193 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001194 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001195 return( ret );
1196 }
1197
1198 if( p != end )
1199 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001200 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001201 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1202 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001203 }
1204
Paul Bakker5121ce52009-01-03 21:22:43 +00001205 if( buflen > 0 )
Paul Bakker320a4b52009-03-28 18:52:39 +00001206 {
1207 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1208
Paul Bakker7d06ad22009-05-02 15:53:56 +00001209 if( crt->next == NULL )
1210 {
Paul Bakker320a4b52009-03-28 18:52:39 +00001211 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001212 return( 1 );
1213 }
Paul Bakker320a4b52009-03-28 18:52:39 +00001214
Paul Bakker7d06ad22009-05-02 15:53:56 +00001215 crt = crt->next;
1216 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001217
Paul Bakker5121ce52009-01-03 21:22:43 +00001218 return( x509parse_crt( crt, buf, buflen ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001219 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001220
1221 return( 0 );
1222}
1223
1224/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001225 * Parse one or more CRLs and add them to the chained list
1226 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001227int x509parse_crl( x509_crl *chain, const unsigned char *buf, int buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001228{
1229 int ret, len;
1230 unsigned char *s1, *s2;
1231 unsigned char *p, *end;
1232 x509_crl *crl;
1233
1234 crl = chain;
1235
1236 /*
1237 * Check for valid input
1238 */
1239 if( crl == NULL || buf == NULL )
1240 return( 1 );
1241
1242 while( crl->version != 0 && crl->next != NULL )
1243 crl = crl->next;
1244
1245 /*
1246 * Add new CRL on the end of the chain if needed.
1247 */
1248 if ( crl->version != 0 && crl->next == NULL)
1249 {
1250 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1251
Paul Bakker7d06ad22009-05-02 15:53:56 +00001252 if( crl->next == NULL )
1253 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001254 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001255 return( 1 );
1256 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001257
Paul Bakker7d06ad22009-05-02 15:53:56 +00001258 crl = crl->next;
1259 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001260 }
1261
1262 /*
1263 * check if the CRL is encoded in base64
1264 */
1265 s1 = (unsigned char *) strstr( (char *) buf,
1266 "-----BEGIN X509 CRL-----" );
1267
1268 if( s1 != NULL )
1269 {
1270 s2 = (unsigned char *) strstr( (char *) buf,
1271 "-----END X509 CRL-----" );
1272
1273 if( s2 == NULL || s2 <= s1 )
1274 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1275
1276 s1 += 24;
1277 if( *s1 == '\r' ) s1++;
1278 if( *s1 == '\n' ) s1++;
1279 else return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1280
1281 /*
1282 * get the DER data length and decode the buffer
1283 */
1284 len = 0;
1285 ret = base64_decode( NULL, &len, s1, s2 - s1 );
1286
1287 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
1288 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
1289
1290 if( ( p = (unsigned char *) malloc( len ) ) == NULL )
1291 return( 1 );
1292
1293 if( ( ret = base64_decode( p, &len, s1, s2 - s1 ) ) != 0 )
1294 {
1295 free( p );
1296 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
1297 }
1298
1299 /*
1300 * update the buffer size and offset
1301 */
1302 s2 += 22;
1303 if( *s2 == '\r' ) s2++;
1304 if( *s2 == '\n' ) s2++;
1305 else
1306 {
1307 free( p );
1308 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1309 }
1310
1311 buflen -= s2 - buf;
1312 buf = s2;
1313 }
1314 else
1315 {
1316 /*
1317 * nope, copy the raw DER data
1318 */
1319 p = (unsigned char *) malloc( len = buflen );
1320
1321 if( p == NULL )
1322 return( 1 );
1323
1324 memcpy( p, buf, buflen );
1325
1326 buflen = 0;
1327 }
1328
1329 crl->raw.p = p;
1330 crl->raw.len = len;
1331 end = p + len;
1332
1333 /*
1334 * CertificateList ::= SEQUENCE {
1335 * tbsCertList TBSCertList,
1336 * signatureAlgorithm AlgorithmIdentifier,
1337 * signatureValue BIT STRING }
1338 */
1339 if( ( ret = asn1_get_tag( &p, end, &len,
1340 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1341 {
1342 x509_crl_free( crl );
1343 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1344 }
1345
1346 if( len != (int) ( end - p ) )
1347 {
1348 x509_crl_free( crl );
1349 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1350 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1351 }
1352
1353 /*
1354 * TBSCertList ::= SEQUENCE {
1355 */
1356 crl->tbs.p = p;
1357
1358 if( ( ret = asn1_get_tag( &p, end, &len,
1359 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1360 {
1361 x509_crl_free( crl );
1362 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
1363 }
1364
1365 end = p + len;
1366 crl->tbs.len = end - crl->tbs.p;
1367
1368 /*
1369 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1370 * -- if present, MUST be v2
1371 *
1372 * signature AlgorithmIdentifier
1373 */
1374 if( ( ret = x509_get_version( &p, end, &crl->version ) ) != 0 ||
1375 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1376 {
1377 x509_crl_free( crl );
1378 return( ret );
1379 }
1380
1381 crl->version++;
1382
1383 if( crl->version > 2 )
1384 {
1385 x509_crl_free( crl );
1386 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1387 }
1388
Paul Bakker27d66162010-03-17 06:56:01 +00001389 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_alg ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001390 {
1391 x509_crl_free( crl );
1392 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1393 }
1394
1395 /*
1396 * issuer Name
1397 */
1398 crl->issuer_raw.p = p;
1399
1400 if( ( ret = asn1_get_tag( &p, end, &len,
1401 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1402 {
1403 x509_crl_free( crl );
1404 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
1405 }
1406
1407 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1408 {
1409 x509_crl_free( crl );
1410 return( ret );
1411 }
1412
1413 crl->issuer_raw.len = p - crl->issuer_raw.p;
1414
1415 /*
1416 * thisUpdate Time
1417 * nextUpdate Time OPTIONAL
1418 */
Paul Bakker91200182010-02-18 21:26:15 +00001419 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001420 {
1421 x509_crl_free( crl );
1422 return( ret );
1423 }
1424
Paul Bakker91200182010-02-18 21:26:15 +00001425 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001426 {
Paul Bakker635f4b42009-07-20 20:34:41 +00001427 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE |
Paul Bakker9be19372009-07-27 20:21:53 +00001428 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
1429 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE |
1430 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001431 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001432 x509_crl_free( crl );
1433 return( ret );
1434 }
1435 }
1436
1437 /*
1438 * revokedCertificates SEQUENCE OF SEQUENCE {
1439 * userCertificate CertificateSerialNumber,
1440 * revocationDate Time,
1441 * crlEntryExtensions Extensions OPTIONAL
1442 * -- if present, MUST be v2
1443 * } OPTIONAL
1444 */
1445 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1446 {
1447 x509_crl_free( crl );
1448 return( ret );
1449 }
1450
1451 /*
1452 * crlExtensions EXPLICIT Extensions OPTIONAL
1453 * -- if present, MUST be v2
1454 */
1455 if( crl->version == 2 )
1456 {
1457 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1458
1459 if( ret != 0 )
1460 {
1461 x509_crl_free( crl );
1462 return( ret );
1463 }
1464 }
1465
1466 if( p != end )
1467 {
1468 x509_crl_free( crl );
1469 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1470 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1471 }
1472
1473 end = crl->raw.p + crl->raw.len;
1474
1475 /*
1476 * signatureAlgorithm AlgorithmIdentifier,
1477 * signatureValue BIT STRING
1478 */
1479 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1480 {
1481 x509_crl_free( crl );
1482 return( ret );
1483 }
1484
1485 if( memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
1486 {
1487 x509_crl_free( crl );
1488 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1489 }
1490
1491 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1492 {
1493 x509_crl_free( crl );
1494 return( ret );
1495 }
1496
1497 if( p != end )
1498 {
1499 x509_crl_free( crl );
1500 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1501 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1502 }
1503
1504 if( buflen > 0 )
1505 {
1506 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1507
Paul Bakker7d06ad22009-05-02 15:53:56 +00001508 if( crl->next == NULL )
1509 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001510 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001511 return( 1 );
1512 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001513
Paul Bakker7d06ad22009-05-02 15:53:56 +00001514 crl = crl->next;
1515 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001516
1517 return( x509parse_crl( crl, buf, buflen ) );
1518 }
1519
1520 return( 0 );
1521}
1522
1523/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001524 * Load all data from a file into a given buffer.
1525 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001526int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001527{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001528 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001529
Paul Bakkerd98030e2009-05-02 15:13:40 +00001530 if( ( f = fopen( path, "rb" ) ) == NULL )
1531 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001532
Paul Bakkerd98030e2009-05-02 15:13:40 +00001533 fseek( f, 0, SEEK_END );
1534 *n = (size_t) ftell( f );
1535 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001536
Paul Bakkerd98030e2009-05-02 15:13:40 +00001537 if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
1538 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001539
Paul Bakkerd98030e2009-05-02 15:13:40 +00001540 if( fread( *buf, 1, *n, f ) != *n )
1541 {
1542 fclose( f );
1543 free( *buf );
1544 return( 1 );
1545 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001546
Paul Bakkerd98030e2009-05-02 15:13:40 +00001547 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001548
Paul Bakkerd98030e2009-05-02 15:13:40 +00001549 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001550
Paul Bakkerd98030e2009-05-02 15:13:40 +00001551 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001552}
1553
1554/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001555 * Load one or more certificates and add them to the chained list
1556 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001557int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001558{
1559 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001560 size_t n;
1561 unsigned char *buf;
1562
Paul Bakker2b245eb2009-04-19 18:44:26 +00001563 if ( load_file( path, &buf, &n ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001564 return( 1 );
1565
Paul Bakker5121ce52009-01-03 21:22:43 +00001566 ret = x509parse_crt( chain, buf, (int) n );
1567
1568 memset( buf, 0, n + 1 );
1569 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001570
1571 return( ret );
1572}
1573
Paul Bakkerd98030e2009-05-02 15:13:40 +00001574/*
1575 * Load one or more CRLs and add them to the chained list
1576 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001577int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001578{
1579 int ret;
1580 size_t n;
1581 unsigned char *buf;
1582
1583 if ( load_file( path, &buf, &n ) )
1584 return( 1 );
1585
1586 ret = x509parse_crl( chain, buf, (int) n );
1587
1588 memset( buf, 0, n + 1 );
1589 free( buf );
1590
1591 return( ret );
1592}
1593
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001594#if defined(POLARSSL_DES_C) && defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001595/*
1596 * Read a 16-byte hex string and convert it to binary
1597 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001598static int x509_get_iv( const unsigned char *s, unsigned char iv[8] )
Paul Bakker5121ce52009-01-03 21:22:43 +00001599{
1600 int i, j, k;
1601
1602 memset( iv, 0, 8 );
1603
1604 for( i = 0; i < 16; i++, s++ )
1605 {
1606 if( *s >= '0' && *s <= '9' ) j = *s - '0'; else
1607 if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else
1608 if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else
Paul Bakker40e46942009-01-03 21:51:57 +00001609 return( POLARSSL_ERR_X509_KEY_INVALID_ENC_IV );
Paul Bakker5121ce52009-01-03 21:22:43 +00001610
1611 k = ( ( i & 1 ) != 0 ) ? j : j << 4;
1612
1613 iv[i >> 1] = (unsigned char)( iv[i >> 1] | k );
1614 }
1615
1616 return( 0 );
1617}
1618
1619/*
1620 * Decrypt with 3DES-CBC, using PBKDF1 for key derivation
1621 */
1622static void x509_des3_decrypt( unsigned char des3_iv[8],
1623 unsigned char *buf, int buflen,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001624 const unsigned char *pwd, int pwdlen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001625{
1626 md5_context md5_ctx;
1627 des3_context des3_ctx;
1628 unsigned char md5sum[16];
1629 unsigned char des3_key[24];
1630
1631 /*
1632 * 3DES key[ 0..15] = MD5(pwd || IV)
1633 * key[16..23] = MD5(pwd || IV || 3DES key[ 0..15])
1634 */
1635 md5_starts( &md5_ctx );
1636 md5_update( &md5_ctx, pwd, pwdlen );
1637 md5_update( &md5_ctx, des3_iv, 8 );
1638 md5_finish( &md5_ctx, md5sum );
1639 memcpy( des3_key, md5sum, 16 );
1640
1641 md5_starts( &md5_ctx );
1642 md5_update( &md5_ctx, md5sum, 16 );
1643 md5_update( &md5_ctx, pwd, pwdlen );
1644 md5_update( &md5_ctx, des3_iv, 8 );
1645 md5_finish( &md5_ctx, md5sum );
1646 memcpy( des3_key + 16, md5sum, 8 );
1647
1648 des3_set3key_dec( &des3_ctx, des3_key );
1649 des3_crypt_cbc( &des3_ctx, DES_DECRYPT, buflen,
1650 des3_iv, buf, buf );
1651
1652 memset( &md5_ctx, 0, sizeof( md5_ctx ) );
1653 memset( &des3_ctx, 0, sizeof( des3_ctx ) );
1654 memset( md5sum, 0, 16 );
1655 memset( des3_key, 0, 24 );
1656}
1657#endif
1658
1659/*
1660 * Parse a private RSA key
1661 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001662int x509parse_key( rsa_context *rsa, const unsigned char *key, int keylen,
1663 const unsigned char *pwd, int pwdlen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001664{
1665 int ret, len, enc;
Paul Bakkerff60ee62010-03-16 21:09:09 +00001666 unsigned char *buf, *s1, *s2;
Paul Bakker5121ce52009-01-03 21:22:43 +00001667 unsigned char *p, *end;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001668#if defined(POLARSSL_DES_C) && defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001669 unsigned char des3_iv[8];
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001670#else
1671 ((void) pwd);
1672 ((void) pwdlen);
1673#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001674
Paul Bakkerff60ee62010-03-16 21:09:09 +00001675 s1 = (unsigned char *) strstr( (char *) key,
Paul Bakker5121ce52009-01-03 21:22:43 +00001676 "-----BEGIN RSA PRIVATE KEY-----" );
1677
1678 if( s1 != NULL )
1679 {
Paul Bakkerff60ee62010-03-16 21:09:09 +00001680 s2 = (unsigned char *) strstr( (char *) key,
Paul Bakker5121ce52009-01-03 21:22:43 +00001681 "-----END RSA PRIVATE KEY-----" );
1682
1683 if( s2 == NULL || s2 <= s1 )
Paul Bakker40e46942009-01-03 21:51:57 +00001684 return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001685
1686 s1 += 31;
1687 if( *s1 == '\r' ) s1++;
1688 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001689 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001690
1691 enc = 0;
1692
1693 if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
1694 {
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001695#if defined(POLARSSL_DES_C) && defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001696 enc++;
1697
1698 s1 += 22;
1699 if( *s1 == '\r' ) s1++;
1700 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001701 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001702
1703 if( memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001704 return( POLARSSL_ERR_X509_KEY_UNKNOWN_ENC_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +00001705
1706 s1 += 23;
1707 if( x509_get_iv( s1, des3_iv ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001708 return( POLARSSL_ERR_X509_KEY_INVALID_ENC_IV );
Paul Bakker5121ce52009-01-03 21:22:43 +00001709
1710 s1 += 16;
1711 if( *s1 == '\r' ) s1++;
1712 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001713 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001714#else
Paul Bakker40e46942009-01-03 21:51:57 +00001715 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001716#endif
1717 }
1718
1719 len = 0;
1720 ret = base64_decode( NULL, &len, s1, s2 - s1 );
1721
Paul Bakker40e46942009-01-03 21:51:57 +00001722 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
1723 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001724
1725 if( ( buf = (unsigned char *) malloc( len ) ) == NULL )
1726 return( 1 );
1727
1728 if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
1729 {
1730 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001731 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001732 }
1733
Paul Bakkerff60ee62010-03-16 21:09:09 +00001734 keylen = len;
Paul Bakker5121ce52009-01-03 21:22:43 +00001735
1736 if( enc != 0 )
1737 {
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001738#if defined(POLARSSL_DES_C) && defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001739 if( pwd == NULL )
1740 {
1741 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001742 return( POLARSSL_ERR_X509_KEY_PASSWORD_REQUIRED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001743 }
1744
Paul Bakkerff60ee62010-03-16 21:09:09 +00001745 x509_des3_decrypt( des3_iv, buf, keylen, pwd, pwdlen );
Paul Bakker5121ce52009-01-03 21:22:43 +00001746
1747 if( buf[0] != 0x30 || buf[1] != 0x82 ||
1748 buf[4] != 0x02 || buf[5] != 0x01 )
1749 {
1750 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001751 return( POLARSSL_ERR_X509_KEY_PASSWORD_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001752 }
1753#else
Paul Bakker40e46942009-01-03 21:51:57 +00001754 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001755#endif
1756 }
1757 }
Paul Bakkerff60ee62010-03-16 21:09:09 +00001758 else
1759 {
1760 buf = NULL;
1761 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001762
1763 memset( rsa, 0, sizeof( rsa_context ) );
1764
Paul Bakkerff60ee62010-03-16 21:09:09 +00001765 p = ( s1 != NULL ) ? buf : (unsigned char *) key;
1766 end = p + keylen;
Paul Bakker5121ce52009-01-03 21:22:43 +00001767
1768 /*
1769 * RSAPrivateKey ::= SEQUENCE {
1770 * version Version,
1771 * modulus INTEGER, -- n
1772 * publicExponent INTEGER, -- e
1773 * privateExponent INTEGER, -- d
1774 * prime1 INTEGER, -- p
1775 * prime2 INTEGER, -- q
1776 * exponent1 INTEGER, -- d mod (p-1)
1777 * exponent2 INTEGER, -- d mod (q-1)
1778 * coefficient INTEGER, -- (inverse of q) mod p
1779 * otherPrimeInfos OtherPrimeInfos OPTIONAL
1780 * }
1781 */
1782 if( ( ret = asn1_get_tag( &p, end, &len,
1783 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1784 {
1785 if( s1 != NULL )
1786 free( buf );
1787
1788 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001789 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001790 }
1791
1792 end = p + len;
1793
1794 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
1795 {
1796 if( s1 != NULL )
1797 free( buf );
1798
1799 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001800 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001801 }
1802
1803 if( rsa->ver != 0 )
1804 {
1805 if( s1 != NULL )
1806 free( buf );
1807
1808 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001809 return( ret | POLARSSL_ERR_X509_KEY_INVALID_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001810 }
1811
1812 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
1813 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
1814 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
1815 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
1816 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
1817 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
1818 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
1819 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
1820 {
1821 if( s1 != NULL )
1822 free( buf );
1823
1824 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001825 return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001826 }
1827
1828 rsa->len = mpi_size( &rsa->N );
1829
1830 if( p != end )
1831 {
1832 if( s1 != NULL )
1833 free( buf );
1834
1835 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001836 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT |
1837 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001838 }
1839
1840 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
1841 {
1842 if( s1 != NULL )
1843 free( buf );
1844
1845 rsa_free( rsa );
1846 return( ret );
1847 }
1848
1849 if( s1 != NULL )
1850 free( buf );
1851
1852 return( 0 );
1853}
1854
1855/*
1856 * Load and parse a private RSA key
1857 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001858int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
Paul Bakker5121ce52009-01-03 21:22:43 +00001859{
1860 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001861 size_t n;
1862 unsigned char *buf;
1863
Paul Bakker2b245eb2009-04-19 18:44:26 +00001864 if ( load_file( path, &buf, &n ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001865 return( 1 );
1866
Paul Bakker5121ce52009-01-03 21:22:43 +00001867 if( pwd == NULL )
1868 ret = x509parse_key( rsa, buf, (int) n, NULL, 0 );
1869 else
1870 ret = x509parse_key( rsa, buf, (int) n,
1871 (unsigned char *) pwd, strlen( pwd ) );
1872
1873 memset( buf, 0, n + 1 );
1874 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001875
1876 return( ret );
1877}
1878
1879#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00001880#include <stdarg.h>
1881
1882#if !defined vsnprintf
1883#define vsnprintf _vsnprintf
1884#endif // vsnprintf
1885
1886/*
1887 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
1888 * Result value is not size of buffer needed, but -1 if no fit is possible.
1889 *
1890 * This fuction tries to 'fix' this by at least suggesting enlarging the
1891 * size by 20.
1892 */
1893int compat_snprintf(char *str, size_t size, const char *format, ...)
1894{
1895 va_list ap;
1896 int res = -1;
1897
1898 va_start( ap, format );
1899
1900 res = vsnprintf( str, size, format, ap );
1901
1902 va_end( ap );
1903
1904 // No quick fix possible
1905 if ( res < 0 )
1906 return( size + 20 );
1907
1908 return res;
1909}
1910
1911#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00001912#endif
1913
Paul Bakkerd98030e2009-05-02 15:13:40 +00001914#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
1915
1916#define SAFE_SNPRINTF() \
1917{ \
1918 if( ret == -1 ) \
1919 return( -1 ); \
1920 \
1921 if ( ret > n ) { \
1922 p[n - 1] = '\0'; \
1923 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
1924 } \
1925 \
1926 n -= ret; \
1927 p += ret; \
1928}
1929
Paul Bakker5121ce52009-01-03 21:22:43 +00001930/*
1931 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00001932 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00001933 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001934int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00001935{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001936 int i, ret, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00001937 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00001938 const x509_name *name;
Paul Bakker5121ce52009-01-03 21:22:43 +00001939 char s[128], *p;
1940
1941 memset( s, 0, sizeof( s ) );
1942
1943 name = dn;
1944 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001945 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00001946
1947 while( name != NULL )
1948 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001949 if( name != dn ) {
1950 ret = snprintf( p, n, ", " );
1951 SAFE_SNPRINTF();
1952 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001953
1954 if( memcmp( name->oid.p, OID_X520, 2 ) == 0 )
1955 {
1956 switch( name->oid.p[2] )
1957 {
1958 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001959 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001960
1961 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001962 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001963
1964 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001965 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001966
1967 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001968 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001969
1970 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001971 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001972
1973 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001974 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001975
1976 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001977 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00001978 name->oid.p[2] );
1979 break;
1980 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001981 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001982 }
1983 else if( memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
1984 {
1985 switch( name->oid.p[8] )
1986 {
1987 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001988 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001989
1990 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001991 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00001992 name->oid.p[8] );
1993 break;
1994 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001995 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001996 }
1997 else
Paul Bakkerd98030e2009-05-02 15:13:40 +00001998 {
1999 ret = snprintf( p, n, "\?\?=" );
2000 SAFE_SNPRINTF();
2001 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002002
2003 for( i = 0; i < name->val.len; i++ )
2004 {
2005 if( i >= (int) sizeof( s ) - 1 )
2006 break;
2007
2008 c = name->val.p[i];
2009 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2010 s[i] = '?';
2011 else s[i] = c;
2012 }
2013 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002014 ret = snprintf( p, n, "%s", s );
2015 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002016 name = name->next;
2017 }
2018
Paul Bakkerd98030e2009-05-02 15:13:40 +00002019 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002020}
2021
2022/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002023 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002024 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002025int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2026 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002027{
Paul Bakkerd98030e2009-05-02 15:13:40 +00002028 int i, n, nr, ret;
2029 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00002030
2031 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002032 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002033
Paul Bakkerd98030e2009-05-02 15:13:40 +00002034 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002035 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002036 SAFE_SNPRINTF();
2037 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002038 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002039 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002040
Paul Bakkerd98030e2009-05-02 15:13:40 +00002041 nr = ( crt->serial.len <= 32 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002042 ? crt->serial.len : 32;
2043
Paul Bakkerd98030e2009-05-02 15:13:40 +00002044 for( i = 0; i < nr; i++ )
2045 {
2046 ret = snprintf( p, n, "%02X%s",
2047 crt->serial.p[i], ( i < nr - 1 ) ? ":" : "" );
2048 SAFE_SNPRINTF();
2049 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002050
Paul Bakkerd98030e2009-05-02 15:13:40 +00002051 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2052 SAFE_SNPRINTF();
2053 ret = x509parse_dn_gets( p, n, &crt->issuer );
2054 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002055
Paul Bakkerd98030e2009-05-02 15:13:40 +00002056 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2057 SAFE_SNPRINTF();
2058 ret = x509parse_dn_gets( p, n, &crt->subject );
2059 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002060
Paul Bakkerd98030e2009-05-02 15:13:40 +00002061 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002062 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2063 crt->valid_from.year, crt->valid_from.mon,
2064 crt->valid_from.day, crt->valid_from.hour,
2065 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002066 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002067
Paul Bakkerd98030e2009-05-02 15:13:40 +00002068 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002069 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2070 crt->valid_to.year, crt->valid_to.mon,
2071 crt->valid_to.day, crt->valid_to.hour,
2072 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002073 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002074
Paul Bakkerd98030e2009-05-02 15:13:40 +00002075 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2076 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002077
Paul Bakker27d66162010-03-17 06:56:01 +00002078 switch( crt->sig_alg )
Paul Bakker5121ce52009-01-03 21:22:43 +00002079 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002080 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2081 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2082 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2083 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2084 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2085 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2086 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2087 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2088 default: ret = snprintf( p, n, "???" ); break;
2089 }
2090 SAFE_SNPRINTF();
2091
2092 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
2093 crt->rsa.N.n * (int) sizeof( unsigned long ) * 8 );
2094 SAFE_SNPRINTF();
2095
2096 return( size - n );
2097}
2098
2099/*
2100 * Return an informational string about the CRL.
2101 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002102int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2103 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002104{
2105 int i, n, nr, ret;
2106 char *p;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002107 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002108
2109 p = buf;
2110 n = size;
2111
2112 ret = snprintf( p, n, "%sCRL version : %d",
2113 prefix, crl->version );
2114 SAFE_SNPRINTF();
2115
2116 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2117 SAFE_SNPRINTF();
2118 ret = x509parse_dn_gets( p, n, &crl->issuer );
2119 SAFE_SNPRINTF();
2120
2121 ret = snprintf( p, n, "\n%sthis update : " \
2122 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2123 crl->this_update.year, crl->this_update.mon,
2124 crl->this_update.day, crl->this_update.hour,
2125 crl->this_update.min, crl->this_update.sec );
2126 SAFE_SNPRINTF();
2127
2128 ret = snprintf( p, n, "\n%snext update : " \
2129 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2130 crl->next_update.year, crl->next_update.mon,
2131 crl->next_update.day, crl->next_update.hour,
2132 crl->next_update.min, crl->next_update.sec );
2133 SAFE_SNPRINTF();
2134
2135 entry = &crl->entry;
2136
2137 ret = snprintf( p, n, "\n%sRevoked certificates:",
2138 prefix );
2139 SAFE_SNPRINTF();
2140
Paul Bakker9be19372009-07-27 20:21:53 +00002141 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002142 {
2143 ret = snprintf( p, n, "\n%sserial number: ",
2144 prefix );
2145 SAFE_SNPRINTF();
2146
2147 nr = ( entry->serial.len <= 32 )
2148 ? entry->serial.len : 32;
2149
2150 for( i = 0; i < nr; i++ ) {
2151 ret = snprintf( p, n, "%02X%s",
2152 entry->serial.p[i], ( i < nr - 1 ) ? ":" : "" );
2153 SAFE_SNPRINTF();
2154 }
2155
2156 ret = snprintf( p, n, " revocation date: " \
2157 "%04d-%02d-%02d %02d:%02d:%02d",
2158 entry->revocation_date.year, entry->revocation_date.mon,
2159 entry->revocation_date.day, entry->revocation_date.hour,
2160 entry->revocation_date.min, entry->revocation_date.sec );
2161 SAFE_SNPRINTF();
2162
2163 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002164 }
2165
Paul Bakkerd98030e2009-05-02 15:13:40 +00002166 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2167 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002168
Paul Bakker27d66162010-03-17 06:56:01 +00002169 switch( crl->sig_alg )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002170 {
2171 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2172 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2173 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2174 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2175 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2176 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2177 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2178 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2179 default: ret = snprintf( p, n, "???" ); break;
2180 }
2181 SAFE_SNPRINTF();
2182
Paul Bakker1e27bb22009-07-19 20:25:25 +00002183 ret = snprintf( p, n, "\n" );
2184 SAFE_SNPRINTF();
2185
Paul Bakkerd98030e2009-05-02 15:13:40 +00002186 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002187}
2188
2189/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00002190 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00002191 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002192int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00002193{
2194 struct tm *lt;
2195 time_t tt;
2196
2197 tt = time( NULL );
2198 lt = localtime( &tt );
2199
Paul Bakker40ea7de2009-05-03 10:18:48 +00002200 if( lt->tm_year > to->year - 1900 )
2201 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002202
Paul Bakker40ea7de2009-05-03 10:18:48 +00002203 if( lt->tm_year == to->year - 1900 &&
2204 lt->tm_mon > to->mon - 1 )
2205 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002206
Paul Bakker40ea7de2009-05-03 10:18:48 +00002207 if( lt->tm_year == to->year - 1900 &&
2208 lt->tm_mon == to->mon - 1 &&
2209 lt->tm_mday > to->day )
2210 return( 1 );
2211
2212 return( 0 );
2213}
2214
2215/*
2216 * Return 1 if the certificate is revoked, or 0 otherwise.
2217 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002218int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002219{
Paul Bakkerff60ee62010-03-16 21:09:09 +00002220 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00002221
2222 while( cur != NULL && cur->serial.len != 0 )
2223 {
2224 if( memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
2225 {
2226 if( x509parse_time_expired( &cur->revocation_date ) )
2227 return( 1 );
2228 }
2229
2230 cur = cur->next;
2231 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002232
2233 return( 0 );
2234}
2235
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002236/*
2237 * Wrapper for x509 hashes.
2238 *
2239 * @param out Buffer to receive the hash (Should be at least 64 bytes)
2240 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002241static void x509_hash( const unsigned char *in, int len, int alg,
Paul Bakker5121ce52009-01-03 21:22:43 +00002242 unsigned char *out )
2243{
2244 switch( alg )
2245 {
Paul Bakker40e46942009-01-03 21:51:57 +00002246#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002247 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002248#endif
Paul Bakker40e46942009-01-03 21:51:57 +00002249#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002250 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002251#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002252#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002253 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002254#endif
2255#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002256 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002257#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00002258#if defined(POLARSSL_SHA2_C)
2259 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
2260 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
2261#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00002262#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002263 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
2264 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
2265#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002266 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002267 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002268 break;
2269 }
2270}
2271
2272/*
2273 * Verify the certificate validity
2274 */
2275int x509parse_verify( x509_cert *crt,
2276 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00002277 x509_crl *ca_crl,
Paul Bakkerff60ee62010-03-16 21:09:09 +00002278 const char *cn, int *flags )
Paul Bakker5121ce52009-01-03 21:22:43 +00002279{
2280 int cn_len;
2281 int hash_id;
2282 int pathlen;
2283 x509_cert *cur;
2284 x509_name *name;
Paul Bakker4593aea2009-02-09 22:32:35 +00002285 unsigned char hash[64];
Paul Bakker5121ce52009-01-03 21:22:43 +00002286
Paul Bakker40ea7de2009-05-03 10:18:48 +00002287 *flags = 0;
2288
2289 if( x509parse_time_expired( &crt->valid_to ) )
2290 *flags = BADCERT_EXPIRED;
Paul Bakker5121ce52009-01-03 21:22:43 +00002291
2292 if( cn != NULL )
2293 {
2294 name = &crt->subject;
2295 cn_len = strlen( cn );
2296
2297 while( name != NULL )
2298 {
2299 if( memcmp( name->oid.p, OID_CN, 3 ) == 0 &&
2300 memcmp( name->val.p, cn, cn_len ) == 0 &&
2301 name->val.len == cn_len )
2302 break;
2303
2304 name = name->next;
2305 }
2306
2307 if( name == NULL )
2308 *flags |= BADCERT_CN_MISMATCH;
2309 }
2310
2311 *flags |= BADCERT_NOT_TRUSTED;
2312
2313 /*
2314 * Iterate upwards in the given cert chain,
2315 * ignoring any upper cert with CA != TRUE.
2316 */
2317 cur = crt->next;
2318
2319 pathlen = 1;
2320
Paul Bakker7c6d4a42009-03-28 20:35:47 +00002321 while( cur != NULL && cur->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002322 {
2323 if( cur->ca_istrue == 0 ||
2324 crt->issuer_raw.len != cur->subject_raw.len ||
2325 memcmp( crt->issuer_raw.p, cur->subject_raw.p,
2326 crt->issuer_raw.len ) != 0 )
2327 {
2328 cur = cur->next;
2329 continue;
2330 }
2331
Paul Bakker27d66162010-03-17 06:56:01 +00002332 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00002333
2334 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2335
2336 if( rsa_pkcs1_verify( &cur->rsa, RSA_PUBLIC, hash_id,
2337 0, hash, crt->sig.p ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00002338 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002339
2340 pathlen++;
2341
2342 crt = cur;
2343 cur = crt->next;
2344 }
2345
2346 /*
2347 * Atempt to validate topmost cert with our CA chain.
2348 */
Paul Bakker7c6d4a42009-03-28 20:35:47 +00002349 while( trust_ca != NULL && trust_ca->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002350 {
2351 if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
2352 memcmp( crt->issuer_raw.p, trust_ca->subject_raw.p,
2353 crt->issuer_raw.len ) != 0 )
2354 {
2355 trust_ca = trust_ca->next;
2356 continue;
2357 }
2358
2359 if( trust_ca->max_pathlen > 0 &&
2360 trust_ca->max_pathlen < pathlen )
2361 break;
2362
Paul Bakker27d66162010-03-17 06:56:01 +00002363 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00002364
2365 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2366
2367 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
2368 0, hash, crt->sig.p ) == 0 )
2369 {
2370 /*
2371 * cert. is signed by a trusted CA
2372 */
2373 *flags &= ~BADCERT_NOT_TRUSTED;
2374 break;
2375 }
2376
2377 trust_ca = trust_ca->next;
2378 }
2379
Paul Bakker40ea7de2009-05-03 10:18:48 +00002380 /*
2381 * TODO: What happens if no CRL is present?
2382 * Suggestion: Revocation state should be unknown if no CRL is present.
2383 * For backwards compatibility this is not yet implemented.
2384 */
2385
2386 /*
2387 * Check if the topmost certificate is revoked if the trusted CA is
2388 * determined.
2389 */
2390 while( trust_ca != NULL && ca_crl != NULL && ca_crl->version != 0 )
2391 {
2392 if( ca_crl->issuer_raw.len != trust_ca->subject_raw.len ||
2393 memcmp( ca_crl->issuer_raw.p, trust_ca->subject_raw.p,
2394 ca_crl->issuer_raw.len ) != 0 )
2395 {
2396 ca_crl = ca_crl->next;
2397 continue;
2398 }
2399
2400 /*
2401 * Check if CRL is correctry signed by the trusted CA
2402 */
Paul Bakker27d66162010-03-17 06:56:01 +00002403 hash_id = ca_crl->sig_alg;
Paul Bakker40ea7de2009-05-03 10:18:48 +00002404
2405 x509_hash( ca_crl->tbs.p, ca_crl->tbs.len, hash_id, hash );
2406
2407 if( !rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
2408 0, hash, ca_crl->sig.p ) == 0 )
2409 {
2410 /*
2411 * CRL is not trusted
2412 */
2413 *flags |= BADCRL_NOT_TRUSTED;
2414 break;
2415 }
2416
2417 /*
2418 * Check for validity of CRL (Do not drop out)
2419 */
2420 if( x509parse_time_expired( &ca_crl->next_update ) )
2421 *flags |= BADCRL_EXPIRED;
2422
2423 /*
2424 * Check if certificate is revoked
2425 */
2426 if( x509parse_revoked(crt, ca_crl) )
2427 {
2428 *flags |= BADCERT_REVOKED;
2429 break;
2430 }
2431
2432 ca_crl = ca_crl->next;
2433 }
2434
Paul Bakker5121ce52009-01-03 21:22:43 +00002435 if( *flags != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00002436 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002437
2438 return( 0 );
2439}
2440
2441/*
2442 * Unallocate all certificate data
2443 */
2444void x509_free( x509_cert *crt )
2445{
2446 x509_cert *cert_cur = crt;
2447 x509_cert *cert_prv;
2448 x509_name *name_cur;
2449 x509_name *name_prv;
2450
2451 if( crt == NULL )
2452 return;
2453
2454 do
2455 {
2456 rsa_free( &cert_cur->rsa );
2457
2458 name_cur = cert_cur->issuer.next;
2459 while( name_cur != NULL )
2460 {
2461 name_prv = name_cur;
2462 name_cur = name_cur->next;
2463 memset( name_prv, 0, sizeof( x509_name ) );
2464 free( name_prv );
2465 }
2466
2467 name_cur = cert_cur->subject.next;
2468 while( name_cur != NULL )
2469 {
2470 name_prv = name_cur;
2471 name_cur = name_cur->next;
2472 memset( name_prv, 0, sizeof( x509_name ) );
2473 free( name_prv );
2474 }
2475
2476 if( cert_cur->raw.p != NULL )
2477 {
2478 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
2479 free( cert_cur->raw.p );
2480 }
2481
2482 cert_cur = cert_cur->next;
2483 }
2484 while( cert_cur != NULL );
2485
2486 cert_cur = crt;
2487 do
2488 {
2489 cert_prv = cert_cur;
2490 cert_cur = cert_cur->next;
2491
2492 memset( cert_prv, 0, sizeof( x509_cert ) );
2493 if( cert_prv != crt )
2494 free( cert_prv );
2495 }
2496 while( cert_cur != NULL );
2497}
2498
Paul Bakkerd98030e2009-05-02 15:13:40 +00002499/*
2500 * Unallocate all CRL data
2501 */
2502void x509_crl_free( x509_crl *crl )
2503{
2504 x509_crl *crl_cur = crl;
2505 x509_crl *crl_prv;
2506 x509_name *name_cur;
2507 x509_name *name_prv;
2508 x509_crl_entry *entry_cur;
2509 x509_crl_entry *entry_prv;
2510
2511 if( crl == NULL )
2512 return;
2513
2514 do
2515 {
2516 name_cur = crl_cur->issuer.next;
2517 while( name_cur != NULL )
2518 {
2519 name_prv = name_cur;
2520 name_cur = name_cur->next;
2521 memset( name_prv, 0, sizeof( x509_name ) );
2522 free( name_prv );
2523 }
2524
2525 entry_cur = crl_cur->entry.next;
2526 while( entry_cur != NULL )
2527 {
2528 entry_prv = entry_cur;
2529 entry_cur = entry_cur->next;
2530 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
2531 free( entry_prv );
2532 }
2533
2534 if( crl_cur->raw.p != NULL )
2535 {
2536 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
2537 free( crl_cur->raw.p );
2538 }
2539
2540 crl_cur = crl_cur->next;
2541 }
2542 while( crl_cur != NULL );
2543
2544 crl_cur = crl;
2545 do
2546 {
2547 crl_prv = crl_cur;
2548 crl_cur = crl_cur->next;
2549
2550 memset( crl_prv, 0, sizeof( x509_crl ) );
2551 if( crl_prv != crl )
2552 free( crl_prv );
2553 }
2554 while( crl_cur != NULL );
2555}
2556
Paul Bakker40e46942009-01-03 21:51:57 +00002557#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002558
Paul Bakker40e46942009-01-03 21:51:57 +00002559#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00002560
2561/*
2562 * Checkup routine
2563 */
2564int x509_self_test( int verbose )
2565{
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002566#if defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00002567 int ret, i, j;
2568 x509_cert cacert;
2569 x509_cert clicert;
2570 rsa_context rsa;
2571
2572 if( verbose != 0 )
2573 printf( " X.509 certificate load: " );
2574
2575 memset( &clicert, 0, sizeof( x509_cert ) );
2576
2577 ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
2578 strlen( test_cli_crt ) );
2579 if( ret != 0 )
2580 {
2581 if( verbose != 0 )
2582 printf( "failed\n" );
2583
2584 return( ret );
2585 }
2586
2587 memset( &cacert, 0, sizeof( x509_cert ) );
2588
2589 ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
2590 strlen( test_ca_crt ) );
2591 if( ret != 0 )
2592 {
2593 if( verbose != 0 )
2594 printf( "failed\n" );
2595
2596 return( ret );
2597 }
2598
2599 if( verbose != 0 )
2600 printf( "passed\n X.509 private key load: " );
2601
2602 i = strlen( test_ca_key );
2603 j = strlen( test_ca_pwd );
2604
2605 if( ( ret = x509parse_key( &rsa,
2606 (unsigned char *) test_ca_key, i,
2607 (unsigned char *) test_ca_pwd, j ) ) != 0 )
2608 {
2609 if( verbose != 0 )
2610 printf( "failed\n" );
2611
2612 return( ret );
2613 }
2614
2615 if( verbose != 0 )
2616 printf( "passed\n X.509 signature verify: ");
2617
Paul Bakker1973e4c2009-07-10 22:32:40 +00002618 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &i );
Paul Bakker5121ce52009-01-03 21:22:43 +00002619 if( ret != 0 )
2620 {
Paul Bakker02710262011-02-22 16:26:47 +00002621 printf("%02x", i);
Paul Bakker5121ce52009-01-03 21:22:43 +00002622 if( verbose != 0 )
2623 printf( "failed\n" );
2624
2625 return( ret );
2626 }
2627
2628 if( verbose != 0 )
2629 printf( "passed\n\n" );
2630
2631 x509_free( &cacert );
2632 x509_free( &clicert );
2633 rsa_free( &rsa );
2634
2635 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002636#else
2637 ((void) verbose);
2638 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
2639#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002640}
2641
2642#endif
2643
2644#endif