blob: 430dab92349b77f2a847d009eab8fea58070a489 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * X.509 certificate and private key decoding
3 *
Paul Bakker77b385e2009-07-28 17:23:11 +00004 * Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org>
5 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +00006 *
Paul Bakker77b385e2009-07-28 17:23:11 +00007 * Joined copyright on original XySSL code with: Christophe Devine
Paul Bakker5121ce52009-01-03 21:22:43 +00008 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
23/*
24 * The ITU-T X.509 standard defines a certificat format for PKI.
25 *
26 * http://www.ietf.org/rfc/rfc2459.txt
27 * http://www.ietf.org/rfc/rfc3279.txt
28 *
29 * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
30 *
31 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
32 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
33 */
34
Paul Bakker40e46942009-01-03 21:51:57 +000035#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000036
Paul Bakker40e46942009-01-03 21:51:57 +000037#if defined(POLARSSL_X509_PARSE_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000038
Paul Bakker40e46942009-01-03 21:51:57 +000039#include "polarssl/x509.h"
40#include "polarssl/base64.h"
41#include "polarssl/des.h"
42#include "polarssl/md2.h"
43#include "polarssl/md4.h"
44#include "polarssl/md5.h"
45#include "polarssl/sha1.h"
Paul Bakker026c03b2009-03-28 17:53:03 +000046#include "polarssl/sha2.h"
47#include "polarssl/sha4.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000048
49#include <string.h>
50#include <stdlib.h>
51#include <stdio.h>
52#include <time.h>
53
54/*
55 * ASN.1 DER decoding routines
56 */
57static int asn1_get_len( unsigned char **p,
58 unsigned char *end,
59 int *len )
60{
61 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +000062 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000063
64 if( ( **p & 0x80 ) == 0 )
65 *len = *(*p)++;
66 else
67 {
68 switch( **p & 0x7F )
69 {
70 case 1:
71 if( ( end - *p ) < 2 )
Paul Bakker40e46942009-01-03 21:51:57 +000072 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000073
74 *len = (*p)[1];
75 (*p) += 2;
76 break;
77
78 case 2:
79 if( ( end - *p ) < 3 )
Paul Bakker40e46942009-01-03 21:51:57 +000080 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000081
82 *len = ( (*p)[1] << 8 ) | (*p)[2];
83 (*p) += 3;
84 break;
85
86 default:
Paul Bakker40e46942009-01-03 21:51:57 +000087 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +000088 break;
89 }
90 }
91
92 if( *len > (int) ( end - *p ) )
Paul Bakker40e46942009-01-03 21:51:57 +000093 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000094
95 return( 0 );
96}
97
98static int asn1_get_tag( unsigned char **p,
99 unsigned char *end,
100 int *len, int tag )
101{
102 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000103 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000104
105 if( **p != tag )
Paul Bakker40e46942009-01-03 21:51:57 +0000106 return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000107
108 (*p)++;
109
110 return( asn1_get_len( p, end, len ) );
111}
112
113static int asn1_get_bool( unsigned char **p,
114 unsigned char *end,
115 int *val )
116{
117 int ret, len;
118
119 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 )
120 return( ret );
121
122 if( len != 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000123 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000124
125 *val = ( **p != 0 ) ? 1 : 0;
126 (*p)++;
127
128 return( 0 );
129}
130
131static int asn1_get_int( unsigned char **p,
132 unsigned char *end,
133 int *val )
134{
135 int ret, len;
136
137 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
138 return( ret );
139
140 if( len > (int) sizeof( int ) || ( **p & 0x80 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000141 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000142
143 *val = 0;
144
145 while( len-- > 0 )
146 {
147 *val = ( *val << 8 ) | **p;
148 (*p)++;
149 }
150
151 return( 0 );
152}
153
154static int asn1_get_mpi( unsigned char **p,
155 unsigned char *end,
156 mpi *X )
157{
158 int ret, len;
159
160 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
161 return( ret );
162
163 ret = mpi_read_binary( X, *p, len );
164
165 *p += len;
166
167 return( ret );
168}
169
170/*
171 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
172 */
173static int x509_get_version( unsigned char **p,
174 unsigned char *end,
175 int *ver )
176{
177 int ret, len;
178
179 if( ( ret = asn1_get_tag( p, end, &len,
180 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
181 {
Paul Bakker40e46942009-01-03 21:51:57 +0000182 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000183 return( *ver = 0 );
184
185 return( ret );
186 }
187
188 end = *p + len;
189
190 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000191 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000192
193 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000194 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION |
195 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000196
197 return( 0 );
198}
199
200/*
201 * CertificateSerialNumber ::= INTEGER
202 */
203static int x509_get_serial( unsigned char **p,
204 unsigned char *end,
205 x509_buf *serial )
206{
207 int ret;
208
209 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000210 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL |
211 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000212
213 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
214 **p != ASN1_INTEGER )
Paul Bakker40e46942009-01-03 21:51:57 +0000215 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL |
216 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000217
218 serial->tag = *(*p)++;
219
220 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000221 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000222
223 serial->p = *p;
224 *p += serial->len;
225
226 return( 0 );
227}
228
229/*
230 * AlgorithmIdentifier ::= SEQUENCE {
231 * algorithm OBJECT IDENTIFIER,
232 * parameters ANY DEFINED BY algorithm OPTIONAL }
233 */
234static int x509_get_alg( unsigned char **p,
235 unsigned char *end,
236 x509_buf *alg )
237{
238 int ret, len;
239
240 if( ( ret = asn1_get_tag( p, end, &len,
241 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000242 return( POLARSSL_ERR_X509_CERT_INVALID_ALG | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000243
244 end = *p + len;
245 alg->tag = **p;
246
247 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000248 return( POLARSSL_ERR_X509_CERT_INVALID_ALG | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000249
250 alg->p = *p;
251 *p += alg->len;
252
253 if( *p == end )
254 return( 0 );
255
256 /*
257 * assume the algorithm parameters must be NULL
258 */
259 if( ( ret = asn1_get_tag( p, end, &len, ASN1_NULL ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000260 return( POLARSSL_ERR_X509_CERT_INVALID_ALG | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000261
262 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000263 return( POLARSSL_ERR_X509_CERT_INVALID_ALG |
264 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000265
266 return( 0 );
267}
268
269/*
270 * RelativeDistinguishedName ::=
271 * SET OF AttributeTypeAndValue
272 *
273 * AttributeTypeAndValue ::= SEQUENCE {
274 * type AttributeType,
275 * value AttributeValue }
276 *
277 * AttributeType ::= OBJECT IDENTIFIER
278 *
279 * AttributeValue ::= ANY DEFINED BY AttributeType
280 */
281static int x509_get_name( unsigned char **p,
282 unsigned char *end,
283 x509_name *cur )
284{
285 int ret, len;
286 unsigned char *end2;
287 x509_buf *oid;
288 x509_buf *val;
289
290 if( ( ret = asn1_get_tag( p, end, &len,
291 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000292 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000293
294 end2 = end;
295 end = *p + len;
296
297 if( ( ret = asn1_get_tag( p, end, &len,
298 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000299 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000300
301 if( *p + len != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000302 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
303 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000304
305 oid = &cur->oid;
306 oid->tag = **p;
307
308 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000309 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000310
311 oid->p = *p;
312 *p += oid->len;
313
314 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000315 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
316 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000317
318 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
319 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
320 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker40e46942009-01-03 21:51:57 +0000321 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
322 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000323
324 val = &cur->val;
325 val->tag = *(*p)++;
326
327 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000328 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000329
330 val->p = *p;
331 *p += val->len;
332
333 cur->next = NULL;
334
335 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000336 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
337 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000338
339 /*
340 * recurse until end of SEQUENCE is reached
341 */
342 if( *p == end2 )
343 return( 0 );
344
345 cur->next = (x509_name *) malloc(
346 sizeof( x509_name ) );
347
348 if( cur->next == NULL )
349 return( 1 );
350
351 return( x509_get_name( p, end2, cur->next ) );
352}
353
354/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000355 * Time ::= CHOICE {
356 * utcTime UTCTime,
357 * generalTime GeneralizedTime }
358 */
Paul Bakker91200182010-02-18 21:26:15 +0000359static int x509_get_time( unsigned char **p,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000360 unsigned char *end,
361 x509_time *time )
362{
363 int ret, len;
364 char date[64];
Paul Bakker91200182010-02-18 21:26:15 +0000365 unsigned char tag;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000366
Paul Bakker91200182010-02-18 21:26:15 +0000367 if( ( end - *p ) < 1 )
368 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000369
Paul Bakker91200182010-02-18 21:26:15 +0000370 tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000371
Paul Bakker91200182010-02-18 21:26:15 +0000372 if ( tag == ASN1_UTC_TIME )
373 {
374 (*p)++;
375 ret = asn1_get_len( p, end, &len );
376
377 if( ret != 0 )
378 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000379
Paul Bakker91200182010-02-18 21:26:15 +0000380 memset( date, 0, sizeof( date ) );
381 memcpy( date, *p, ( len < (int) sizeof( date ) - 1 ) ?
382 len : (int) sizeof( date ) - 1 );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000383
Paul Bakker91200182010-02-18 21:26:15 +0000384 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
385 &time->year, &time->mon, &time->day,
386 &time->hour, &time->min, &time->sec ) < 5 )
387 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000388
Paul Bakker91200182010-02-18 21:26:15 +0000389 time->year += 100 * ( time->year < 90 );
390 time->year += 1900;
391
392 *p += len;
393
394 return( 0 );
395 }
396 else if ( tag == ASN1_GENERALIZED_TIME )
397 {
398 (*p)++;
399 ret = asn1_get_len( p, end, &len );
400
401 if( ret != 0 )
402 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret );
403
404 memset( date, 0, sizeof( date ) );
405 memcpy( date, *p, ( len < (int) sizeof( date ) - 1 ) ?
406 len : (int) sizeof( date ) - 1 );
407
408 if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
409 &time->year, &time->mon, &time->day,
410 &time->hour, &time->min, &time->sec ) < 5 )
411 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
412
413 *p += len;
414
415 return( 0 );
416 }
417 else
418 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000419}
420
421
422/*
423 * Validity ::= SEQUENCE {
424 * notBefore Time,
425 * notAfter Time }
426 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000427static int x509_get_dates( unsigned char **p,
428 unsigned char *end,
429 x509_time *from,
430 x509_time *to )
431{
432 int ret, len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000433
434 if( ( ret = asn1_get_tag( p, end, &len,
435 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000436 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000437
438 end = *p + len;
439
Paul Bakker91200182010-02-18 21:26:15 +0000440 if( ( ret = x509_get_time( p, end, from ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000441 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000442
Paul Bakker91200182010-02-18 21:26:15 +0000443 if( ( ret = x509_get_time( p, end, to ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000444 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000445
446 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000447 return( POLARSSL_ERR_X509_CERT_INVALID_DATE |
448 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000449
450 return( 0 );
451}
452
453/*
454 * SubjectPublicKeyInfo ::= SEQUENCE {
455 * algorithm AlgorithmIdentifier,
456 * subjectPublicKey BIT STRING }
457 */
458static int x509_get_pubkey( unsigned char **p,
459 unsigned char *end,
460 x509_buf *pk_alg_oid,
461 mpi *N, mpi *E )
462{
463 int ret, len;
464 unsigned char *end2;
465
466 if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 )
467 return( ret );
468
469 /*
470 * only RSA public keys handled at this time
471 */
472 if( pk_alg_oid->len != 9 ||
473 memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000474 return( POLARSSL_ERR_X509_CERT_UNKNOWN_PK_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000475
476 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000477 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000478
479 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000480 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY |
481 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000482
483 end2 = *p + len;
484
485 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000486 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000487
488 /*
489 * RSAPublicKey ::= SEQUENCE {
490 * modulus INTEGER, -- n
491 * publicExponent INTEGER -- e
492 * }
493 */
494 if( ( ret = asn1_get_tag( p, end2, &len,
495 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000496 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000497
498 if( *p + len != end2 )
Paul Bakker40e46942009-01-03 21:51:57 +0000499 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY |
500 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000501
502 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
503 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000504 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000505
506 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000507 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY |
508 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000509
510 return( 0 );
511}
512
513static int x509_get_sig( unsigned char **p,
514 unsigned char *end,
515 x509_buf *sig )
516{
517 int ret, len;
518
519 sig->tag = **p;
520
521 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000522 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000523
524 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000525 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000526
527 sig->len = len;
528 sig->p = *p;
529
530 *p += len;
531
532 return( 0 );
533}
534
535/*
536 * X.509 v2/v3 unique identifier (not parsed)
537 */
538static int x509_get_uid( unsigned char **p,
539 unsigned char *end,
540 x509_buf *uid, int n )
541{
542 int ret;
543
544 if( *p == end )
545 return( 0 );
546
547 uid->tag = **p;
548
549 if( ( ret = asn1_get_tag( p, end, &uid->len,
550 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
551 {
Paul Bakker40e46942009-01-03 21:51:57 +0000552 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000553 return( 0 );
554
555 return( ret );
556 }
557
558 uid->p = *p;
559 *p += uid->len;
560
561 return( 0 );
562}
563
564/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000565 * X.509 Extensions (No parsing of extensions, pointer should
566 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000567 */
568static int x509_get_ext( unsigned char **p,
569 unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000570 x509_buf *ext )
Paul Bakker5121ce52009-01-03 21:22:43 +0000571{
572 int ret, len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000573
574 if( *p == end )
575 return( 0 );
576
577 ext->tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000578
Paul Bakker5121ce52009-01-03 21:22:43 +0000579 if( ( ret = asn1_get_tag( p, end, &ext->len,
580 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000581 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000582
583 ext->p = *p;
584 end = *p + ext->len;
585
586 /*
587 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
588 *
589 * Extension ::= SEQUENCE {
590 * extnID OBJECT IDENTIFIER,
591 * critical BOOLEAN DEFAULT FALSE,
592 * extnValue OCTET STRING }
593 */
594 if( ( ret = asn1_get_tag( p, end, &len,
595 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000596 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000597
598 if( end != *p + len )
Paul Bakker40e46942009-01-03 21:51:57 +0000599 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
600 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000601
Paul Bakkerd98030e2009-05-02 15:13:40 +0000602 return( 0 );
603}
604
605/*
606 * X.509 CRL v2 extensions (no extensions parsed yet.)
607 */
608static int x509_get_crl_ext( unsigned char **p,
609 unsigned char *end,
610 x509_buf *ext )
611{
612 int ret, len;
613
614 if( ( ret = x509_get_ext( p, end, ext ) ) != 0 )
615 {
616 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
617 return( 0 );
618
619 return( ret );
620 }
621
622 while( *p < end )
623 {
624 if( ( ret = asn1_get_tag( p, end, &len,
625 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
626 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
627
628 *p += len;
629 }
630
631 if( *p != end )
632 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
633 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
634
635 return( 0 );
636}
637
638/*
639 * X.509 v3 extensions (only BasicConstraints are parsed)
640 */
641static int x509_get_crt_ext( unsigned char **p,
642 unsigned char *end,
643 x509_buf *ext,
644 int *ca_istrue,
645 int *max_pathlen )
646{
647 int ret, len;
648 int is_critical = 1;
649 int is_cacert = 0;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000650 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000651
652 if( ( ret = x509_get_ext( p, end, ext ) ) != 0 )
653 {
654 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
655 return( 0 );
656
657 return( ret );
658 }
659
Paul Bakker5121ce52009-01-03 21:22:43 +0000660 while( *p < end )
661 {
662 if( ( ret = asn1_get_tag( p, end, &len,
663 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000664 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000665
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000666 end_ext_data = *p + len;
667
Paul Bakker5121ce52009-01-03 21:22:43 +0000668 if( memcmp( *p, "\x06\x03\x55\x1D\x13", 5 ) != 0 )
669 {
670 *p += len;
671 continue;
672 }
673
674 *p += 5;
675
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000676 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000677 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
678 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000679
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000680 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000681 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000682 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000683
684 /*
685 * BasicConstraints ::= SEQUENCE {
686 * cA BOOLEAN DEFAULT FALSE,
687 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
688 */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000689 end_ext_octet = *p + len;
690
691 if( end_ext_octet != end_ext_data )
692 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
693 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000694
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000695 if( ( ret = asn1_get_tag( p, end_ext_octet, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000696 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000697 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000698
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000699 if( *p == end_ext_octet )
Paul Bakker5121ce52009-01-03 21:22:43 +0000700 continue;
701
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000702 if( ( ret = asn1_get_bool( p, end_ext_octet, &is_cacert ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000703 {
Paul Bakker40e46942009-01-03 21:51:57 +0000704 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000705 ret = asn1_get_int( p, end_ext_octet, &is_cacert );
Paul Bakker5121ce52009-01-03 21:22:43 +0000706
707 if( ret != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000708 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000709
710 if( is_cacert != 0 )
711 is_cacert = 1;
712 }
713
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000714 if( *p == end_ext_octet )
Paul Bakker5121ce52009-01-03 21:22:43 +0000715 continue;
716
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000717 if( ( ret = asn1_get_int( p, end_ext_octet, max_pathlen ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000718 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000719
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000720 if( *p != end_ext_octet )
Paul Bakker40e46942009-01-03 21:51:57 +0000721 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
722 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000723
724 max_pathlen++;
725 }
726
727 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000728 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
729 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000730
731 *ca_istrue = is_critical & is_cacert;
732
733 return( 0 );
734}
735
736/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000737 * X.509 CRL Entries
738 */
739static int x509_get_entries( unsigned char **p,
740 unsigned char *end,
741 x509_crl_entry *entry )
742{
Paul Bakker9be19372009-07-27 20:21:53 +0000743 int ret, entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000744 x509_crl_entry *cur_entry = entry;
745
746 if( *p == end )
747 return( 0 );
748
Paul Bakker9be19372009-07-27 20:21:53 +0000749 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000750 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
751 {
752 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
753 return( 0 );
754
755 return( ret );
756 }
757
Paul Bakker9be19372009-07-27 20:21:53 +0000758 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000759
760 while( *p < end )
761 {
762 int len2;
763
764 if( ( ret = asn1_get_tag( p, end, &len2,
765 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
766 {
Paul Bakkerd98030e2009-05-02 15:13:40 +0000767 return( ret );
768 }
769
Paul Bakker9be19372009-07-27 20:21:53 +0000770 cur_entry->raw.tag = **p;
771 cur_entry->raw.p = *p;
772 cur_entry->raw.len = len2;
773
Paul Bakkerd98030e2009-05-02 15:13:40 +0000774 if( ( ret = x509_get_serial( p, end, &cur_entry->serial ) ) != 0 )
775 return( ret );
776
Paul Bakker91200182010-02-18 21:26:15 +0000777 if( ( ret = x509_get_time( p, end, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000778 return( ret );
779
780 if( ( ret = x509_get_crl_ext( p, end, &cur_entry->entry_ext ) ) != 0 )
781 return( ret );
782
783 if ( *p < end ) {
784 cur_entry->next = malloc( sizeof( x509_crl_entry ) );
785 cur_entry = cur_entry->next;
786 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
787 }
788 }
789
790 return( 0 );
791}
792
793/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000794 * Parse one or more certificates and add them to the chained list
795 */
796int x509parse_crt( x509_cert *chain, unsigned char *buf, int buflen )
797{
798 int ret, len;
799 unsigned char *s1, *s2;
800 unsigned char *p, *end;
801 x509_cert *crt;
802
803 crt = chain;
804
Paul Bakker320a4b52009-03-28 18:52:39 +0000805 /*
806 * Check for valid input
807 */
808 if( crt == NULL || buf == NULL )
809 return( 1 );
810
Paul Bakkere9581d62009-03-28 20:29:25 +0000811 while( crt->version != 0 && crt->next != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +0000812 crt = crt->next;
813
814 /*
Paul Bakker320a4b52009-03-28 18:52:39 +0000815 * Add new certificate on the end of the chain if needed.
816 */
Paul Bakkere9581d62009-03-28 20:29:25 +0000817 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +0000818 {
819 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
820
Paul Bakker7d06ad22009-05-02 15:53:56 +0000821 if( crt->next == NULL )
822 {
Paul Bakker320a4b52009-03-28 18:52:39 +0000823 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +0000824 return( 1 );
825 }
Paul Bakker320a4b52009-03-28 18:52:39 +0000826
Paul Bakker7d06ad22009-05-02 15:53:56 +0000827 crt = crt->next;
828 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +0000829 }
830
831 /*
Paul Bakker5121ce52009-01-03 21:22:43 +0000832 * check if the certificate is encoded in base64
833 */
834 s1 = (unsigned char *) strstr( (char *) buf,
835 "-----BEGIN CERTIFICATE-----" );
836
837 if( s1 != NULL )
838 {
839 s2 = (unsigned char *) strstr( (char *) buf,
840 "-----END CERTIFICATE-----" );
841
842 if( s2 == NULL || s2 <= s1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000843 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +0000844
845 s1 += 27;
846 if( *s1 == '\r' ) s1++;
847 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +0000848 else return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +0000849
850 /*
851 * get the DER data length and decode the buffer
852 */
853 len = 0;
854 ret = base64_decode( NULL, &len, s1, s2 - s1 );
855
Paul Bakker40e46942009-01-03 21:51:57 +0000856 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
857 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000858
859 if( ( p = (unsigned char *) malloc( len ) ) == NULL )
860 return( 1 );
861
862 if( ( ret = base64_decode( p, &len, s1, s2 - s1 ) ) != 0 )
863 {
864 free( p );
Paul Bakker40e46942009-01-03 21:51:57 +0000865 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000866 }
867
868 /*
869 * update the buffer size and offset
870 */
871 s2 += 25;
872 if( *s2 == '\r' ) s2++;
873 if( *s2 == '\n' ) s2++;
874 else
875 {
876 free( p );
Paul Bakker40e46942009-01-03 21:51:57 +0000877 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +0000878 }
879
880 buflen -= s2 - buf;
881 buf = s2;
882 }
883 else
884 {
885 /*
886 * nope, copy the raw DER data
887 */
888 p = (unsigned char *) malloc( len = buflen );
889
890 if( p == NULL )
891 return( 1 );
892
893 memcpy( p, buf, buflen );
894
895 buflen = 0;
896 }
897
898 crt->raw.p = p;
899 crt->raw.len = len;
900 end = p + len;
901
902 /*
903 * Certificate ::= SEQUENCE {
904 * tbsCertificate TBSCertificate,
905 * signatureAlgorithm AlgorithmIdentifier,
906 * signatureValue BIT STRING }
907 */
908 if( ( ret = asn1_get_tag( &p, end, &len,
909 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
910 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000911 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000912 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +0000913 }
914
915 if( len != (int) ( end - p ) )
916 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000917 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000918 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
919 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000920 }
921
922 /*
923 * TBSCertificate ::= SEQUENCE {
924 */
925 crt->tbs.p = p;
926
927 if( ( ret = asn1_get_tag( &p, end, &len,
928 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
929 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000930 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000931 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000932 }
933
934 end = p + len;
935 crt->tbs.len = end - crt->tbs.p;
936
937 /*
938 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
939 *
940 * CertificateSerialNumber ::= INTEGER
941 *
942 * signature AlgorithmIdentifier
943 */
944 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
945 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
946 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
947 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000948 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +0000949 return( ret );
950 }
951
952 crt->version++;
953
954 if( crt->version > 3 )
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_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +0000958 }
959
960 if( crt->sig_oid1.len != 9 ||
961 memcmp( crt->sig_oid1.p, OID_PKCS1, 8 ) != 0 )
962 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000963 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000964 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000965 }
966
967 if( crt->sig_oid1.p[8] < 2 ||
Paul Bakker4593aea2009-02-09 22:32:35 +0000968 ( crt->sig_oid1.p[8] > 5 && crt->sig_oid1.p[8] < 11 ) ||
Paul Bakker7d06ad22009-05-02 15:53:56 +0000969 crt->sig_oid1.p[8] > 14 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000970 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000971 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000972 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000973 }
974
975 /*
976 * issuer Name
977 */
978 crt->issuer_raw.p = p;
979
980 if( ( ret = asn1_get_tag( &p, end, &len,
981 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
982 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000983 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000984 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000985 }
986
987 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
988 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000989 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +0000990 return( ret );
991 }
992
993 crt->issuer_raw.len = p - crt->issuer_raw.p;
994
995 /*
996 * Validity ::= SEQUENCE {
997 * notBefore Time,
998 * notAfter Time }
999 *
1000 */
1001 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1002 &crt->valid_to ) ) != 0 )
1003 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001004 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001005 return( ret );
1006 }
1007
1008 /*
1009 * subject Name
1010 */
1011 crt->subject_raw.p = p;
1012
1013 if( ( ret = asn1_get_tag( &p, end, &len,
1014 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1015 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001016 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001017 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001018 }
1019
1020 if( ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
1021 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001022 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001023 return( ret );
1024 }
1025
1026 crt->subject_raw.len = p - crt->subject_raw.p;
1027
1028 /*
1029 * SubjectPublicKeyInfo ::= SEQUENCE
1030 * algorithm AlgorithmIdentifier,
1031 * subjectPublicKey BIT STRING }
1032 */
1033 if( ( ret = asn1_get_tag( &p, end, &len,
1034 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1035 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001036 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001037 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001038 }
1039
1040 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1041 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1042 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001043 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001044 return( ret );
1045 }
1046
1047 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1048 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001049 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001050 return( ret );
1051 }
1052
1053 crt->rsa.len = mpi_size( &crt->rsa.N );
1054
1055 /*
1056 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1057 * -- If present, version shall be v2 or v3
1058 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1059 * -- If present, version shall be v2 or v3
1060 * extensions [3] EXPLICIT Extensions OPTIONAL
1061 * -- If present, version shall be v3
1062 */
1063 if( crt->version == 2 || crt->version == 3 )
1064 {
1065 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1066 if( ret != 0 )
1067 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001068 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001069 return( ret );
1070 }
1071 }
1072
1073 if( crt->version == 2 || crt->version == 3 )
1074 {
1075 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1076 if( ret != 0 )
1077 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001078 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001079 return( ret );
1080 }
1081 }
1082
1083 if( crt->version == 3 )
1084 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001085 ret = x509_get_crt_ext( &p, end, &crt->v3_ext,
Paul Bakker5121ce52009-01-03 21:22:43 +00001086 &crt->ca_istrue, &crt->max_pathlen );
1087 if( ret != 0 )
1088 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001089 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001090 return( ret );
1091 }
1092 }
1093
1094 if( p != end )
1095 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001096 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001097 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1098 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001099 }
1100
1101 end = crt->raw.p + crt->raw.len;
1102
1103 /*
1104 * signatureAlgorithm AlgorithmIdentifier,
1105 * signatureValue BIT STRING
1106 */
1107 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1108 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001109 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001110 return( ret );
1111 }
1112
Paul Bakker320a4b52009-03-28 18:52:39 +00001113 if( memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001114 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001115 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001116 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001117 }
1118
1119 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1120 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001121 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001122 return( ret );
1123 }
1124
1125 if( p != end )
1126 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001127 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001128 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1129 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001130 }
1131
Paul Bakker5121ce52009-01-03 21:22:43 +00001132 if( buflen > 0 )
Paul Bakker320a4b52009-03-28 18:52:39 +00001133 {
1134 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1135
Paul Bakker7d06ad22009-05-02 15:53:56 +00001136 if( crt->next == NULL )
1137 {
Paul Bakker320a4b52009-03-28 18:52:39 +00001138 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001139 return( 1 );
1140 }
Paul Bakker320a4b52009-03-28 18:52:39 +00001141
Paul Bakker7d06ad22009-05-02 15:53:56 +00001142 crt = crt->next;
1143 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001144
Paul Bakker5121ce52009-01-03 21:22:43 +00001145 return( x509parse_crt( crt, buf, buflen ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001146 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001147
1148 return( 0 );
1149}
1150
1151/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001152 * Parse one or more CRLs and add them to the chained list
1153 */
1154int x509parse_crl( x509_crl *chain, unsigned char *buf, int buflen )
1155{
1156 int ret, len;
1157 unsigned char *s1, *s2;
1158 unsigned char *p, *end;
1159 x509_crl *crl;
1160
1161 crl = chain;
1162
1163 /*
1164 * Check for valid input
1165 */
1166 if( crl == NULL || buf == NULL )
1167 return( 1 );
1168
1169 while( crl->version != 0 && crl->next != NULL )
1170 crl = crl->next;
1171
1172 /*
1173 * Add new CRL on the end of the chain if needed.
1174 */
1175 if ( crl->version != 0 && crl->next == NULL)
1176 {
1177 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1178
Paul Bakker7d06ad22009-05-02 15:53:56 +00001179 if( crl->next == NULL )
1180 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001181 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001182 return( 1 );
1183 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001184
Paul Bakker7d06ad22009-05-02 15:53:56 +00001185 crl = crl->next;
1186 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001187 }
1188
1189 /*
1190 * check if the CRL is encoded in base64
1191 */
1192 s1 = (unsigned char *) strstr( (char *) buf,
1193 "-----BEGIN X509 CRL-----" );
1194
1195 if( s1 != NULL )
1196 {
1197 s2 = (unsigned char *) strstr( (char *) buf,
1198 "-----END X509 CRL-----" );
1199
1200 if( s2 == NULL || s2 <= s1 )
1201 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1202
1203 s1 += 24;
1204 if( *s1 == '\r' ) s1++;
1205 if( *s1 == '\n' ) s1++;
1206 else return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1207
1208 /*
1209 * get the DER data length and decode the buffer
1210 */
1211 len = 0;
1212 ret = base64_decode( NULL, &len, s1, s2 - s1 );
1213
1214 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
1215 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
1216
1217 if( ( p = (unsigned char *) malloc( len ) ) == NULL )
1218 return( 1 );
1219
1220 if( ( ret = base64_decode( p, &len, s1, s2 - s1 ) ) != 0 )
1221 {
1222 free( p );
1223 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
1224 }
1225
1226 /*
1227 * update the buffer size and offset
1228 */
1229 s2 += 22;
1230 if( *s2 == '\r' ) s2++;
1231 if( *s2 == '\n' ) s2++;
1232 else
1233 {
1234 free( p );
1235 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1236 }
1237
1238 buflen -= s2 - buf;
1239 buf = s2;
1240 }
1241 else
1242 {
1243 /*
1244 * nope, copy the raw DER data
1245 */
1246 p = (unsigned char *) malloc( len = buflen );
1247
1248 if( p == NULL )
1249 return( 1 );
1250
1251 memcpy( p, buf, buflen );
1252
1253 buflen = 0;
1254 }
1255
1256 crl->raw.p = p;
1257 crl->raw.len = len;
1258 end = p + len;
1259
1260 /*
1261 * CertificateList ::= SEQUENCE {
1262 * tbsCertList TBSCertList,
1263 * signatureAlgorithm AlgorithmIdentifier,
1264 * signatureValue BIT STRING }
1265 */
1266 if( ( ret = asn1_get_tag( &p, end, &len,
1267 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1268 {
1269 x509_crl_free( crl );
1270 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1271 }
1272
1273 if( len != (int) ( end - p ) )
1274 {
1275 x509_crl_free( crl );
1276 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1277 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1278 }
1279
1280 /*
1281 * TBSCertList ::= SEQUENCE {
1282 */
1283 crl->tbs.p = p;
1284
1285 if( ( ret = asn1_get_tag( &p, end, &len,
1286 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1287 {
1288 x509_crl_free( crl );
1289 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
1290 }
1291
1292 end = p + len;
1293 crl->tbs.len = end - crl->tbs.p;
1294
1295 /*
1296 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1297 * -- if present, MUST be v2
1298 *
1299 * signature AlgorithmIdentifier
1300 */
1301 if( ( ret = x509_get_version( &p, end, &crl->version ) ) != 0 ||
1302 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1303 {
1304 x509_crl_free( crl );
1305 return( ret );
1306 }
1307
1308 crl->version++;
1309
1310 if( crl->version > 2 )
1311 {
1312 x509_crl_free( crl );
1313 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1314 }
1315
1316 if( crl->sig_oid1.len != 9 ||
1317 memcmp( crl->sig_oid1.p, OID_PKCS1, 8 ) != 0 )
1318 {
1319 x509_crl_free( crl );
1320 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1321 }
1322
1323 if( crl->sig_oid1.p[8] < 2 ||
1324 ( crl->sig_oid1.p[8] > 5 && crl->sig_oid1.p[8] < 11 ) ||
1325 crl->sig_oid1.p[8] > 14 )
1326 {
1327 x509_crl_free( crl );
1328 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1329 }
1330
1331 /*
1332 * issuer Name
1333 */
1334 crl->issuer_raw.p = p;
1335
1336 if( ( ret = asn1_get_tag( &p, end, &len,
1337 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1338 {
1339 x509_crl_free( crl );
1340 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
1341 }
1342
1343 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1344 {
1345 x509_crl_free( crl );
1346 return( ret );
1347 }
1348
1349 crl->issuer_raw.len = p - crl->issuer_raw.p;
1350
1351 /*
1352 * thisUpdate Time
1353 * nextUpdate Time OPTIONAL
1354 */
Paul Bakker91200182010-02-18 21:26:15 +00001355 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001356 {
1357 x509_crl_free( crl );
1358 return( ret );
1359 }
1360
Paul Bakker91200182010-02-18 21:26:15 +00001361 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001362 {
Paul Bakker635f4b42009-07-20 20:34:41 +00001363 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE |
Paul Bakker9be19372009-07-27 20:21:53 +00001364 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
1365 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE |
1366 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001367 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001368 x509_crl_free( crl );
1369 return( ret );
1370 }
1371 }
1372
1373 /*
1374 * revokedCertificates SEQUENCE OF SEQUENCE {
1375 * userCertificate CertificateSerialNumber,
1376 * revocationDate Time,
1377 * crlEntryExtensions Extensions OPTIONAL
1378 * -- if present, MUST be v2
1379 * } OPTIONAL
1380 */
1381 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1382 {
1383 x509_crl_free( crl );
1384 return( ret );
1385 }
1386
1387 /*
1388 * crlExtensions EXPLICIT Extensions OPTIONAL
1389 * -- if present, MUST be v2
1390 */
1391 if( crl->version == 2 )
1392 {
1393 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1394
1395 if( ret != 0 )
1396 {
1397 x509_crl_free( crl );
1398 return( ret );
1399 }
1400 }
1401
1402 if( p != end )
1403 {
1404 x509_crl_free( crl );
1405 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1406 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1407 }
1408
1409 end = crl->raw.p + crl->raw.len;
1410
1411 /*
1412 * signatureAlgorithm AlgorithmIdentifier,
1413 * signatureValue BIT STRING
1414 */
1415 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1416 {
1417 x509_crl_free( crl );
1418 return( ret );
1419 }
1420
1421 if( memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
1422 {
1423 x509_crl_free( crl );
1424 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1425 }
1426
1427 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1428 {
1429 x509_crl_free( crl );
1430 return( ret );
1431 }
1432
1433 if( p != end )
1434 {
1435 x509_crl_free( crl );
1436 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1437 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1438 }
1439
1440 if( buflen > 0 )
1441 {
1442 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1443
Paul Bakker7d06ad22009-05-02 15:53:56 +00001444 if( crl->next == NULL )
1445 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001446 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001447 return( 1 );
1448 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001449
Paul Bakker7d06ad22009-05-02 15:53:56 +00001450 crl = crl->next;
1451 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001452
1453 return( x509parse_crl( crl, buf, buflen ) );
1454 }
1455
1456 return( 0 );
1457}
1458
1459/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001460 * Load all data from a file into a given buffer.
1461 */
1462int load_file( char *path, unsigned char **buf, size_t *n )
1463{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001464 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001465
Paul Bakkerd98030e2009-05-02 15:13:40 +00001466 if( ( f = fopen( path, "rb" ) ) == NULL )
1467 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001468
Paul Bakkerd98030e2009-05-02 15:13:40 +00001469 fseek( f, 0, SEEK_END );
1470 *n = (size_t) ftell( f );
1471 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001472
Paul Bakkerd98030e2009-05-02 15:13:40 +00001473 if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
1474 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001475
Paul Bakkerd98030e2009-05-02 15:13:40 +00001476 if( fread( *buf, 1, *n, f ) != *n )
1477 {
1478 fclose( f );
1479 free( *buf );
1480 return( 1 );
1481 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001482
Paul Bakkerd98030e2009-05-02 15:13:40 +00001483 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001484
Paul Bakkerd98030e2009-05-02 15:13:40 +00001485 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001486
Paul Bakkerd98030e2009-05-02 15:13:40 +00001487 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001488}
1489
1490/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001491 * Load one or more certificates and add them to the chained list
1492 */
1493int x509parse_crtfile( x509_cert *chain, char *path )
1494{
1495 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001496 size_t n;
1497 unsigned char *buf;
1498
Paul Bakker2b245eb2009-04-19 18:44:26 +00001499 if ( load_file( path, &buf, &n ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001500 return( 1 );
1501
Paul Bakker5121ce52009-01-03 21:22:43 +00001502 ret = x509parse_crt( chain, buf, (int) n );
1503
1504 memset( buf, 0, n + 1 );
1505 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001506
1507 return( ret );
1508}
1509
Paul Bakkerd98030e2009-05-02 15:13:40 +00001510/*
1511 * Load one or more CRLs and add them to the chained list
1512 */
1513int x509parse_crlfile( x509_crl *chain, char *path )
1514{
1515 int ret;
1516 size_t n;
1517 unsigned char *buf;
1518
1519 if ( load_file( path, &buf, &n ) )
1520 return( 1 );
1521
1522 ret = x509parse_crl( chain, buf, (int) n );
1523
1524 memset( buf, 0, n + 1 );
1525 free( buf );
1526
1527 return( ret );
1528}
1529
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001530#if defined(POLARSSL_DES_C) && defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001531/*
1532 * Read a 16-byte hex string and convert it to binary
1533 */
1534static int x509_get_iv( unsigned char *s, unsigned char iv[8] )
1535{
1536 int i, j, k;
1537
1538 memset( iv, 0, 8 );
1539
1540 for( i = 0; i < 16; i++, s++ )
1541 {
1542 if( *s >= '0' && *s <= '9' ) j = *s - '0'; else
1543 if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else
1544 if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else
Paul Bakker40e46942009-01-03 21:51:57 +00001545 return( POLARSSL_ERR_X509_KEY_INVALID_ENC_IV );
Paul Bakker5121ce52009-01-03 21:22:43 +00001546
1547 k = ( ( i & 1 ) != 0 ) ? j : j << 4;
1548
1549 iv[i >> 1] = (unsigned char)( iv[i >> 1] | k );
1550 }
1551
1552 return( 0 );
1553}
1554
1555/*
1556 * Decrypt with 3DES-CBC, using PBKDF1 for key derivation
1557 */
1558static void x509_des3_decrypt( unsigned char des3_iv[8],
1559 unsigned char *buf, int buflen,
1560 unsigned char *pwd, int pwdlen )
1561{
1562 md5_context md5_ctx;
1563 des3_context des3_ctx;
1564 unsigned char md5sum[16];
1565 unsigned char des3_key[24];
1566
1567 /*
1568 * 3DES key[ 0..15] = MD5(pwd || IV)
1569 * key[16..23] = MD5(pwd || IV || 3DES key[ 0..15])
1570 */
1571 md5_starts( &md5_ctx );
1572 md5_update( &md5_ctx, pwd, pwdlen );
1573 md5_update( &md5_ctx, des3_iv, 8 );
1574 md5_finish( &md5_ctx, md5sum );
1575 memcpy( des3_key, md5sum, 16 );
1576
1577 md5_starts( &md5_ctx );
1578 md5_update( &md5_ctx, md5sum, 16 );
1579 md5_update( &md5_ctx, pwd, pwdlen );
1580 md5_update( &md5_ctx, des3_iv, 8 );
1581 md5_finish( &md5_ctx, md5sum );
1582 memcpy( des3_key + 16, md5sum, 8 );
1583
1584 des3_set3key_dec( &des3_ctx, des3_key );
1585 des3_crypt_cbc( &des3_ctx, DES_DECRYPT, buflen,
1586 des3_iv, buf, buf );
1587
1588 memset( &md5_ctx, 0, sizeof( md5_ctx ) );
1589 memset( &des3_ctx, 0, sizeof( des3_ctx ) );
1590 memset( md5sum, 0, 16 );
1591 memset( des3_key, 0, 24 );
1592}
1593#endif
1594
1595/*
1596 * Parse a private RSA key
1597 */
1598int x509parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
1599 unsigned char *pwd, int pwdlen )
1600{
1601 int ret, len, enc;
1602 unsigned char *s1, *s2;
1603 unsigned char *p, *end;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001604#if defined(POLARSSL_DES_C) && defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001605 unsigned char des3_iv[8];
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001606#else
1607 ((void) pwd);
1608 ((void) pwdlen);
1609#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001610
1611 s1 = (unsigned char *) strstr( (char *) buf,
1612 "-----BEGIN RSA PRIVATE KEY-----" );
1613
1614 if( s1 != NULL )
1615 {
1616 s2 = (unsigned char *) strstr( (char *) buf,
1617 "-----END RSA PRIVATE KEY-----" );
1618
1619 if( s2 == NULL || s2 <= s1 )
Paul Bakker40e46942009-01-03 21:51:57 +00001620 return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001621
1622 s1 += 31;
1623 if( *s1 == '\r' ) s1++;
1624 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001625 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001626
1627 enc = 0;
1628
1629 if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
1630 {
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001631#if defined(POLARSSL_DES_C) && defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001632 enc++;
1633
1634 s1 += 22;
1635 if( *s1 == '\r' ) s1++;
1636 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001637 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001638
1639 if( memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001640 return( POLARSSL_ERR_X509_KEY_UNKNOWN_ENC_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +00001641
1642 s1 += 23;
1643 if( x509_get_iv( s1, des3_iv ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001644 return( POLARSSL_ERR_X509_KEY_INVALID_ENC_IV );
Paul Bakker5121ce52009-01-03 21:22:43 +00001645
1646 s1 += 16;
1647 if( *s1 == '\r' ) s1++;
1648 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001649 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001650#else
Paul Bakker40e46942009-01-03 21:51:57 +00001651 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001652#endif
1653 }
1654
1655 len = 0;
1656 ret = base64_decode( NULL, &len, s1, s2 - s1 );
1657
Paul Bakker40e46942009-01-03 21:51:57 +00001658 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
1659 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001660
1661 if( ( buf = (unsigned char *) malloc( len ) ) == NULL )
1662 return( 1 );
1663
1664 if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
1665 {
1666 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001667 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001668 }
1669
1670 buflen = len;
1671
1672 if( enc != 0 )
1673 {
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001674#if defined(POLARSSL_DES_C) && defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001675 if( pwd == NULL )
1676 {
1677 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001678 return( POLARSSL_ERR_X509_KEY_PASSWORD_REQUIRED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001679 }
1680
1681 x509_des3_decrypt( des3_iv, buf, buflen, pwd, pwdlen );
1682
1683 if( buf[0] != 0x30 || buf[1] != 0x82 ||
1684 buf[4] != 0x02 || buf[5] != 0x01 )
1685 {
1686 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001687 return( POLARSSL_ERR_X509_KEY_PASSWORD_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001688 }
1689#else
Paul Bakker40e46942009-01-03 21:51:57 +00001690 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001691#endif
1692 }
1693 }
1694
1695 memset( rsa, 0, sizeof( rsa_context ) );
1696
1697 p = buf;
1698 end = buf + buflen;
1699
1700 /*
1701 * RSAPrivateKey ::= SEQUENCE {
1702 * version Version,
1703 * modulus INTEGER, -- n
1704 * publicExponent INTEGER, -- e
1705 * privateExponent INTEGER, -- d
1706 * prime1 INTEGER, -- p
1707 * prime2 INTEGER, -- q
1708 * exponent1 INTEGER, -- d mod (p-1)
1709 * exponent2 INTEGER, -- d mod (q-1)
1710 * coefficient INTEGER, -- (inverse of q) mod p
1711 * otherPrimeInfos OtherPrimeInfos OPTIONAL
1712 * }
1713 */
1714 if( ( ret = asn1_get_tag( &p, end, &len,
1715 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1716 {
1717 if( s1 != NULL )
1718 free( buf );
1719
1720 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001721 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001722 }
1723
1724 end = p + len;
1725
1726 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
1727 {
1728 if( s1 != NULL )
1729 free( buf );
1730
1731 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001732 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001733 }
1734
1735 if( rsa->ver != 0 )
1736 {
1737 if( s1 != NULL )
1738 free( buf );
1739
1740 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001741 return( ret | POLARSSL_ERR_X509_KEY_INVALID_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001742 }
1743
1744 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
1745 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
1746 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
1747 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
1748 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
1749 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
1750 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
1751 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
1752 {
1753 if( s1 != NULL )
1754 free( buf );
1755
1756 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001757 return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001758 }
1759
1760 rsa->len = mpi_size( &rsa->N );
1761
1762 if( p != end )
1763 {
1764 if( s1 != NULL )
1765 free( buf );
1766
1767 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001768 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT |
1769 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001770 }
1771
1772 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
1773 {
1774 if( s1 != NULL )
1775 free( buf );
1776
1777 rsa_free( rsa );
1778 return( ret );
1779 }
1780
1781 if( s1 != NULL )
1782 free( buf );
1783
1784 return( 0 );
1785}
1786
1787/*
1788 * Load and parse a private RSA key
1789 */
1790int x509parse_keyfile( rsa_context *rsa, char *path, char *pwd )
1791{
1792 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001793 size_t n;
1794 unsigned char *buf;
1795
Paul Bakker2b245eb2009-04-19 18:44:26 +00001796 if ( load_file( path, &buf, &n ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001797 return( 1 );
1798
Paul Bakker5121ce52009-01-03 21:22:43 +00001799 if( pwd == NULL )
1800 ret = x509parse_key( rsa, buf, (int) n, NULL, 0 );
1801 else
1802 ret = x509parse_key( rsa, buf, (int) n,
1803 (unsigned char *) pwd, strlen( pwd ) );
1804
1805 memset( buf, 0, n + 1 );
1806 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001807
1808 return( ret );
1809}
1810
1811#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00001812#include <stdarg.h>
1813
1814#if !defined vsnprintf
1815#define vsnprintf _vsnprintf
1816#endif // vsnprintf
1817
1818/*
1819 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
1820 * Result value is not size of buffer needed, but -1 if no fit is possible.
1821 *
1822 * This fuction tries to 'fix' this by at least suggesting enlarging the
1823 * size by 20.
1824 */
1825int compat_snprintf(char *str, size_t size, const char *format, ...)
1826{
1827 va_list ap;
1828 int res = -1;
1829
1830 va_start( ap, format );
1831
1832 res = vsnprintf( str, size, format, ap );
1833
1834 va_end( ap );
1835
1836 // No quick fix possible
1837 if ( res < 0 )
1838 return( size + 20 );
1839
1840 return res;
1841}
1842
1843#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00001844#endif
1845
Paul Bakkerd98030e2009-05-02 15:13:40 +00001846#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
1847
1848#define SAFE_SNPRINTF() \
1849{ \
1850 if( ret == -1 ) \
1851 return( -1 ); \
1852 \
1853 if ( ret > n ) { \
1854 p[n - 1] = '\0'; \
1855 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
1856 } \
1857 \
1858 n -= ret; \
1859 p += ret; \
1860}
1861
Paul Bakker5121ce52009-01-03 21:22:43 +00001862/*
1863 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00001864 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00001865 */
Paul Bakkerd98030e2009-05-02 15:13:40 +00001866int x509parse_dn_gets( char *buf, size_t size, x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00001867{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001868 int i, ret, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00001869 unsigned char c;
1870 x509_name *name;
1871 char s[128], *p;
1872
1873 memset( s, 0, sizeof( s ) );
1874
1875 name = dn;
1876 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001877 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00001878
1879 while( name != NULL )
1880 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001881 if( name != dn ) {
1882 ret = snprintf( p, n, ", " );
1883 SAFE_SNPRINTF();
1884 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001885
1886 if( memcmp( name->oid.p, OID_X520, 2 ) == 0 )
1887 {
1888 switch( name->oid.p[2] )
1889 {
1890 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001891 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001892
1893 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001894 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001895
1896 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001897 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001898
1899 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001900 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001901
1902 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001903 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001904
1905 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001906 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001907
1908 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001909 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00001910 name->oid.p[2] );
1911 break;
1912 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001913 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001914 }
1915 else if( memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
1916 {
1917 switch( name->oid.p[8] )
1918 {
1919 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001920 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001921
1922 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001923 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00001924 name->oid.p[8] );
1925 break;
1926 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001927 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001928 }
1929 else
Paul Bakkerd98030e2009-05-02 15:13:40 +00001930 {
1931 ret = snprintf( p, n, "\?\?=" );
1932 SAFE_SNPRINTF();
1933 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001934
1935 for( i = 0; i < name->val.len; i++ )
1936 {
1937 if( i >= (int) sizeof( s ) - 1 )
1938 break;
1939
1940 c = name->val.p[i];
1941 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
1942 s[i] = '?';
1943 else s[i] = c;
1944 }
1945 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00001946 ret = snprintf( p, n, "%s", s );
1947 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001948 name = name->next;
1949 }
1950
Paul Bakkerd98030e2009-05-02 15:13:40 +00001951 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001952}
1953
1954/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001955 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00001956 */
Paul Bakkerd98030e2009-05-02 15:13:40 +00001957int x509parse_cert_info( char *buf, size_t size, char *prefix, x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00001958{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001959 int i, n, nr, ret;
1960 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00001961
1962 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001963 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00001964
Paul Bakkerd98030e2009-05-02 15:13:40 +00001965 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00001966 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001967 SAFE_SNPRINTF();
1968 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00001969 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001970 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001971
Paul Bakkerd98030e2009-05-02 15:13:40 +00001972 nr = ( crt->serial.len <= 32 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001973 ? crt->serial.len : 32;
1974
Paul Bakkerd98030e2009-05-02 15:13:40 +00001975 for( i = 0; i < nr; i++ )
1976 {
1977 ret = snprintf( p, n, "%02X%s",
1978 crt->serial.p[i], ( i < nr - 1 ) ? ":" : "" );
1979 SAFE_SNPRINTF();
1980 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001981
Paul Bakkerd98030e2009-05-02 15:13:40 +00001982 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
1983 SAFE_SNPRINTF();
1984 ret = x509parse_dn_gets( p, n, &crt->issuer );
1985 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001986
Paul Bakkerd98030e2009-05-02 15:13:40 +00001987 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
1988 SAFE_SNPRINTF();
1989 ret = x509parse_dn_gets( p, n, &crt->subject );
1990 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001991
Paul Bakkerd98030e2009-05-02 15:13:40 +00001992 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00001993 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1994 crt->valid_from.year, crt->valid_from.mon,
1995 crt->valid_from.day, crt->valid_from.hour,
1996 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001997 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001998
Paul Bakkerd98030e2009-05-02 15:13:40 +00001999 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002000 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2001 crt->valid_to.year, crt->valid_to.mon,
2002 crt->valid_to.day, crt->valid_to.hour,
2003 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002004 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002005
Paul Bakkerd98030e2009-05-02 15:13:40 +00002006 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2007 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002008
2009 switch( crt->sig_oid1.p[8] )
2010 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002011 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2012 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2013 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2014 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2015 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2016 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2017 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2018 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2019 default: ret = snprintf( p, n, "???" ); break;
2020 }
2021 SAFE_SNPRINTF();
2022
2023 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
2024 crt->rsa.N.n * (int) sizeof( unsigned long ) * 8 );
2025 SAFE_SNPRINTF();
2026
2027 return( size - n );
2028}
2029
2030/*
2031 * Return an informational string about the CRL.
2032 */
2033int x509parse_crl_info( char *buf, size_t size, char *prefix, x509_crl *crl )
2034{
2035 int i, n, nr, ret;
2036 char *p;
2037 x509_crl_entry *entry;
2038
2039 p = buf;
2040 n = size;
2041
2042 ret = snprintf( p, n, "%sCRL version : %d",
2043 prefix, crl->version );
2044 SAFE_SNPRINTF();
2045
2046 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2047 SAFE_SNPRINTF();
2048 ret = x509parse_dn_gets( p, n, &crl->issuer );
2049 SAFE_SNPRINTF();
2050
2051 ret = snprintf( p, n, "\n%sthis update : " \
2052 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2053 crl->this_update.year, crl->this_update.mon,
2054 crl->this_update.day, crl->this_update.hour,
2055 crl->this_update.min, crl->this_update.sec );
2056 SAFE_SNPRINTF();
2057
2058 ret = snprintf( p, n, "\n%snext update : " \
2059 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2060 crl->next_update.year, crl->next_update.mon,
2061 crl->next_update.day, crl->next_update.hour,
2062 crl->next_update.min, crl->next_update.sec );
2063 SAFE_SNPRINTF();
2064
2065 entry = &crl->entry;
2066
2067 ret = snprintf( p, n, "\n%sRevoked certificates:",
2068 prefix );
2069 SAFE_SNPRINTF();
2070
Paul Bakker9be19372009-07-27 20:21:53 +00002071 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002072 {
2073 ret = snprintf( p, n, "\n%sserial number: ",
2074 prefix );
2075 SAFE_SNPRINTF();
2076
2077 nr = ( entry->serial.len <= 32 )
2078 ? entry->serial.len : 32;
2079
2080 for( i = 0; i < nr; i++ ) {
2081 ret = snprintf( p, n, "%02X%s",
2082 entry->serial.p[i], ( i < nr - 1 ) ? ":" : "" );
2083 SAFE_SNPRINTF();
2084 }
2085
2086 ret = snprintf( p, n, " revocation date: " \
2087 "%04d-%02d-%02d %02d:%02d:%02d",
2088 entry->revocation_date.year, entry->revocation_date.mon,
2089 entry->revocation_date.day, entry->revocation_date.hour,
2090 entry->revocation_date.min, entry->revocation_date.sec );
2091 SAFE_SNPRINTF();
2092
2093 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002094 }
2095
Paul Bakkerd98030e2009-05-02 15:13:40 +00002096 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2097 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002098
Paul Bakkerd98030e2009-05-02 15:13:40 +00002099 switch( crl->sig_oid1.p[8] )
2100 {
2101 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2102 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2103 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2104 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2105 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2106 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2107 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2108 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2109 default: ret = snprintf( p, n, "???" ); break;
2110 }
2111 SAFE_SNPRINTF();
2112
Paul Bakker1e27bb22009-07-19 20:25:25 +00002113 ret = snprintf( p, n, "\n" );
2114 SAFE_SNPRINTF();
2115
Paul Bakkerd98030e2009-05-02 15:13:40 +00002116 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002117}
2118
2119/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00002120 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00002121 */
Paul Bakker40ea7de2009-05-03 10:18:48 +00002122int x509parse_time_expired( x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00002123{
2124 struct tm *lt;
2125 time_t tt;
2126
2127 tt = time( NULL );
2128 lt = localtime( &tt );
2129
Paul Bakker40ea7de2009-05-03 10:18:48 +00002130 if( lt->tm_year > to->year - 1900 )
2131 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002132
Paul Bakker40ea7de2009-05-03 10:18:48 +00002133 if( lt->tm_year == to->year - 1900 &&
2134 lt->tm_mon > to->mon - 1 )
2135 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002136
Paul Bakker40ea7de2009-05-03 10:18:48 +00002137 if( lt->tm_year == to->year - 1900 &&
2138 lt->tm_mon == to->mon - 1 &&
2139 lt->tm_mday > to->day )
2140 return( 1 );
2141
2142 return( 0 );
2143}
2144
2145/*
2146 * Return 1 if the certificate is revoked, or 0 otherwise.
2147 */
2148int x509parse_revoked( x509_cert *crt, x509_crl *crl )
2149{
2150 x509_crl_entry *cur = &crl->entry;
2151
2152 while( cur != NULL && cur->serial.len != 0 )
2153 {
2154 if( memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
2155 {
2156 if( x509parse_time_expired( &cur->revocation_date ) )
2157 return( 1 );
2158 }
2159
2160 cur = cur->next;
2161 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002162
2163 return( 0 );
2164}
2165
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002166/*
2167 * Wrapper for x509 hashes.
2168 *
2169 * @param out Buffer to receive the hash (Should be at least 64 bytes)
2170 */
Paul Bakker5121ce52009-01-03 21:22:43 +00002171static void x509_hash( unsigned char *in, int len, int alg,
2172 unsigned char *out )
2173{
2174 switch( alg )
2175 {
Paul Bakker40e46942009-01-03 21:51:57 +00002176#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002177 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002178#endif
Paul Bakker40e46942009-01-03 21:51:57 +00002179#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002180 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002181#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002182#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002183 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002184#endif
2185#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002186 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002187#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00002188#if defined(POLARSSL_SHA2_C)
2189 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
2190 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
2191#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00002192#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002193 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
2194 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
2195#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002196 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002197 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002198 break;
2199 }
2200}
2201
2202/*
2203 * Verify the certificate validity
2204 */
2205int x509parse_verify( x509_cert *crt,
2206 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00002207 x509_crl *ca_crl,
Paul Bakker5121ce52009-01-03 21:22:43 +00002208 char *cn, int *flags )
2209{
2210 int cn_len;
2211 int hash_id;
2212 int pathlen;
2213 x509_cert *cur;
2214 x509_name *name;
Paul Bakker4593aea2009-02-09 22:32:35 +00002215 unsigned char hash[64];
Paul Bakker5121ce52009-01-03 21:22:43 +00002216
Paul Bakker40ea7de2009-05-03 10:18:48 +00002217 *flags = 0;
2218
2219 if( x509parse_time_expired( &crt->valid_to ) )
2220 *flags = BADCERT_EXPIRED;
Paul Bakker5121ce52009-01-03 21:22:43 +00002221
2222 if( cn != NULL )
2223 {
2224 name = &crt->subject;
2225 cn_len = strlen( cn );
2226
2227 while( name != NULL )
2228 {
2229 if( memcmp( name->oid.p, OID_CN, 3 ) == 0 &&
2230 memcmp( name->val.p, cn, cn_len ) == 0 &&
2231 name->val.len == cn_len )
2232 break;
2233
2234 name = name->next;
2235 }
2236
2237 if( name == NULL )
2238 *flags |= BADCERT_CN_MISMATCH;
2239 }
2240
2241 *flags |= BADCERT_NOT_TRUSTED;
2242
2243 /*
2244 * Iterate upwards in the given cert chain,
2245 * ignoring any upper cert with CA != TRUE.
2246 */
2247 cur = crt->next;
2248
2249 pathlen = 1;
2250
Paul Bakker7c6d4a42009-03-28 20:35:47 +00002251 while( cur != NULL && cur->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002252 {
2253 if( cur->ca_istrue == 0 ||
2254 crt->issuer_raw.len != cur->subject_raw.len ||
2255 memcmp( crt->issuer_raw.p, cur->subject_raw.p,
2256 crt->issuer_raw.len ) != 0 )
2257 {
2258 cur = cur->next;
2259 continue;
2260 }
2261
2262 hash_id = crt->sig_oid1.p[8];
2263
2264 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2265
2266 if( rsa_pkcs1_verify( &cur->rsa, RSA_PUBLIC, hash_id,
2267 0, hash, crt->sig.p ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00002268 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002269
2270 pathlen++;
2271
2272 crt = cur;
2273 cur = crt->next;
2274 }
2275
2276 /*
2277 * Atempt to validate topmost cert with our CA chain.
2278 */
Paul Bakker7c6d4a42009-03-28 20:35:47 +00002279 while( trust_ca != NULL && trust_ca->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002280 {
2281 if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
2282 memcmp( crt->issuer_raw.p, trust_ca->subject_raw.p,
2283 crt->issuer_raw.len ) != 0 )
2284 {
2285 trust_ca = trust_ca->next;
2286 continue;
2287 }
2288
2289 if( trust_ca->max_pathlen > 0 &&
2290 trust_ca->max_pathlen < pathlen )
2291 break;
2292
2293 hash_id = crt->sig_oid1.p[8];
2294
2295 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2296
2297 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
2298 0, hash, crt->sig.p ) == 0 )
2299 {
2300 /*
2301 * cert. is signed by a trusted CA
2302 */
2303 *flags &= ~BADCERT_NOT_TRUSTED;
2304 break;
2305 }
2306
2307 trust_ca = trust_ca->next;
2308 }
2309
Paul Bakker40ea7de2009-05-03 10:18:48 +00002310 /*
2311 * TODO: What happens if no CRL is present?
2312 * Suggestion: Revocation state should be unknown if no CRL is present.
2313 * For backwards compatibility this is not yet implemented.
2314 */
2315
2316 /*
2317 * Check if the topmost certificate is revoked if the trusted CA is
2318 * determined.
2319 */
2320 while( trust_ca != NULL && ca_crl != NULL && ca_crl->version != 0 )
2321 {
2322 if( ca_crl->issuer_raw.len != trust_ca->subject_raw.len ||
2323 memcmp( ca_crl->issuer_raw.p, trust_ca->subject_raw.p,
2324 ca_crl->issuer_raw.len ) != 0 )
2325 {
2326 ca_crl = ca_crl->next;
2327 continue;
2328 }
2329
2330 /*
2331 * Check if CRL is correctry signed by the trusted CA
2332 */
2333 hash_id = ca_crl->sig_oid1.p[8];
2334
2335 x509_hash( ca_crl->tbs.p, ca_crl->tbs.len, hash_id, hash );
2336
2337 if( !rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
2338 0, hash, ca_crl->sig.p ) == 0 )
2339 {
2340 /*
2341 * CRL is not trusted
2342 */
2343 *flags |= BADCRL_NOT_TRUSTED;
2344 break;
2345 }
2346
2347 /*
2348 * Check for validity of CRL (Do not drop out)
2349 */
2350 if( x509parse_time_expired( &ca_crl->next_update ) )
2351 *flags |= BADCRL_EXPIRED;
2352
2353 /*
2354 * Check if certificate is revoked
2355 */
2356 if( x509parse_revoked(crt, ca_crl) )
2357 {
2358 *flags |= BADCERT_REVOKED;
2359 break;
2360 }
2361
2362 ca_crl = ca_crl->next;
2363 }
2364
Paul Bakker5121ce52009-01-03 21:22:43 +00002365 if( *flags != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00002366 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002367
2368 return( 0 );
2369}
2370
2371/*
2372 * Unallocate all certificate data
2373 */
2374void x509_free( x509_cert *crt )
2375{
2376 x509_cert *cert_cur = crt;
2377 x509_cert *cert_prv;
2378 x509_name *name_cur;
2379 x509_name *name_prv;
2380
2381 if( crt == NULL )
2382 return;
2383
2384 do
2385 {
2386 rsa_free( &cert_cur->rsa );
2387
2388 name_cur = cert_cur->issuer.next;
2389 while( name_cur != NULL )
2390 {
2391 name_prv = name_cur;
2392 name_cur = name_cur->next;
2393 memset( name_prv, 0, sizeof( x509_name ) );
2394 free( name_prv );
2395 }
2396
2397 name_cur = cert_cur->subject.next;
2398 while( name_cur != NULL )
2399 {
2400 name_prv = name_cur;
2401 name_cur = name_cur->next;
2402 memset( name_prv, 0, sizeof( x509_name ) );
2403 free( name_prv );
2404 }
2405
2406 if( cert_cur->raw.p != NULL )
2407 {
2408 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
2409 free( cert_cur->raw.p );
2410 }
2411
2412 cert_cur = cert_cur->next;
2413 }
2414 while( cert_cur != NULL );
2415
2416 cert_cur = crt;
2417 do
2418 {
2419 cert_prv = cert_cur;
2420 cert_cur = cert_cur->next;
2421
2422 memset( cert_prv, 0, sizeof( x509_cert ) );
2423 if( cert_prv != crt )
2424 free( cert_prv );
2425 }
2426 while( cert_cur != NULL );
2427}
2428
Paul Bakkerd98030e2009-05-02 15:13:40 +00002429/*
2430 * Unallocate all CRL data
2431 */
2432void x509_crl_free( x509_crl *crl )
2433{
2434 x509_crl *crl_cur = crl;
2435 x509_crl *crl_prv;
2436 x509_name *name_cur;
2437 x509_name *name_prv;
2438 x509_crl_entry *entry_cur;
2439 x509_crl_entry *entry_prv;
2440
2441 if( crl == NULL )
2442 return;
2443
2444 do
2445 {
2446 name_cur = crl_cur->issuer.next;
2447 while( name_cur != NULL )
2448 {
2449 name_prv = name_cur;
2450 name_cur = name_cur->next;
2451 memset( name_prv, 0, sizeof( x509_name ) );
2452 free( name_prv );
2453 }
2454
2455 entry_cur = crl_cur->entry.next;
2456 while( entry_cur != NULL )
2457 {
2458 entry_prv = entry_cur;
2459 entry_cur = entry_cur->next;
2460 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
2461 free( entry_prv );
2462 }
2463
2464 if( crl_cur->raw.p != NULL )
2465 {
2466 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
2467 free( crl_cur->raw.p );
2468 }
2469
2470 crl_cur = crl_cur->next;
2471 }
2472 while( crl_cur != NULL );
2473
2474 crl_cur = crl;
2475 do
2476 {
2477 crl_prv = crl_cur;
2478 crl_cur = crl_cur->next;
2479
2480 memset( crl_prv, 0, sizeof( x509_crl ) );
2481 if( crl_prv != crl )
2482 free( crl_prv );
2483 }
2484 while( crl_cur != NULL );
2485}
2486
Paul Bakker40e46942009-01-03 21:51:57 +00002487#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002488
Paul Bakker40e46942009-01-03 21:51:57 +00002489#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00002490
2491/*
2492 * Checkup routine
2493 */
2494int x509_self_test( int verbose )
2495{
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002496#if defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00002497 int ret, i, j;
2498 x509_cert cacert;
2499 x509_cert clicert;
2500 rsa_context rsa;
2501
2502 if( verbose != 0 )
2503 printf( " X.509 certificate load: " );
2504
2505 memset( &clicert, 0, sizeof( x509_cert ) );
2506
2507 ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
2508 strlen( test_cli_crt ) );
2509 if( ret != 0 )
2510 {
2511 if( verbose != 0 )
2512 printf( "failed\n" );
2513
2514 return( ret );
2515 }
2516
2517 memset( &cacert, 0, sizeof( x509_cert ) );
2518
2519 ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
2520 strlen( test_ca_crt ) );
2521 if( ret != 0 )
2522 {
2523 if( verbose != 0 )
2524 printf( "failed\n" );
2525
2526 return( ret );
2527 }
2528
2529 if( verbose != 0 )
2530 printf( "passed\n X.509 private key load: " );
2531
2532 i = strlen( test_ca_key );
2533 j = strlen( test_ca_pwd );
2534
2535 if( ( ret = x509parse_key( &rsa,
2536 (unsigned char *) test_ca_key, i,
2537 (unsigned char *) test_ca_pwd, j ) ) != 0 )
2538 {
2539 if( verbose != 0 )
2540 printf( "failed\n" );
2541
2542 return( ret );
2543 }
2544
2545 if( verbose != 0 )
2546 printf( "passed\n X.509 signature verify: ");
2547
Paul Bakker1973e4c2009-07-10 22:32:40 +00002548 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &i );
Paul Bakker5121ce52009-01-03 21:22:43 +00002549 if( ret != 0 )
2550 {
2551 if( verbose != 0 )
2552 printf( "failed\n" );
2553
2554 return( ret );
2555 }
2556
2557 if( verbose != 0 )
2558 printf( "passed\n\n" );
2559
2560 x509_free( &cacert );
2561 x509_free( &clicert );
2562 rsa_free( &rsa );
2563
2564 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002565#else
2566 ((void) verbose);
2567 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
2568#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002569}
2570
2571#endif
2572
2573#endif