blob: ec7e2186cb4f8f018852b1ecd38bd7104287d9b4 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * X.509 certificate and private key decoding
3 *
Paul Bakker84f12b72010-07-18 10:13:04 +00004 * Copyright (C) 2006-2010, Brainspark B.V.
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
Paul Bakker84f12b72010-07-18 10:13:04 +00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakkerb96f1542010-07-18 20:36:00 +00008 *
Paul Bakker77b385e2009-07-28 17:23:11 +00009 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +000010 *
Paul Bakker5121ce52009-01-03 21:22:43 +000011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25/*
26 * The ITU-T X.509 standard defines a certificat format for PKI.
27 *
28 * http://www.ietf.org/rfc/rfc2459.txt
29 * http://www.ietf.org/rfc/rfc3279.txt
30 *
31 * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
32 *
33 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
34 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
35 */
36
Paul Bakker40e46942009-01-03 21:51:57 +000037#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000038
Paul Bakker40e46942009-01-03 21:51:57 +000039#if defined(POLARSSL_X509_PARSE_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000040
Paul Bakker40e46942009-01-03 21:51:57 +000041#include "polarssl/x509.h"
42#include "polarssl/base64.h"
43#include "polarssl/des.h"
44#include "polarssl/md2.h"
45#include "polarssl/md4.h"
46#include "polarssl/md5.h"
47#include "polarssl/sha1.h"
Paul Bakker026c03b2009-03-28 17:53:03 +000048#include "polarssl/sha2.h"
49#include "polarssl/sha4.h"
Paul Bakker1b57b062011-01-06 15:48:19 +000050#include "polarssl/dhm.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000051
52#include <string.h>
53#include <stdlib.h>
54#include <stdio.h>
55#include <time.h>
56
57/*
58 * ASN.1 DER decoding routines
59 */
60static int asn1_get_len( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +000061 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +000062 int *len )
63{
64 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +000065 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000066
67 if( ( **p & 0x80 ) == 0 )
68 *len = *(*p)++;
69 else
70 {
71 switch( **p & 0x7F )
72 {
73 case 1:
74 if( ( end - *p ) < 2 )
Paul Bakker40e46942009-01-03 21:51:57 +000075 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000076
77 *len = (*p)[1];
78 (*p) += 2;
79 break;
80
81 case 2:
82 if( ( end - *p ) < 3 )
Paul Bakker40e46942009-01-03 21:51:57 +000083 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000084
85 *len = ( (*p)[1] << 8 ) | (*p)[2];
86 (*p) += 3;
87 break;
88
89 default:
Paul Bakker40e46942009-01-03 21:51:57 +000090 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +000091 break;
92 }
93 }
94
95 if( *len > (int) ( end - *p ) )
Paul Bakker40e46942009-01-03 21:51:57 +000096 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000097
98 return( 0 );
99}
100
101static int asn1_get_tag( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000102 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000103 int *len, int tag )
104{
105 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000106 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000107
108 if( **p != tag )
Paul Bakker40e46942009-01-03 21:51:57 +0000109 return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000110
111 (*p)++;
112
113 return( asn1_get_len( p, end, len ) );
114}
115
116static int asn1_get_bool( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000117 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000118 int *val )
119{
120 int ret, len;
121
122 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 )
123 return( ret );
124
125 if( len != 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000126 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000127
128 *val = ( **p != 0 ) ? 1 : 0;
129 (*p)++;
130
131 return( 0 );
132}
133
134static int asn1_get_int( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000135 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000136 int *val )
137{
138 int ret, len;
139
140 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
141 return( ret );
142
143 if( len > (int) sizeof( int ) || ( **p & 0x80 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000144 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000145
146 *val = 0;
147
148 while( len-- > 0 )
149 {
150 *val = ( *val << 8 ) | **p;
151 (*p)++;
152 }
153
154 return( 0 );
155}
156
157static int asn1_get_mpi( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000158 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000159 mpi *X )
160{
161 int ret, len;
162
163 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
164 return( ret );
165
166 ret = mpi_read_binary( X, *p, len );
167
168 *p += len;
169
170 return( ret );
171}
172
173/*
174 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
175 */
176static int x509_get_version( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000177 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000178 int *ver )
179{
180 int ret, len;
181
182 if( ( ret = asn1_get_tag( p, end, &len,
183 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
184 {
Paul Bakker40e46942009-01-03 21:51:57 +0000185 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000186 return( *ver = 0 );
187
188 return( ret );
189 }
190
191 end = *p + len;
192
193 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000194 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000195
196 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000197 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION |
198 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000199
200 return( 0 );
201}
202
203/*
204 * CertificateSerialNumber ::= INTEGER
205 */
206static int x509_get_serial( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000207 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000208 x509_buf *serial )
209{
210 int ret;
211
212 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000213 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL |
214 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000215
216 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
217 **p != ASN1_INTEGER )
Paul Bakker40e46942009-01-03 21:51:57 +0000218 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL |
219 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000220
221 serial->tag = *(*p)++;
222
223 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000224 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000225
226 serial->p = *p;
227 *p += serial->len;
228
229 return( 0 );
230}
231
232/*
233 * AlgorithmIdentifier ::= SEQUENCE {
234 * algorithm OBJECT IDENTIFIER,
235 * parameters ANY DEFINED BY algorithm OPTIONAL }
236 */
237static int x509_get_alg( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000238 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000239 x509_buf *alg )
240{
241 int ret, len;
242
243 if( ( ret = asn1_get_tag( p, end, &len,
244 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000245 return( POLARSSL_ERR_X509_CERT_INVALID_ALG | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000246
247 end = *p + len;
248 alg->tag = **p;
249
250 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000251 return( POLARSSL_ERR_X509_CERT_INVALID_ALG | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000252
253 alg->p = *p;
254 *p += alg->len;
255
256 if( *p == end )
257 return( 0 );
258
259 /*
260 * assume the algorithm parameters must be NULL
261 */
262 if( ( ret = asn1_get_tag( p, end, &len, ASN1_NULL ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000263 return( POLARSSL_ERR_X509_CERT_INVALID_ALG | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000264
265 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000266 return( POLARSSL_ERR_X509_CERT_INVALID_ALG |
267 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000268
269 return( 0 );
270}
271
272/*
273 * RelativeDistinguishedName ::=
274 * SET OF AttributeTypeAndValue
275 *
276 * AttributeTypeAndValue ::= SEQUENCE {
277 * type AttributeType,
278 * value AttributeValue }
279 *
280 * AttributeType ::= OBJECT IDENTIFIER
281 *
282 * AttributeValue ::= ANY DEFINED BY AttributeType
283 */
284static int x509_get_name( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000285 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000286 x509_name *cur )
287{
288 int ret, len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000289 const unsigned char *end2;
Paul Bakker5121ce52009-01-03 21:22:43 +0000290 x509_buf *oid;
291 x509_buf *val;
292
293 if( ( ret = asn1_get_tag( p, end, &len,
294 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000295 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000296
297 end2 = end;
298 end = *p + len;
299
300 if( ( ret = asn1_get_tag( p, end, &len,
301 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000302 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000303
304 if( *p + len != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000305 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
306 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000307
308 oid = &cur->oid;
309 oid->tag = **p;
310
311 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000312 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000313
314 oid->p = *p;
315 *p += oid->len;
316
317 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000318 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
319 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000320
321 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
322 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
323 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker40e46942009-01-03 21:51:57 +0000324 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
325 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000326
327 val = &cur->val;
328 val->tag = *(*p)++;
329
330 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000331 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000332
333 val->p = *p;
334 *p += val->len;
335
336 cur->next = NULL;
337
338 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000339 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
340 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000341
342 /*
343 * recurse until end of SEQUENCE is reached
344 */
345 if( *p == end2 )
346 return( 0 );
347
348 cur->next = (x509_name *) malloc(
349 sizeof( x509_name ) );
350
351 if( cur->next == NULL )
352 return( 1 );
353
354 return( x509_get_name( p, end2, cur->next ) );
355}
356
357/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000358 * Time ::= CHOICE {
359 * utcTime UTCTime,
360 * generalTime GeneralizedTime }
361 */
Paul Bakker91200182010-02-18 21:26:15 +0000362static int x509_get_time( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000363 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000364 x509_time *time )
365{
366 int ret, len;
367 char date[64];
Paul Bakker91200182010-02-18 21:26:15 +0000368 unsigned char tag;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000369
Paul Bakker91200182010-02-18 21:26:15 +0000370 if( ( end - *p ) < 1 )
371 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000372
Paul Bakker91200182010-02-18 21:26:15 +0000373 tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000374
Paul Bakker91200182010-02-18 21:26:15 +0000375 if ( tag == ASN1_UTC_TIME )
376 {
377 (*p)++;
378 ret = asn1_get_len( p, end, &len );
379
380 if( ret != 0 )
381 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000382
Paul Bakker91200182010-02-18 21:26:15 +0000383 memset( date, 0, sizeof( date ) );
384 memcpy( date, *p, ( len < (int) sizeof( date ) - 1 ) ?
385 len : (int) sizeof( date ) - 1 );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000386
Paul Bakker91200182010-02-18 21:26:15 +0000387 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
388 &time->year, &time->mon, &time->day,
389 &time->hour, &time->min, &time->sec ) < 5 )
390 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000391
Paul Bakker91200182010-02-18 21:26:15 +0000392 time->year += 100 * ( time->year < 90 );
393 time->year += 1900;
394
395 *p += len;
396
397 return( 0 );
398 }
399 else if ( tag == ASN1_GENERALIZED_TIME )
400 {
401 (*p)++;
402 ret = asn1_get_len( p, end, &len );
403
404 if( ret != 0 )
405 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret );
406
407 memset( date, 0, sizeof( date ) );
408 memcpy( date, *p, ( len < (int) sizeof( date ) - 1 ) ?
409 len : (int) sizeof( date ) - 1 );
410
411 if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
412 &time->year, &time->mon, &time->day,
413 &time->hour, &time->min, &time->sec ) < 5 )
414 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
415
416 *p += len;
417
418 return( 0 );
419 }
420 else
421 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000422}
423
424
425/*
426 * Validity ::= SEQUENCE {
427 * notBefore Time,
428 * notAfter Time }
429 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000430static int x509_get_dates( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000431 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000432 x509_time *from,
433 x509_time *to )
434{
435 int ret, len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000436
437 if( ( ret = asn1_get_tag( p, end, &len,
438 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000439 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000440
441 end = *p + len;
442
Paul Bakker91200182010-02-18 21:26:15 +0000443 if( ( ret = x509_get_time( p, end, from ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000444 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000445
Paul Bakker91200182010-02-18 21:26:15 +0000446 if( ( ret = x509_get_time( p, end, to ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000447 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000448
449 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000450 return( POLARSSL_ERR_X509_CERT_INVALID_DATE |
451 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000452
453 return( 0 );
454}
455
456/*
457 * SubjectPublicKeyInfo ::= SEQUENCE {
458 * algorithm AlgorithmIdentifier,
459 * subjectPublicKey BIT STRING }
460 */
461static int x509_get_pubkey( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000462 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000463 x509_buf *pk_alg_oid,
464 mpi *N, mpi *E )
465{
466 int ret, len;
467 unsigned char *end2;
468
469 if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 )
470 return( ret );
471
472 /*
473 * only RSA public keys handled at this time
474 */
475 if( pk_alg_oid->len != 9 ||
476 memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000477 return( POLARSSL_ERR_X509_CERT_UNKNOWN_PK_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000478
479 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000480 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000481
482 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000483 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY |
484 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000485
486 end2 = *p + len;
487
488 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000489 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000490
491 /*
492 * RSAPublicKey ::= SEQUENCE {
493 * modulus INTEGER, -- n
494 * publicExponent INTEGER -- e
495 * }
496 */
497 if( ( ret = asn1_get_tag( p, end2, &len,
498 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000499 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000500
501 if( *p + len != end2 )
Paul Bakker40e46942009-01-03 21:51:57 +0000502 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY |
503 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000504
505 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
506 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000507 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000508
509 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000510 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY |
511 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000512
513 return( 0 );
514}
515
516static int x509_get_sig( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000517 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000518 x509_buf *sig )
519{
520 int ret, len;
521
522 sig->tag = **p;
523
524 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000525 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000526
527 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000528 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000529
530 sig->len = len;
531 sig->p = *p;
532
533 *p += len;
534
535 return( 0 );
536}
537
538/*
539 * X.509 v2/v3 unique identifier (not parsed)
540 */
541static int x509_get_uid( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000542 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000543 x509_buf *uid, int n )
544{
545 int ret;
546
547 if( *p == end )
548 return( 0 );
549
550 uid->tag = **p;
551
552 if( ( ret = asn1_get_tag( p, end, &uid->len,
553 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
554 {
Paul Bakker40e46942009-01-03 21:51:57 +0000555 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000556 return( 0 );
557
558 return( ret );
559 }
560
561 uid->p = *p;
562 *p += uid->len;
563
564 return( 0 );
565}
566
567/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000568 * X.509 Extensions (No parsing of extensions, pointer should
569 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000570 */
571static int x509_get_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000572 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000573 x509_buf *ext )
Paul Bakker5121ce52009-01-03 21:22:43 +0000574{
575 int ret, len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000576
577 if( *p == end )
578 return( 0 );
579
580 ext->tag = **p;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000581
Paul Bakker5121ce52009-01-03 21:22:43 +0000582 if( ( ret = asn1_get_tag( p, end, &ext->len,
583 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000584 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000585
586 ext->p = *p;
587 end = *p + ext->len;
588
589 /*
590 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
591 *
592 * Extension ::= SEQUENCE {
593 * extnID OBJECT IDENTIFIER,
594 * critical BOOLEAN DEFAULT FALSE,
595 * extnValue OCTET STRING }
596 */
597 if( ( ret = asn1_get_tag( p, end, &len,
598 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000599 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000600
601 if( end != *p + len )
Paul Bakker40e46942009-01-03 21:51:57 +0000602 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
603 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000604
Paul Bakkerd98030e2009-05-02 15:13:40 +0000605 return( 0 );
606}
607
608/*
609 * X.509 CRL v2 extensions (no extensions parsed yet.)
610 */
611static int x509_get_crl_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000612 const unsigned char *end,
613 x509_buf *ext )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000614{
615 int ret, len;
616
617 if( ( ret = x509_get_ext( p, end, ext ) ) != 0 )
618 {
619 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
620 return( 0 );
621
622 return( ret );
623 }
624
625 while( *p < end )
626 {
627 if( ( ret = asn1_get_tag( p, end, &len,
628 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
629 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
630
631 *p += len;
632 }
633
634 if( *p != end )
635 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
636 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
637
638 return( 0 );
639}
640
641/*
642 * X.509 v3 extensions (only BasicConstraints are parsed)
643 */
644static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000645 const unsigned char *end,
646 x509_buf *ext,
647 int *ca_istrue,
648 int *max_pathlen )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000649{
650 int ret, len;
651 int is_critical = 1;
652 int is_cacert = 0;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000653 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000654
655 if( ( ret = x509_get_ext( p, end, ext ) ) != 0 )
656 {
657 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
658 return( 0 );
659
660 return( ret );
661 }
662
Paul Bakker5121ce52009-01-03 21:22:43 +0000663 while( *p < end )
664 {
665 if( ( ret = asn1_get_tag( p, end, &len,
666 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000667 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000668
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000669 end_ext_data = *p + len;
670
Paul Bakker5121ce52009-01-03 21:22:43 +0000671 if( memcmp( *p, "\x06\x03\x55\x1D\x13", 5 ) != 0 )
672 {
673 *p += len;
674 continue;
675 }
676
677 *p += 5;
678
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000679 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000680 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
681 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000682
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000683 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000684 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000685 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000686
687 /*
688 * BasicConstraints ::= SEQUENCE {
689 * cA BOOLEAN DEFAULT FALSE,
690 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
691 */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000692 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000693
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000694 if( end_ext_octet != end_ext_data )
695 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
696 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000697
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000698 if( ( ret = asn1_get_tag( p, end_ext_octet, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000699 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000700 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000701
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000702 if( *p == end_ext_octet )
Paul Bakker5121ce52009-01-03 21:22:43 +0000703 continue;
704
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000705 if( ( ret = asn1_get_bool( p, end_ext_octet, &is_cacert ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000706 {
Paul Bakker40e46942009-01-03 21:51:57 +0000707 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000708 ret = asn1_get_int( p, end_ext_octet, &is_cacert );
Paul Bakker5121ce52009-01-03 21:22:43 +0000709
710 if( ret != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000711 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000712
713 if( is_cacert != 0 )
714 is_cacert = 1;
715 }
716
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000717 if( *p == end_ext_octet )
Paul Bakker5121ce52009-01-03 21:22:43 +0000718 continue;
719
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000720 if( ( ret = asn1_get_int( p, end_ext_octet, max_pathlen ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000721 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000722
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000723 if( *p != end_ext_octet )
Paul Bakker40e46942009-01-03 21:51:57 +0000724 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
725 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000726
727 max_pathlen++;
728 }
729
730 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000731 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
732 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000733
734 *ca_istrue = is_critical & is_cacert;
735
736 return( 0 );
737}
738
739/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000740 * X.509 CRL Entries
741 */
742static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000743 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000744 x509_crl_entry *entry )
745{
Paul Bakker9be19372009-07-27 20:21:53 +0000746 int ret, entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000747 x509_crl_entry *cur_entry = entry;
748
749 if( *p == end )
750 return( 0 );
751
Paul Bakker9be19372009-07-27 20:21:53 +0000752 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000753 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
754 {
755 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
756 return( 0 );
757
758 return( ret );
759 }
760
Paul Bakker9be19372009-07-27 20:21:53 +0000761 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000762
763 while( *p < end )
764 {
765 int len2;
766
767 if( ( ret = asn1_get_tag( p, end, &len2,
768 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
769 {
Paul Bakkerd98030e2009-05-02 15:13:40 +0000770 return( ret );
771 }
772
Paul Bakker9be19372009-07-27 20:21:53 +0000773 cur_entry->raw.tag = **p;
774 cur_entry->raw.p = *p;
775 cur_entry->raw.len = len2;
776
Paul Bakkerd98030e2009-05-02 15:13:40 +0000777 if( ( ret = x509_get_serial( p, end, &cur_entry->serial ) ) != 0 )
778 return( ret );
779
Paul Bakker91200182010-02-18 21:26:15 +0000780 if( ( ret = x509_get_time( p, end, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000781 return( ret );
782
783 if( ( ret = x509_get_crl_ext( p, end, &cur_entry->entry_ext ) ) != 0 )
784 return( ret );
785
786 if ( *p < end ) {
787 cur_entry->next = malloc( sizeof( x509_crl_entry ) );
788 cur_entry = cur_entry->next;
789 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
790 }
791 }
792
793 return( 0 );
794}
795
Paul Bakker27d66162010-03-17 06:56:01 +0000796static int x509_get_sig_alg( const x509_buf *sig_oid, int *sig_alg )
797{
798 if( sig_oid->len == 9 &&
799 memcmp( sig_oid->p, OID_PKCS1, 8 ) == 0 )
800 {
801 if( sig_oid->p[8] >= 2 && sig_oid->p[8] <= 5 )
802 {
803 *sig_alg = sig_oid->p[8];
804 return( 0 );
805 }
806
807 if ( sig_oid->p[8] >= 11 && sig_oid->p[8] <= 14 )
808 {
809 *sig_alg = sig_oid->p[8];
810 return( 0 );
811 }
812
813 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
814 }
815
816 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
817}
818
Paul Bakkerd98030e2009-05-02 15:13:40 +0000819/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000820 * Parse one or more certificates and add them to the chained list
821 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000822int x509parse_crt( x509_cert *chain, const unsigned char *buf, int buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000823{
824 int ret, len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000825 const unsigned char *s1, *s2;
Paul Bakker5121ce52009-01-03 21:22:43 +0000826 unsigned char *p, *end;
827 x509_cert *crt;
828
829 crt = chain;
830
Paul Bakker320a4b52009-03-28 18:52:39 +0000831 /*
832 * Check for valid input
833 */
834 if( crt == NULL || buf == NULL )
835 return( 1 );
836
Paul Bakkere9581d62009-03-28 20:29:25 +0000837 while( crt->version != 0 && crt->next != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +0000838 crt = crt->next;
839
840 /*
Paul Bakker320a4b52009-03-28 18:52:39 +0000841 * Add new certificate on the end of the chain if needed.
842 */
Paul Bakkere9581d62009-03-28 20:29:25 +0000843 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +0000844 {
845 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
846
Paul Bakker7d06ad22009-05-02 15:53:56 +0000847 if( crt->next == NULL )
848 {
Paul Bakker320a4b52009-03-28 18:52:39 +0000849 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +0000850 return( 1 );
851 }
Paul Bakker320a4b52009-03-28 18:52:39 +0000852
Paul Bakker7d06ad22009-05-02 15:53:56 +0000853 crt = crt->next;
854 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +0000855 }
856
857 /*
Paul Bakker5121ce52009-01-03 21:22:43 +0000858 * check if the certificate is encoded in base64
859 */
860 s1 = (unsigned char *) strstr( (char *) buf,
861 "-----BEGIN CERTIFICATE-----" );
862
863 if( s1 != NULL )
864 {
865 s2 = (unsigned char *) strstr( (char *) buf,
866 "-----END CERTIFICATE-----" );
867
868 if( s2 == NULL || s2 <= s1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000869 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +0000870
871 s1 += 27;
872 if( *s1 == '\r' ) s1++;
873 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +0000874 else return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +0000875
876 /*
877 * get the DER data length and decode the buffer
878 */
879 len = 0;
880 ret = base64_decode( NULL, &len, s1, s2 - s1 );
881
Paul Bakker40e46942009-01-03 21:51:57 +0000882 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
883 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000884
885 if( ( p = (unsigned char *) malloc( len ) ) == NULL )
886 return( 1 );
887
888 if( ( ret = base64_decode( p, &len, s1, s2 - s1 ) ) != 0 )
889 {
890 free( p );
Paul Bakker40e46942009-01-03 21:51:57 +0000891 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000892 }
893
894 /*
895 * update the buffer size and offset
896 */
897 s2 += 25;
898 if( *s2 == '\r' ) s2++;
899 if( *s2 == '\n' ) s2++;
900 else
901 {
902 free( p );
Paul Bakker40e46942009-01-03 21:51:57 +0000903 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +0000904 }
905
906 buflen -= s2 - buf;
907 buf = s2;
908 }
909 else
910 {
911 /*
912 * nope, copy the raw DER data
913 */
914 p = (unsigned char *) malloc( len = buflen );
915
916 if( p == NULL )
917 return( 1 );
918
919 memcpy( p, buf, buflen );
920
921 buflen = 0;
922 }
923
924 crt->raw.p = p;
925 crt->raw.len = len;
926 end = p + len;
927
928 /*
929 * Certificate ::= SEQUENCE {
930 * tbsCertificate TBSCertificate,
931 * signatureAlgorithm AlgorithmIdentifier,
932 * signatureValue BIT STRING }
933 */
934 if( ( ret = asn1_get_tag( &p, end, &len,
935 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
936 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000937 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000938 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +0000939 }
940
941 if( len != (int) ( end - p ) )
942 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000943 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000944 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
945 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000946 }
947
948 /*
949 * TBSCertificate ::= SEQUENCE {
950 */
951 crt->tbs.p = p;
952
953 if( ( ret = asn1_get_tag( &p, end, &len,
954 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
955 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000956 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000957 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000958 }
959
960 end = p + len;
961 crt->tbs.len = end - crt->tbs.p;
962
963 /*
964 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
965 *
966 * CertificateSerialNumber ::= INTEGER
967 *
968 * signature AlgorithmIdentifier
969 */
970 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
971 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
972 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
973 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000974 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +0000975 return( ret );
976 }
977
978 crt->version++;
979
980 if( crt->version > 3 )
981 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000982 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000983 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +0000984 }
985
Paul Bakker27d66162010-03-17 06:56:01 +0000986 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_alg ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000987 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000988 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +0000989 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000990 }
991
992 /*
993 * issuer Name
994 */
995 crt->issuer_raw.p = p;
996
997 if( ( ret = asn1_get_tag( &p, end, &len,
998 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
999 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001000 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001001 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001002 }
1003
1004 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1005 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001006 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001007 return( ret );
1008 }
1009
1010 crt->issuer_raw.len = p - crt->issuer_raw.p;
1011
1012 /*
1013 * Validity ::= SEQUENCE {
1014 * notBefore Time,
1015 * notAfter Time }
1016 *
1017 */
1018 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1019 &crt->valid_to ) ) != 0 )
1020 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001021 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001022 return( ret );
1023 }
1024
1025 /*
1026 * subject Name
1027 */
1028 crt->subject_raw.p = p;
1029
1030 if( ( ret = asn1_get_tag( &p, end, &len,
1031 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1032 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001033 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001034 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001035 }
1036
1037 if( ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
1038 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001039 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001040 return( ret );
1041 }
1042
1043 crt->subject_raw.len = p - crt->subject_raw.p;
1044
1045 /*
1046 * SubjectPublicKeyInfo ::= SEQUENCE
1047 * algorithm AlgorithmIdentifier,
1048 * subjectPublicKey BIT STRING }
1049 */
1050 if( ( ret = asn1_get_tag( &p, end, &len,
1051 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1052 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001053 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001054 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001055 }
1056
1057 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1058 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1059 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001060 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001061 return( ret );
1062 }
1063
1064 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1065 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001066 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001067 return( ret );
1068 }
1069
1070 crt->rsa.len = mpi_size( &crt->rsa.N );
1071
1072 /*
1073 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1074 * -- If present, version shall be v2 or v3
1075 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1076 * -- If present, version shall be v2 or v3
1077 * extensions [3] EXPLICIT Extensions OPTIONAL
1078 * -- If present, version shall be v3
1079 */
1080 if( crt->version == 2 || crt->version == 3 )
1081 {
1082 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1083 if( ret != 0 )
1084 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001085 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001086 return( ret );
1087 }
1088 }
1089
1090 if( crt->version == 2 || crt->version == 3 )
1091 {
1092 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1093 if( ret != 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
1100 if( crt->version == 3 )
1101 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001102 ret = x509_get_crt_ext( &p, end, &crt->v3_ext,
Paul Bakker5121ce52009-01-03 21:22:43 +00001103 &crt->ca_istrue, &crt->max_pathlen );
1104 if( ret != 0 )
1105 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001106 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001107 return( ret );
1108 }
1109 }
1110
1111 if( p != end )
1112 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001113 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001114 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1115 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001116 }
1117
1118 end = crt->raw.p + crt->raw.len;
1119
1120 /*
1121 * signatureAlgorithm AlgorithmIdentifier,
1122 * signatureValue BIT STRING
1123 */
1124 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1125 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001126 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001127 return( ret );
1128 }
1129
Paul Bakker320a4b52009-03-28 18:52:39 +00001130 if( memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001131 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001132 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001133 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001134 }
1135
1136 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1137 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001138 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001139 return( ret );
1140 }
1141
1142 if( p != end )
1143 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001144 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001145 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1146 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001147 }
1148
Paul Bakker5121ce52009-01-03 21:22:43 +00001149 if( buflen > 0 )
Paul Bakker320a4b52009-03-28 18:52:39 +00001150 {
1151 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1152
Paul Bakker7d06ad22009-05-02 15:53:56 +00001153 if( crt->next == NULL )
1154 {
Paul Bakker320a4b52009-03-28 18:52:39 +00001155 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001156 return( 1 );
1157 }
Paul Bakker320a4b52009-03-28 18:52:39 +00001158
Paul Bakker7d06ad22009-05-02 15:53:56 +00001159 crt = crt->next;
1160 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001161
Paul Bakker5121ce52009-01-03 21:22:43 +00001162 return( x509parse_crt( crt, buf, buflen ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001163 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001164
1165 return( 0 );
1166}
1167
1168/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001169 * Parse one or more CRLs and add them to the chained list
1170 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001171int x509parse_crl( x509_crl *chain, const unsigned char *buf, int buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001172{
1173 int ret, len;
1174 unsigned char *s1, *s2;
1175 unsigned char *p, *end;
1176 x509_crl *crl;
1177
1178 crl = chain;
1179
1180 /*
1181 * Check for valid input
1182 */
1183 if( crl == NULL || buf == NULL )
1184 return( 1 );
1185
1186 while( crl->version != 0 && crl->next != NULL )
1187 crl = crl->next;
1188
1189 /*
1190 * Add new CRL on the end of the chain if needed.
1191 */
1192 if ( crl->version != 0 && crl->next == NULL)
1193 {
1194 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1195
Paul Bakker7d06ad22009-05-02 15:53:56 +00001196 if( crl->next == NULL )
1197 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001198 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001199 return( 1 );
1200 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001201
Paul Bakker7d06ad22009-05-02 15:53:56 +00001202 crl = crl->next;
1203 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001204 }
1205
1206 /*
1207 * check if the CRL is encoded in base64
1208 */
1209 s1 = (unsigned char *) strstr( (char *) buf,
1210 "-----BEGIN X509 CRL-----" );
1211
1212 if( s1 != NULL )
1213 {
1214 s2 = (unsigned char *) strstr( (char *) buf,
1215 "-----END X509 CRL-----" );
1216
1217 if( s2 == NULL || s2 <= s1 )
1218 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1219
1220 s1 += 24;
1221 if( *s1 == '\r' ) s1++;
1222 if( *s1 == '\n' ) s1++;
1223 else return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1224
1225 /*
1226 * get the DER data length and decode the buffer
1227 */
1228 len = 0;
1229 ret = base64_decode( NULL, &len, s1, s2 - s1 );
1230
1231 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
1232 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
1233
1234 if( ( p = (unsigned char *) malloc( len ) ) == NULL )
1235 return( 1 );
1236
1237 if( ( ret = base64_decode( p, &len, s1, s2 - s1 ) ) != 0 )
1238 {
1239 free( p );
1240 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
1241 }
1242
1243 /*
1244 * update the buffer size and offset
1245 */
1246 s2 += 22;
1247 if( *s2 == '\r' ) s2++;
1248 if( *s2 == '\n' ) s2++;
1249 else
1250 {
1251 free( p );
1252 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1253 }
1254
1255 buflen -= s2 - buf;
1256 buf = s2;
1257 }
1258 else
1259 {
1260 /*
1261 * nope, copy the raw DER data
1262 */
1263 p = (unsigned char *) malloc( len = buflen );
1264
1265 if( p == NULL )
1266 return( 1 );
1267
1268 memcpy( p, buf, buflen );
1269
1270 buflen = 0;
1271 }
1272
1273 crl->raw.p = p;
1274 crl->raw.len = len;
1275 end = p + len;
1276
1277 /*
1278 * CertificateList ::= SEQUENCE {
1279 * tbsCertList TBSCertList,
1280 * signatureAlgorithm AlgorithmIdentifier,
1281 * signatureValue BIT STRING }
1282 */
1283 if( ( ret = asn1_get_tag( &p, end, &len,
1284 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1285 {
1286 x509_crl_free( crl );
1287 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1288 }
1289
1290 if( len != (int) ( end - p ) )
1291 {
1292 x509_crl_free( crl );
1293 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1294 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1295 }
1296
1297 /*
1298 * TBSCertList ::= SEQUENCE {
1299 */
1300 crl->tbs.p = p;
1301
1302 if( ( ret = asn1_get_tag( &p, end, &len,
1303 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1304 {
1305 x509_crl_free( crl );
1306 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
1307 }
1308
1309 end = p + len;
1310 crl->tbs.len = end - crl->tbs.p;
1311
1312 /*
1313 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1314 * -- if present, MUST be v2
1315 *
1316 * signature AlgorithmIdentifier
1317 */
1318 if( ( ret = x509_get_version( &p, end, &crl->version ) ) != 0 ||
1319 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1320 {
1321 x509_crl_free( crl );
1322 return( ret );
1323 }
1324
1325 crl->version++;
1326
1327 if( crl->version > 2 )
1328 {
1329 x509_crl_free( crl );
1330 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1331 }
1332
Paul Bakker27d66162010-03-17 06:56:01 +00001333 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_alg ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001334 {
1335 x509_crl_free( crl );
1336 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1337 }
1338
1339 /*
1340 * issuer Name
1341 */
1342 crl->issuer_raw.p = p;
1343
1344 if( ( ret = asn1_get_tag( &p, end, &len,
1345 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1346 {
1347 x509_crl_free( crl );
1348 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
1349 }
1350
1351 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1352 {
1353 x509_crl_free( crl );
1354 return( ret );
1355 }
1356
1357 crl->issuer_raw.len = p - crl->issuer_raw.p;
1358
1359 /*
1360 * thisUpdate Time
1361 * nextUpdate Time OPTIONAL
1362 */
Paul Bakker91200182010-02-18 21:26:15 +00001363 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001364 {
1365 x509_crl_free( crl );
1366 return( ret );
1367 }
1368
Paul Bakker91200182010-02-18 21:26:15 +00001369 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001370 {
Paul Bakker635f4b42009-07-20 20:34:41 +00001371 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE |
Paul Bakker9be19372009-07-27 20:21:53 +00001372 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
1373 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE |
1374 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001375 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001376 x509_crl_free( crl );
1377 return( ret );
1378 }
1379 }
1380
1381 /*
1382 * revokedCertificates SEQUENCE OF SEQUENCE {
1383 * userCertificate CertificateSerialNumber,
1384 * revocationDate Time,
1385 * crlEntryExtensions Extensions OPTIONAL
1386 * -- if present, MUST be v2
1387 * } OPTIONAL
1388 */
1389 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1390 {
1391 x509_crl_free( crl );
1392 return( ret );
1393 }
1394
1395 /*
1396 * crlExtensions EXPLICIT Extensions OPTIONAL
1397 * -- if present, MUST be v2
1398 */
1399 if( crl->version == 2 )
1400 {
1401 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1402
1403 if( ret != 0 )
1404 {
1405 x509_crl_free( crl );
1406 return( ret );
1407 }
1408 }
1409
1410 if( p != end )
1411 {
1412 x509_crl_free( crl );
1413 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1414 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1415 }
1416
1417 end = crl->raw.p + crl->raw.len;
1418
1419 /*
1420 * signatureAlgorithm AlgorithmIdentifier,
1421 * signatureValue BIT STRING
1422 */
1423 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1424 {
1425 x509_crl_free( crl );
1426 return( ret );
1427 }
1428
1429 if( memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
1430 {
1431 x509_crl_free( crl );
1432 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1433 }
1434
1435 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1436 {
1437 x509_crl_free( crl );
1438 return( ret );
1439 }
1440
1441 if( p != end )
1442 {
1443 x509_crl_free( crl );
1444 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1445 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1446 }
1447
1448 if( buflen > 0 )
1449 {
1450 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1451
Paul Bakker7d06ad22009-05-02 15:53:56 +00001452 if( crl->next == NULL )
1453 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001454 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001455 return( 1 );
1456 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001457
Paul Bakker7d06ad22009-05-02 15:53:56 +00001458 crl = crl->next;
1459 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001460
1461 return( x509parse_crl( crl, buf, buflen ) );
1462 }
1463
1464 return( 0 );
1465}
1466
1467/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001468 * Load all data from a file into a given buffer.
1469 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001470int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001471{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001472 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001473
Paul Bakkerd98030e2009-05-02 15:13:40 +00001474 if( ( f = fopen( path, "rb" ) ) == NULL )
1475 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001476
Paul Bakkerd98030e2009-05-02 15:13:40 +00001477 fseek( f, 0, SEEK_END );
1478 *n = (size_t) ftell( f );
1479 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001480
Paul Bakkerd98030e2009-05-02 15:13:40 +00001481 if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
1482 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001483
Paul Bakkerd98030e2009-05-02 15:13:40 +00001484 if( fread( *buf, 1, *n, f ) != *n )
1485 {
1486 fclose( f );
1487 free( *buf );
1488 return( 1 );
1489 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001490
Paul Bakkerd98030e2009-05-02 15:13:40 +00001491 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001492
Paul Bakkerd98030e2009-05-02 15:13:40 +00001493 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001494
Paul Bakkerd98030e2009-05-02 15:13:40 +00001495 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001496}
1497
1498/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001499 * Load one or more certificates and add them to the chained list
1500 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001501int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001502{
1503 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001504 size_t n;
1505 unsigned char *buf;
1506
Paul Bakker2b245eb2009-04-19 18:44:26 +00001507 if ( load_file( path, &buf, &n ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001508 return( 1 );
1509
Paul Bakker5121ce52009-01-03 21:22:43 +00001510 ret = x509parse_crt( chain, buf, (int) n );
1511
1512 memset( buf, 0, n + 1 );
1513 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001514
1515 return( ret );
1516}
1517
Paul Bakkerd98030e2009-05-02 15:13:40 +00001518/*
1519 * Load one or more CRLs and add them to the chained list
1520 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001521int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001522{
1523 int ret;
1524 size_t n;
1525 unsigned char *buf;
1526
1527 if ( load_file( path, &buf, &n ) )
1528 return( 1 );
1529
1530 ret = x509parse_crl( chain, buf, (int) n );
1531
1532 memset( buf, 0, n + 1 );
1533 free( buf );
1534
1535 return( ret );
1536}
1537
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001538#if defined(POLARSSL_DES_C) && defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001539/*
1540 * Read a 16-byte hex string and convert it to binary
1541 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001542static int x509_get_iv( const unsigned char *s, unsigned char iv[8] )
Paul Bakker5121ce52009-01-03 21:22:43 +00001543{
1544 int i, j, k;
1545
1546 memset( iv, 0, 8 );
1547
1548 for( i = 0; i < 16; i++, s++ )
1549 {
1550 if( *s >= '0' && *s <= '9' ) j = *s - '0'; else
1551 if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else
1552 if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else
Paul Bakker40e46942009-01-03 21:51:57 +00001553 return( POLARSSL_ERR_X509_KEY_INVALID_ENC_IV );
Paul Bakker5121ce52009-01-03 21:22:43 +00001554
1555 k = ( ( i & 1 ) != 0 ) ? j : j << 4;
1556
1557 iv[i >> 1] = (unsigned char)( iv[i >> 1] | k );
1558 }
1559
1560 return( 0 );
1561}
1562
1563/*
1564 * Decrypt with 3DES-CBC, using PBKDF1 for key derivation
1565 */
1566static void x509_des3_decrypt( unsigned char des3_iv[8],
1567 unsigned char *buf, int buflen,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001568 const unsigned char *pwd, int pwdlen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001569{
1570 md5_context md5_ctx;
1571 des3_context des3_ctx;
1572 unsigned char md5sum[16];
1573 unsigned char des3_key[24];
1574
1575 /*
1576 * 3DES key[ 0..15] = MD5(pwd || IV)
1577 * key[16..23] = MD5(pwd || IV || 3DES key[ 0..15])
1578 */
1579 md5_starts( &md5_ctx );
1580 md5_update( &md5_ctx, pwd, pwdlen );
1581 md5_update( &md5_ctx, des3_iv, 8 );
1582 md5_finish( &md5_ctx, md5sum );
1583 memcpy( des3_key, md5sum, 16 );
1584
1585 md5_starts( &md5_ctx );
1586 md5_update( &md5_ctx, md5sum, 16 );
1587 md5_update( &md5_ctx, pwd, pwdlen );
1588 md5_update( &md5_ctx, des3_iv, 8 );
1589 md5_finish( &md5_ctx, md5sum );
1590 memcpy( des3_key + 16, md5sum, 8 );
1591
1592 des3_set3key_dec( &des3_ctx, des3_key );
1593 des3_crypt_cbc( &des3_ctx, DES_DECRYPT, buflen,
1594 des3_iv, buf, buf );
1595
1596 memset( &md5_ctx, 0, sizeof( md5_ctx ) );
1597 memset( &des3_ctx, 0, sizeof( des3_ctx ) );
1598 memset( md5sum, 0, 16 );
1599 memset( des3_key, 0, 24 );
1600}
1601#endif
1602
1603/*
1604 * Parse a private RSA key
1605 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001606int x509parse_key( rsa_context *rsa, const unsigned char *key, int keylen,
1607 const unsigned char *pwd, int pwdlen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001608{
1609 int ret, len, enc;
Paul Bakkerff60ee62010-03-16 21:09:09 +00001610 unsigned char *buf, *s1, *s2;
Paul Bakker5121ce52009-01-03 21:22:43 +00001611 unsigned char *p, *end;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001612#if defined(POLARSSL_DES_C) && defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001613 unsigned char des3_iv[8];
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001614#else
1615 ((void) pwd);
1616 ((void) pwdlen);
1617#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001618
Paul Bakkerff60ee62010-03-16 21:09:09 +00001619 s1 = (unsigned char *) strstr( (char *) key,
Paul Bakker5121ce52009-01-03 21:22:43 +00001620 "-----BEGIN RSA PRIVATE KEY-----" );
1621
1622 if( s1 != NULL )
1623 {
Paul Bakkerff60ee62010-03-16 21:09:09 +00001624 s2 = (unsigned char *) strstr( (char *) key,
Paul Bakker5121ce52009-01-03 21:22:43 +00001625 "-----END RSA PRIVATE KEY-----" );
1626
1627 if( s2 == NULL || s2 <= s1 )
Paul Bakker40e46942009-01-03 21:51:57 +00001628 return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001629
1630 s1 += 31;
1631 if( *s1 == '\r' ) s1++;
1632 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001633 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001634
1635 enc = 0;
1636
1637 if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
1638 {
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001639#if defined(POLARSSL_DES_C) && defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001640 enc++;
1641
1642 s1 += 22;
1643 if( *s1 == '\r' ) s1++;
1644 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001645 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001646
1647 if( memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001648 return( POLARSSL_ERR_X509_KEY_UNKNOWN_ENC_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +00001649
1650 s1 += 23;
1651 if( x509_get_iv( s1, des3_iv ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001652 return( POLARSSL_ERR_X509_KEY_INVALID_ENC_IV );
Paul Bakker5121ce52009-01-03 21:22:43 +00001653
1654 s1 += 16;
1655 if( *s1 == '\r' ) s1++;
1656 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001657 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001658#else
Paul Bakker40e46942009-01-03 21:51:57 +00001659 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001660#endif
1661 }
1662
1663 len = 0;
1664 ret = base64_decode( NULL, &len, s1, s2 - s1 );
1665
Paul Bakker40e46942009-01-03 21:51:57 +00001666 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
1667 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001668
1669 if( ( buf = (unsigned char *) malloc( len ) ) == NULL )
1670 return( 1 );
1671
1672 if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
1673 {
1674 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001675 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001676 }
1677
Paul Bakkerff60ee62010-03-16 21:09:09 +00001678 keylen = len;
Paul Bakker5121ce52009-01-03 21:22:43 +00001679
1680 if( enc != 0 )
1681 {
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001682#if defined(POLARSSL_DES_C) && defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001683 if( pwd == NULL )
1684 {
1685 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001686 return( POLARSSL_ERR_X509_KEY_PASSWORD_REQUIRED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001687 }
1688
Paul Bakkerff60ee62010-03-16 21:09:09 +00001689 x509_des3_decrypt( des3_iv, buf, keylen, pwd, pwdlen );
Paul Bakker5121ce52009-01-03 21:22:43 +00001690
1691 if( buf[0] != 0x30 || buf[1] != 0x82 ||
1692 buf[4] != 0x02 || buf[5] != 0x01 )
1693 {
1694 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001695 return( POLARSSL_ERR_X509_KEY_PASSWORD_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001696 }
1697#else
Paul Bakker40e46942009-01-03 21:51:57 +00001698 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001699#endif
1700 }
1701 }
Paul Bakkerff60ee62010-03-16 21:09:09 +00001702 else
1703 {
1704 buf = NULL;
1705 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001706
1707 memset( rsa, 0, sizeof( rsa_context ) );
1708
Paul Bakkerff60ee62010-03-16 21:09:09 +00001709 p = ( s1 != NULL ) ? buf : (unsigned char *) key;
1710 end = p + keylen;
Paul Bakker5121ce52009-01-03 21:22:43 +00001711
1712 /*
1713 * RSAPrivateKey ::= SEQUENCE {
1714 * version Version,
1715 * modulus INTEGER, -- n
1716 * publicExponent INTEGER, -- e
1717 * privateExponent INTEGER, -- d
1718 * prime1 INTEGER, -- p
1719 * prime2 INTEGER, -- q
1720 * exponent1 INTEGER, -- d mod (p-1)
1721 * exponent2 INTEGER, -- d mod (q-1)
1722 * coefficient INTEGER, -- (inverse of q) mod p
1723 * otherPrimeInfos OtherPrimeInfos OPTIONAL
1724 * }
1725 */
1726 if( ( ret = asn1_get_tag( &p, end, &len,
1727 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1728 {
1729 if( s1 != NULL )
1730 free( buf );
1731
1732 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001733 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001734 }
1735
1736 end = p + len;
1737
1738 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
1739 {
1740 if( s1 != NULL )
1741 free( buf );
1742
1743 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001744 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001745 }
1746
1747 if( rsa->ver != 0 )
1748 {
1749 if( s1 != NULL )
1750 free( buf );
1751
1752 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001753 return( ret | POLARSSL_ERR_X509_KEY_INVALID_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001754 }
1755
1756 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
1757 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
1758 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
1759 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
1760 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
1761 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
1762 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
1763 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
1764 {
1765 if( s1 != NULL )
1766 free( buf );
1767
1768 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001769 return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001770 }
1771
1772 rsa->len = mpi_size( &rsa->N );
1773
1774 if( p != end )
1775 {
1776 if( s1 != NULL )
1777 free( buf );
1778
1779 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001780 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT |
1781 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001782 }
1783
1784 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
1785 {
1786 if( s1 != NULL )
1787 free( buf );
1788
1789 rsa_free( rsa );
1790 return( ret );
1791 }
1792
1793 if( s1 != NULL )
1794 free( buf );
1795
1796 return( 0 );
1797}
1798
1799/*
1800 * Load and parse a private RSA key
1801 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001802int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
Paul Bakker5121ce52009-01-03 21:22:43 +00001803{
1804 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001805 size_t n;
1806 unsigned char *buf;
1807
Paul Bakker2b245eb2009-04-19 18:44:26 +00001808 if ( load_file( path, &buf, &n ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001809 return( 1 );
1810
Paul Bakker5121ce52009-01-03 21:22:43 +00001811 if( pwd == NULL )
1812 ret = x509parse_key( rsa, buf, (int) n, NULL, 0 );
1813 else
1814 ret = x509parse_key( rsa, buf, (int) n,
1815 (unsigned char *) pwd, strlen( pwd ) );
1816
1817 memset( buf, 0, n + 1 );
1818 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001819
1820 return( ret );
1821}
1822
Paul Bakker1b57b062011-01-06 15:48:19 +00001823/*
1824 * Parse DHM parameters
1825 */
1826int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, int dhminlen )
1827{
1828 int ret, len;
1829 unsigned char *buf, *s1, *s2;
1830 unsigned char *p, *end;
1831
1832 s1 = (unsigned char *) strstr( (char *) dhmin,
1833 "-----BEGIN DH PARAMETERS-----" );
1834
1835 if( s1 != NULL )
1836 {
1837 s2 = (unsigned char *) strstr( (char *) dhmin,
1838 "-----END DH PARAMETERS-----" );
1839
1840 if( s2 == NULL || s2 <= s1 )
1841 return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
1842
1843 s1 += 29;
1844 if( *s1 == '\r' ) s1++;
1845 if( *s1 == '\n' ) s1++;
1846 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
1847
1848 len = 0;
1849 ret = base64_decode( NULL, &len, s1, s2 - s1 );
1850
1851 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
1852 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
1853
1854 if( ( buf = (unsigned char *) malloc( len ) ) == NULL )
1855 return( 1 );
1856
1857 if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
1858 {
1859 free( buf );
1860 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
1861 }
1862
1863 dhminlen = len;
1864 }
1865 else
1866 {
1867 buf = NULL;
1868 }
1869
1870 memset( dhm, 0, sizeof( dhm_context ) );
1871
1872 p = ( s1 != NULL ) ? buf : (unsigned char *) dhmin;
1873 end = p + dhminlen;
1874
1875 /*
1876 * DHParams ::= SEQUENCE {
1877 * prime INTEGER, -- P
1878 * generator INTEGER, -- g
1879 * }
1880 */
1881 if( ( ret = asn1_get_tag( &p, end, &len,
1882 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1883 {
1884 if( s1 != NULL )
1885 free( buf );
1886
1887 dhm_free( dhm );
1888 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
1889 }
1890
1891 end = p + len;
1892
1893 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
1894 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
1895 {
1896 if( s1 != NULL )
1897 free( buf );
1898
1899 dhm_free( dhm );
1900 return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
1901 }
1902
1903 if( p != end )
1904 {
1905 if( s1 != NULL )
1906 free( buf );
1907
1908 dhm_free( dhm );
1909 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT |
1910 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1911 }
1912
1913 if( s1 != NULL )
1914 free( buf );
1915
1916 return( 0 );
1917}
1918
1919/*
1920 * Load and parse a private RSA key
1921 */
1922int x509parse_dhmfile( dhm_context *dhm, const char *path )
1923{
1924 int ret;
1925 size_t n;
1926 unsigned char *buf;
1927
1928 if ( load_file( path, &buf, &n ) )
1929 return( 1 );
1930
1931 ret = x509parse_dhm( dhm, buf, (int) n);
1932
1933 memset( buf, 0, n + 1 );
1934 free( buf );
1935
1936 return( ret );
1937}
1938
Paul Bakker5121ce52009-01-03 21:22:43 +00001939#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00001940#include <stdarg.h>
1941
1942#if !defined vsnprintf
1943#define vsnprintf _vsnprintf
1944#endif // vsnprintf
1945
1946/*
1947 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
1948 * Result value is not size of buffer needed, but -1 if no fit is possible.
1949 *
1950 * This fuction tries to 'fix' this by at least suggesting enlarging the
1951 * size by 20.
1952 */
1953int compat_snprintf(char *str, size_t size, const char *format, ...)
1954{
1955 va_list ap;
1956 int res = -1;
1957
1958 va_start( ap, format );
1959
1960 res = vsnprintf( str, size, format, ap );
1961
1962 va_end( ap );
1963
1964 // No quick fix possible
1965 if ( res < 0 )
1966 return( size + 20 );
1967
1968 return res;
1969}
1970
1971#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00001972#endif
1973
Paul Bakkerd98030e2009-05-02 15:13:40 +00001974#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
1975
1976#define SAFE_SNPRINTF() \
1977{ \
1978 if( ret == -1 ) \
1979 return( -1 ); \
1980 \
1981 if ( ret > n ) { \
1982 p[n - 1] = '\0'; \
1983 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
1984 } \
1985 \
1986 n -= ret; \
1987 p += ret; \
1988}
1989
Paul Bakker5121ce52009-01-03 21:22:43 +00001990/*
1991 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00001992 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00001993 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001994int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00001995{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001996 int i, ret, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00001997 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00001998 const x509_name *name;
Paul Bakker5121ce52009-01-03 21:22:43 +00001999 char s[128], *p;
2000
2001 memset( s, 0, sizeof( s ) );
2002
2003 name = dn;
2004 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002005 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002006
2007 while( name != NULL )
2008 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002009 if( name != dn ) {
2010 ret = snprintf( p, n, ", " );
2011 SAFE_SNPRINTF();
2012 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002013
2014 if( memcmp( name->oid.p, OID_X520, 2 ) == 0 )
2015 {
2016 switch( name->oid.p[2] )
2017 {
2018 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002019 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002020
2021 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002022 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002023
2024 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002025 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002026
2027 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002028 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002029
2030 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002031 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002032
2033 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002034 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002035
2036 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002037 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002038 name->oid.p[2] );
2039 break;
2040 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002041 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002042 }
2043 else if( memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
2044 {
2045 switch( name->oid.p[8] )
2046 {
2047 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002048 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002049
2050 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002051 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002052 name->oid.p[8] );
2053 break;
2054 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002055 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002056 }
2057 else
Paul Bakkerd98030e2009-05-02 15:13:40 +00002058 {
2059 ret = snprintf( p, n, "\?\?=" );
2060 SAFE_SNPRINTF();
2061 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002062
2063 for( i = 0; i < name->val.len; i++ )
2064 {
2065 if( i >= (int) sizeof( s ) - 1 )
2066 break;
2067
2068 c = name->val.p[i];
2069 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2070 s[i] = '?';
2071 else s[i] = c;
2072 }
2073 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002074 ret = snprintf( p, n, "%s", s );
2075 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002076 name = name->next;
2077 }
2078
Paul Bakkerd98030e2009-05-02 15:13:40 +00002079 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002080}
2081
2082/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002083 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002084 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002085int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2086 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002087{
Paul Bakkerd98030e2009-05-02 15:13:40 +00002088 int i, n, nr, ret;
2089 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00002090
2091 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002092 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002093
Paul Bakkerd98030e2009-05-02 15:13:40 +00002094 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002095 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002096 SAFE_SNPRINTF();
2097 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002098 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002099 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002100
Paul Bakkerd98030e2009-05-02 15:13:40 +00002101 nr = ( crt->serial.len <= 32 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002102 ? crt->serial.len : 32;
2103
Paul Bakkerd98030e2009-05-02 15:13:40 +00002104 for( i = 0; i < nr; i++ )
2105 {
2106 ret = snprintf( p, n, "%02X%s",
2107 crt->serial.p[i], ( i < nr - 1 ) ? ":" : "" );
2108 SAFE_SNPRINTF();
2109 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002110
Paul Bakkerd98030e2009-05-02 15:13:40 +00002111 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2112 SAFE_SNPRINTF();
2113 ret = x509parse_dn_gets( p, n, &crt->issuer );
2114 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002115
Paul Bakkerd98030e2009-05-02 15:13:40 +00002116 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2117 SAFE_SNPRINTF();
2118 ret = x509parse_dn_gets( p, n, &crt->subject );
2119 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002120
Paul Bakkerd98030e2009-05-02 15:13:40 +00002121 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002122 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2123 crt->valid_from.year, crt->valid_from.mon,
2124 crt->valid_from.day, crt->valid_from.hour,
2125 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002126 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002127
Paul Bakkerd98030e2009-05-02 15:13:40 +00002128 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002129 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2130 crt->valid_to.year, crt->valid_to.mon,
2131 crt->valid_to.day, crt->valid_to.hour,
2132 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002133 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002134
Paul Bakkerd98030e2009-05-02 15:13:40 +00002135 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2136 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002137
Paul Bakker27d66162010-03-17 06:56:01 +00002138 switch( crt->sig_alg )
Paul Bakker5121ce52009-01-03 21:22:43 +00002139 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002140 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2141 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2142 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2143 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2144 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2145 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2146 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2147 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2148 default: ret = snprintf( p, n, "???" ); break;
2149 }
2150 SAFE_SNPRINTF();
2151
2152 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
2153 crt->rsa.N.n * (int) sizeof( unsigned long ) * 8 );
2154 SAFE_SNPRINTF();
2155
2156 return( size - n );
2157}
2158
2159/*
2160 * Return an informational string about the CRL.
2161 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002162int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2163 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002164{
2165 int i, n, nr, ret;
2166 char *p;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002167 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002168
2169 p = buf;
2170 n = size;
2171
2172 ret = snprintf( p, n, "%sCRL version : %d",
2173 prefix, crl->version );
2174 SAFE_SNPRINTF();
2175
2176 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2177 SAFE_SNPRINTF();
2178 ret = x509parse_dn_gets( p, n, &crl->issuer );
2179 SAFE_SNPRINTF();
2180
2181 ret = snprintf( p, n, "\n%sthis update : " \
2182 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2183 crl->this_update.year, crl->this_update.mon,
2184 crl->this_update.day, crl->this_update.hour,
2185 crl->this_update.min, crl->this_update.sec );
2186 SAFE_SNPRINTF();
2187
2188 ret = snprintf( p, n, "\n%snext update : " \
2189 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2190 crl->next_update.year, crl->next_update.mon,
2191 crl->next_update.day, crl->next_update.hour,
2192 crl->next_update.min, crl->next_update.sec );
2193 SAFE_SNPRINTF();
2194
2195 entry = &crl->entry;
2196
2197 ret = snprintf( p, n, "\n%sRevoked certificates:",
2198 prefix );
2199 SAFE_SNPRINTF();
2200
Paul Bakker9be19372009-07-27 20:21:53 +00002201 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002202 {
2203 ret = snprintf( p, n, "\n%sserial number: ",
2204 prefix );
2205 SAFE_SNPRINTF();
2206
2207 nr = ( entry->serial.len <= 32 )
2208 ? entry->serial.len : 32;
2209
2210 for( i = 0; i < nr; i++ ) {
2211 ret = snprintf( p, n, "%02X%s",
2212 entry->serial.p[i], ( i < nr - 1 ) ? ":" : "" );
2213 SAFE_SNPRINTF();
2214 }
2215
2216 ret = snprintf( p, n, " revocation date: " \
2217 "%04d-%02d-%02d %02d:%02d:%02d",
2218 entry->revocation_date.year, entry->revocation_date.mon,
2219 entry->revocation_date.day, entry->revocation_date.hour,
2220 entry->revocation_date.min, entry->revocation_date.sec );
2221 SAFE_SNPRINTF();
2222
2223 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002224 }
2225
Paul Bakkerd98030e2009-05-02 15:13:40 +00002226 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2227 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002228
Paul Bakker27d66162010-03-17 06:56:01 +00002229 switch( crl->sig_alg )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002230 {
2231 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2232 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2233 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2234 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2235 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2236 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2237 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2238 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2239 default: ret = snprintf( p, n, "???" ); break;
2240 }
2241 SAFE_SNPRINTF();
2242
Paul Bakker1e27bb22009-07-19 20:25:25 +00002243 ret = snprintf( p, n, "\n" );
2244 SAFE_SNPRINTF();
2245
Paul Bakkerd98030e2009-05-02 15:13:40 +00002246 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002247}
2248
2249/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00002250 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00002251 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002252int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00002253{
2254 struct tm *lt;
2255 time_t tt;
2256
2257 tt = time( NULL );
2258 lt = localtime( &tt );
2259
Paul Bakker40ea7de2009-05-03 10:18:48 +00002260 if( lt->tm_year > to->year - 1900 )
2261 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002262
Paul Bakker40ea7de2009-05-03 10:18:48 +00002263 if( lt->tm_year == to->year - 1900 &&
2264 lt->tm_mon > to->mon - 1 )
2265 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002266
Paul Bakker40ea7de2009-05-03 10:18:48 +00002267 if( lt->tm_year == to->year - 1900 &&
2268 lt->tm_mon == to->mon - 1 &&
2269 lt->tm_mday > to->day )
2270 return( 1 );
2271
2272 return( 0 );
2273}
2274
2275/*
2276 * Return 1 if the certificate is revoked, or 0 otherwise.
2277 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002278int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002279{
Paul Bakkerff60ee62010-03-16 21:09:09 +00002280 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00002281
2282 while( cur != NULL && cur->serial.len != 0 )
2283 {
2284 if( memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
2285 {
2286 if( x509parse_time_expired( &cur->revocation_date ) )
2287 return( 1 );
2288 }
2289
2290 cur = cur->next;
2291 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002292
2293 return( 0 );
2294}
2295
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002296/*
2297 * Wrapper for x509 hashes.
2298 *
2299 * @param out Buffer to receive the hash (Should be at least 64 bytes)
2300 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002301static void x509_hash( const unsigned char *in, int len, int alg,
Paul Bakker5121ce52009-01-03 21:22:43 +00002302 unsigned char *out )
2303{
2304 switch( alg )
2305 {
Paul Bakker40e46942009-01-03 21:51:57 +00002306#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002307 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002308#endif
Paul Bakker40e46942009-01-03 21:51:57 +00002309#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002310 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002311#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002312#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002313 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002314#endif
2315#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002316 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002317#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00002318#if defined(POLARSSL_SHA2_C)
2319 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
2320 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
2321#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00002322#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002323 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
2324 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
2325#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002326 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002327 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002328 break;
2329 }
2330}
2331
2332/*
2333 * Verify the certificate validity
2334 */
2335int x509parse_verify( x509_cert *crt,
2336 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00002337 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002338 const char *cn, int *flags,
2339 int (*f_vrfy)(void *, x509_cert *, int, int),
2340 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00002341{
2342 int cn_len;
2343 int hash_id;
2344 int pathlen;
2345 x509_cert *cur;
2346 x509_name *name;
Paul Bakker4593aea2009-02-09 22:32:35 +00002347 unsigned char hash[64];
Paul Bakker5121ce52009-01-03 21:22:43 +00002348
Paul Bakker40ea7de2009-05-03 10:18:48 +00002349 *flags = 0;
2350
2351 if( x509parse_time_expired( &crt->valid_to ) )
2352 *flags = BADCERT_EXPIRED;
Paul Bakker5121ce52009-01-03 21:22:43 +00002353
2354 if( cn != NULL )
2355 {
2356 name = &crt->subject;
2357 cn_len = strlen( cn );
2358
2359 while( name != NULL )
2360 {
2361 if( memcmp( name->oid.p, OID_CN, 3 ) == 0 &&
2362 memcmp( name->val.p, cn, cn_len ) == 0 &&
2363 name->val.len == cn_len )
2364 break;
2365
2366 name = name->next;
2367 }
2368
2369 if( name == NULL )
2370 *flags |= BADCERT_CN_MISMATCH;
2371 }
2372
2373 *flags |= BADCERT_NOT_TRUSTED;
2374
2375 /*
2376 * Iterate upwards in the given cert chain,
2377 * ignoring any upper cert with CA != TRUE.
2378 */
2379 cur = crt->next;
2380
2381 pathlen = 1;
2382
Paul Bakker7c6d4a42009-03-28 20:35:47 +00002383 while( cur != NULL && cur->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002384 {
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002385 int verify_ok = 1;
2386
Paul Bakker5121ce52009-01-03 21:22:43 +00002387 if( cur->ca_istrue == 0 ||
2388 crt->issuer_raw.len != cur->subject_raw.len ||
2389 memcmp( crt->issuer_raw.p, cur->subject_raw.p,
2390 crt->issuer_raw.len ) != 0 )
2391 {
2392 cur = cur->next;
2393 continue;
2394 }
2395
Paul Bakker27d66162010-03-17 06:56:01 +00002396 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00002397
2398 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2399
2400 if( rsa_pkcs1_verify( &cur->rsa, RSA_PUBLIC, hash_id,
2401 0, hash, crt->sig.p ) != 0 )
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002402 verify_ok = 0;
2403
2404 /* crt is verified to be a child of the parent cur, call verify callback */
2405 if( NULL != f_vrfy ) {
2406 if ( f_vrfy( p_vrfy, crt, pathlen-1, verify_ok ) != 0 )
2407 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
2408 } else if ( verify_ok == 0 ) {
Paul Bakker40e46942009-01-03 21:51:57 +00002409 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002410 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002411
2412 pathlen++;
2413
2414 crt = cur;
2415 cur = crt->next;
2416 }
2417
2418 /*
2419 * Atempt to validate topmost cert with our CA chain.
2420 */
Paul Bakker7c6d4a42009-03-28 20:35:47 +00002421 while( trust_ca != NULL && trust_ca->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002422 {
2423 if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
2424 memcmp( crt->issuer_raw.p, trust_ca->subject_raw.p,
2425 crt->issuer_raw.len ) != 0 )
2426 {
2427 trust_ca = trust_ca->next;
2428 continue;
2429 }
2430
2431 if( trust_ca->max_pathlen > 0 &&
2432 trust_ca->max_pathlen < pathlen )
2433 break;
2434
Paul Bakker27d66162010-03-17 06:56:01 +00002435 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00002436
2437 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2438
2439 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
2440 0, hash, crt->sig.p ) == 0 )
2441 {
2442 /*
2443 * cert. is signed by a trusted CA
2444 */
2445 *flags &= ~BADCERT_NOT_TRUSTED;
2446 break;
2447 }
2448
2449 trust_ca = trust_ca->next;
2450 }
2451
Paul Bakker40ea7de2009-05-03 10:18:48 +00002452 /*
2453 * TODO: What happens if no CRL is present?
2454 * Suggestion: Revocation state should be unknown if no CRL is present.
2455 * For backwards compatibility this is not yet implemented.
2456 */
2457
2458 /*
2459 * Check if the topmost certificate is revoked if the trusted CA is
2460 * determined.
2461 */
2462 while( trust_ca != NULL && ca_crl != NULL && ca_crl->version != 0 )
2463 {
2464 if( ca_crl->issuer_raw.len != trust_ca->subject_raw.len ||
2465 memcmp( ca_crl->issuer_raw.p, trust_ca->subject_raw.p,
2466 ca_crl->issuer_raw.len ) != 0 )
2467 {
2468 ca_crl = ca_crl->next;
2469 continue;
2470 }
2471
2472 /*
2473 * Check if CRL is correctry signed by the trusted CA
2474 */
Paul Bakker27d66162010-03-17 06:56:01 +00002475 hash_id = ca_crl->sig_alg;
Paul Bakker40ea7de2009-05-03 10:18:48 +00002476
2477 x509_hash( ca_crl->tbs.p, ca_crl->tbs.len, hash_id, hash );
2478
2479 if( !rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
2480 0, hash, ca_crl->sig.p ) == 0 )
2481 {
2482 /*
2483 * CRL is not trusted
2484 */
2485 *flags |= BADCRL_NOT_TRUSTED;
2486 break;
2487 }
2488
2489 /*
2490 * Check for validity of CRL (Do not drop out)
2491 */
2492 if( x509parse_time_expired( &ca_crl->next_update ) )
2493 *flags |= BADCRL_EXPIRED;
2494
2495 /*
2496 * Check if certificate is revoked
2497 */
2498 if( x509parse_revoked(crt, ca_crl) )
2499 {
2500 *flags |= BADCERT_REVOKED;
2501 break;
2502 }
2503
2504 ca_crl = ca_crl->next;
2505 }
2506
Paul Bakker5121ce52009-01-03 21:22:43 +00002507 if( *flags != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00002508 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002509
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002510
2511 /* Verification succeeded, call callback on top cert */
2512 if( NULL != f_vrfy ) {
2513 if ( f_vrfy(p_vrfy, crt, pathlen - 1, 1) != 0 )
2514 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
2515 }
2516
Paul Bakker5121ce52009-01-03 21:22:43 +00002517 return( 0 );
2518}
2519
2520/*
2521 * Unallocate all certificate data
2522 */
2523void x509_free( x509_cert *crt )
2524{
2525 x509_cert *cert_cur = crt;
2526 x509_cert *cert_prv;
2527 x509_name *name_cur;
2528 x509_name *name_prv;
2529
2530 if( crt == NULL )
2531 return;
2532
2533 do
2534 {
2535 rsa_free( &cert_cur->rsa );
2536
2537 name_cur = cert_cur->issuer.next;
2538 while( name_cur != NULL )
2539 {
2540 name_prv = name_cur;
2541 name_cur = name_cur->next;
2542 memset( name_prv, 0, sizeof( x509_name ) );
2543 free( name_prv );
2544 }
2545
2546 name_cur = cert_cur->subject.next;
2547 while( name_cur != NULL )
2548 {
2549 name_prv = name_cur;
2550 name_cur = name_cur->next;
2551 memset( name_prv, 0, sizeof( x509_name ) );
2552 free( name_prv );
2553 }
2554
2555 if( cert_cur->raw.p != NULL )
2556 {
2557 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
2558 free( cert_cur->raw.p );
2559 }
2560
2561 cert_cur = cert_cur->next;
2562 }
2563 while( cert_cur != NULL );
2564
2565 cert_cur = crt;
2566 do
2567 {
2568 cert_prv = cert_cur;
2569 cert_cur = cert_cur->next;
2570
2571 memset( cert_prv, 0, sizeof( x509_cert ) );
2572 if( cert_prv != crt )
2573 free( cert_prv );
2574 }
2575 while( cert_cur != NULL );
2576}
2577
Paul Bakkerd98030e2009-05-02 15:13:40 +00002578/*
2579 * Unallocate all CRL data
2580 */
2581void x509_crl_free( x509_crl *crl )
2582{
2583 x509_crl *crl_cur = crl;
2584 x509_crl *crl_prv;
2585 x509_name *name_cur;
2586 x509_name *name_prv;
2587 x509_crl_entry *entry_cur;
2588 x509_crl_entry *entry_prv;
2589
2590 if( crl == NULL )
2591 return;
2592
2593 do
2594 {
2595 name_cur = crl_cur->issuer.next;
2596 while( name_cur != NULL )
2597 {
2598 name_prv = name_cur;
2599 name_cur = name_cur->next;
2600 memset( name_prv, 0, sizeof( x509_name ) );
2601 free( name_prv );
2602 }
2603
2604 entry_cur = crl_cur->entry.next;
2605 while( entry_cur != NULL )
2606 {
2607 entry_prv = entry_cur;
2608 entry_cur = entry_cur->next;
2609 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
2610 free( entry_prv );
2611 }
2612
2613 if( crl_cur->raw.p != NULL )
2614 {
2615 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
2616 free( crl_cur->raw.p );
2617 }
2618
2619 crl_cur = crl_cur->next;
2620 }
2621 while( crl_cur != NULL );
2622
2623 crl_cur = crl;
2624 do
2625 {
2626 crl_prv = crl_cur;
2627 crl_cur = crl_cur->next;
2628
2629 memset( crl_prv, 0, sizeof( x509_crl ) );
2630 if( crl_prv != crl )
2631 free( crl_prv );
2632 }
2633 while( crl_cur != NULL );
2634}
2635
Paul Bakker40e46942009-01-03 21:51:57 +00002636#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002637
Paul Bakker40e46942009-01-03 21:51:57 +00002638#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00002639
2640/*
2641 * Checkup routine
2642 */
2643int x509_self_test( int verbose )
2644{
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002645#if defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00002646 int ret, i, j;
2647 x509_cert cacert;
2648 x509_cert clicert;
2649 rsa_context rsa;
Paul Bakker1b57b062011-01-06 15:48:19 +00002650 dhm_context dhm;
Paul Bakker5121ce52009-01-03 21:22:43 +00002651
2652 if( verbose != 0 )
2653 printf( " X.509 certificate load: " );
2654
2655 memset( &clicert, 0, sizeof( x509_cert ) );
2656
2657 ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
2658 strlen( test_cli_crt ) );
2659 if( ret != 0 )
2660 {
2661 if( verbose != 0 )
2662 printf( "failed\n" );
2663
2664 return( ret );
2665 }
2666
2667 memset( &cacert, 0, sizeof( x509_cert ) );
2668
2669 ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
2670 strlen( test_ca_crt ) );
2671 if( ret != 0 )
2672 {
2673 if( verbose != 0 )
2674 printf( "failed\n" );
2675
2676 return( ret );
2677 }
2678
2679 if( verbose != 0 )
2680 printf( "passed\n X.509 private key load: " );
2681
2682 i = strlen( test_ca_key );
2683 j = strlen( test_ca_pwd );
2684
2685 if( ( ret = x509parse_key( &rsa,
2686 (unsigned char *) test_ca_key, i,
2687 (unsigned char *) test_ca_pwd, j ) ) != 0 )
2688 {
2689 if( verbose != 0 )
2690 printf( "failed\n" );
2691
2692 return( ret );
2693 }
2694
2695 if( verbose != 0 )
2696 printf( "passed\n X.509 signature verify: ");
2697
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002698 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &i, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00002699 if( ret != 0 )
2700 {
2701 if( verbose != 0 )
2702 printf( "failed\n" );
2703
2704 return( ret );
2705 }
2706
2707 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00002708 printf( "passed\n X.509 DHM parameter load: " );
2709
2710 i = strlen( test_dhm_params );
2711 j = strlen( test_ca_pwd );
2712
2713 if( ( ret = x509parse_dhm( &dhm, (unsigned char *) test_dhm_params, i ) ) != 0 )
2714 {
2715 if( verbose != 0 )
2716 printf( "failed\n" );
2717
2718 return( ret );
2719 }
2720
2721 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002722 printf( "passed\n\n" );
2723
2724 x509_free( &cacert );
2725 x509_free( &clicert );
2726 rsa_free( &rsa );
Paul Bakker1b57b062011-01-06 15:48:19 +00002727 dhm_free( &dhm );
Paul Bakker5121ce52009-01-03 21:22:43 +00002728
2729 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002730#else
2731 ((void) verbose);
2732 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
2733#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002734}
2735
2736#endif
2737
2738#endif