blob: dcb8ea9fad158d4754f7eff0279cf61ccf76d26f [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * X.509 certificate and private key decoding
3 *
Paul Bakkere0ccd0a2009-01-04 16:27:10 +00004 * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
5 *
Paul Bakker785a9ee2009-01-25 14:15:10 +00006 * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
Paul Bakker5121ce52009-01-03 21:22:43 +00007 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22/*
23 * The ITU-T X.509 standard defines a certificat format for PKI.
24 *
25 * http://www.ietf.org/rfc/rfc2459.txt
26 * http://www.ietf.org/rfc/rfc3279.txt
27 *
28 * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
29 *
30 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
31 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
32 */
33
Paul Bakker40e46942009-01-03 21:51:57 +000034#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000035
Paul Bakker40e46942009-01-03 21:51:57 +000036#if defined(POLARSSL_X509_PARSE_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000037
Paul Bakker40e46942009-01-03 21:51:57 +000038#include "polarssl/x509.h"
39#include "polarssl/base64.h"
40#include "polarssl/des.h"
41#include "polarssl/md2.h"
42#include "polarssl/md4.h"
43#include "polarssl/md5.h"
44#include "polarssl/sha1.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000045
46#include <string.h>
47#include <stdlib.h>
48#include <stdio.h>
49#include <time.h>
50
51/*
52 * ASN.1 DER decoding routines
53 */
54static int asn1_get_len( unsigned char **p,
55 unsigned char *end,
56 int *len )
57{
58 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +000059 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000060
61 if( ( **p & 0x80 ) == 0 )
62 *len = *(*p)++;
63 else
64 {
65 switch( **p & 0x7F )
66 {
67 case 1:
68 if( ( end - *p ) < 2 )
Paul Bakker40e46942009-01-03 21:51:57 +000069 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000070
71 *len = (*p)[1];
72 (*p) += 2;
73 break;
74
75 case 2:
76 if( ( end - *p ) < 3 )
Paul Bakker40e46942009-01-03 21:51:57 +000077 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000078
79 *len = ( (*p)[1] << 8 ) | (*p)[2];
80 (*p) += 3;
81 break;
82
83 default:
Paul Bakker40e46942009-01-03 21:51:57 +000084 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +000085 break;
86 }
87 }
88
89 if( *len > (int) ( end - *p ) )
Paul Bakker40e46942009-01-03 21:51:57 +000090 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000091
92 return( 0 );
93}
94
95static int asn1_get_tag( unsigned char **p,
96 unsigned char *end,
97 int *len, int tag )
98{
99 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000100 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000101
102 if( **p != tag )
Paul Bakker40e46942009-01-03 21:51:57 +0000103 return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000104
105 (*p)++;
106
107 return( asn1_get_len( p, end, len ) );
108}
109
110static int asn1_get_bool( unsigned char **p,
111 unsigned char *end,
112 int *val )
113{
114 int ret, len;
115
116 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 )
117 return( ret );
118
119 if( len != 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000120 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000121
122 *val = ( **p != 0 ) ? 1 : 0;
123 (*p)++;
124
125 return( 0 );
126}
127
128static int asn1_get_int( unsigned char **p,
129 unsigned char *end,
130 int *val )
131{
132 int ret, len;
133
134 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
135 return( ret );
136
137 if( len > (int) sizeof( int ) || ( **p & 0x80 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000138 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000139
140 *val = 0;
141
142 while( len-- > 0 )
143 {
144 *val = ( *val << 8 ) | **p;
145 (*p)++;
146 }
147
148 return( 0 );
149}
150
151static int asn1_get_mpi( unsigned char **p,
152 unsigned char *end,
153 mpi *X )
154{
155 int ret, len;
156
157 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
158 return( ret );
159
160 ret = mpi_read_binary( X, *p, len );
161
162 *p += len;
163
164 return( ret );
165}
166
167/*
168 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
169 */
170static int x509_get_version( unsigned char **p,
171 unsigned char *end,
172 int *ver )
173{
174 int ret, len;
175
176 if( ( ret = asn1_get_tag( p, end, &len,
177 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
178 {
Paul Bakker40e46942009-01-03 21:51:57 +0000179 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000180 return( *ver = 0 );
181
182 return( ret );
183 }
184
185 end = *p + len;
186
187 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000188 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000189
190 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000191 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION |
192 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000193
194 return( 0 );
195}
196
197/*
198 * CertificateSerialNumber ::= INTEGER
199 */
200static int x509_get_serial( unsigned char **p,
201 unsigned char *end,
202 x509_buf *serial )
203{
204 int ret;
205
206 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000207 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL |
208 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000209
210 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
211 **p != ASN1_INTEGER )
Paul Bakker40e46942009-01-03 21:51:57 +0000212 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL |
213 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000214
215 serial->tag = *(*p)++;
216
217 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000218 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000219
220 serial->p = *p;
221 *p += serial->len;
222
223 return( 0 );
224}
225
226/*
227 * AlgorithmIdentifier ::= SEQUENCE {
228 * algorithm OBJECT IDENTIFIER,
229 * parameters ANY DEFINED BY algorithm OPTIONAL }
230 */
231static int x509_get_alg( unsigned char **p,
232 unsigned char *end,
233 x509_buf *alg )
234{
235 int ret, len;
236
237 if( ( ret = asn1_get_tag( p, end, &len,
238 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000239 return( POLARSSL_ERR_X509_CERT_INVALID_ALG | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000240
241 end = *p + len;
242 alg->tag = **p;
243
244 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 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 alg->p = *p;
248 *p += alg->len;
249
250 if( *p == end )
251 return( 0 );
252
253 /*
254 * assume the algorithm parameters must be NULL
255 */
256 if( ( ret = asn1_get_tag( p, end, &len, ASN1_NULL ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000257 return( POLARSSL_ERR_X509_CERT_INVALID_ALG | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000258
259 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000260 return( POLARSSL_ERR_X509_CERT_INVALID_ALG |
261 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000262
263 return( 0 );
264}
265
266/*
267 * RelativeDistinguishedName ::=
268 * SET OF AttributeTypeAndValue
269 *
270 * AttributeTypeAndValue ::= SEQUENCE {
271 * type AttributeType,
272 * value AttributeValue }
273 *
274 * AttributeType ::= OBJECT IDENTIFIER
275 *
276 * AttributeValue ::= ANY DEFINED BY AttributeType
277 */
278static int x509_get_name( unsigned char **p,
279 unsigned char *end,
280 x509_name *cur )
281{
282 int ret, len;
283 unsigned char *end2;
284 x509_buf *oid;
285 x509_buf *val;
286
287 if( ( ret = asn1_get_tag( p, end, &len,
288 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000289 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000290
291 end2 = end;
292 end = *p + len;
293
294 if( ( ret = asn1_get_tag( p, end, &len,
295 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000296 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000297
298 if( *p + len != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000299 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
300 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000301
302 oid = &cur->oid;
303 oid->tag = **p;
304
305 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000306 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000307
308 oid->p = *p;
309 *p += oid->len;
310
311 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000312 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
313 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000314
315 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
316 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
317 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker40e46942009-01-03 21:51:57 +0000318 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
319 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000320
321 val = &cur->val;
322 val->tag = *(*p)++;
323
324 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000325 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000326
327 val->p = *p;
328 *p += val->len;
329
330 cur->next = NULL;
331
332 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000333 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
334 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000335
336 /*
337 * recurse until end of SEQUENCE is reached
338 */
339 if( *p == end2 )
340 return( 0 );
341
342 cur->next = (x509_name *) malloc(
343 sizeof( x509_name ) );
344
345 if( cur->next == NULL )
346 return( 1 );
347
348 return( x509_get_name( p, end2, cur->next ) );
349}
350
351/*
352 * Validity ::= SEQUENCE {
353 * notBefore Time,
354 * notAfter Time }
355 *
356 * Time ::= CHOICE {
357 * utcTime UTCTime,
358 * generalTime GeneralizedTime }
359 */
360static int x509_get_dates( unsigned char **p,
361 unsigned char *end,
362 x509_time *from,
363 x509_time *to )
364{
365 int ret, len;
366 char date[64];
367
368 if( ( ret = asn1_get_tag( p, end, &len,
369 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000370 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000371
372 end = *p + len;
373
374 /*
375 * TODO: also handle GeneralizedTime
376 */
377 if( ( ret = asn1_get_tag( p, end, &len, ASN1_UTC_TIME ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000378 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000379
380 memset( date, 0, sizeof( date ) );
381 memcpy( date, *p, ( len < (int) sizeof( date ) - 1 ) ?
382 len : (int) sizeof( date ) - 1 );
383
384 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
385 &from->year, &from->mon, &from->day,
386 &from->hour, &from->min, &from->sec ) < 5 )
Paul Bakker40e46942009-01-03 21:51:57 +0000387 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000388
389 from->year += 100 * ( from->year < 90 );
390 from->year += 1900;
391
392 *p += len;
393
394 if( ( ret = asn1_get_tag( p, end, &len, ASN1_UTC_TIME ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000395 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000396
397 memset( date, 0, sizeof( date ) );
398 memcpy( date, *p, ( len < (int) sizeof( date ) - 1 ) ?
399 len : (int) sizeof( date ) - 1 );
400
401 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
402 &to->year, &to->mon, &to->day,
403 &to->hour, &to->min, &to->sec ) < 5 )
Paul Bakker40e46942009-01-03 21:51:57 +0000404 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000405
406 to->year += 100 * ( to->year < 90 );
407 to->year += 1900;
408
409 *p += len;
410
411 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000412 return( POLARSSL_ERR_X509_CERT_INVALID_DATE |
413 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000414
415 return( 0 );
416}
417
418/*
419 * SubjectPublicKeyInfo ::= SEQUENCE {
420 * algorithm AlgorithmIdentifier,
421 * subjectPublicKey BIT STRING }
422 */
423static int x509_get_pubkey( unsigned char **p,
424 unsigned char *end,
425 x509_buf *pk_alg_oid,
426 mpi *N, mpi *E )
427{
428 int ret, len;
429 unsigned char *end2;
430
431 if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 )
432 return( ret );
433
434 /*
435 * only RSA public keys handled at this time
436 */
437 if( pk_alg_oid->len != 9 ||
438 memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000439 return( POLARSSL_ERR_X509_CERT_UNKNOWN_PK_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000440
441 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000442 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000443
444 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000445 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY |
446 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000447
448 end2 = *p + len;
449
450 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000451 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000452
453 /*
454 * RSAPublicKey ::= SEQUENCE {
455 * modulus INTEGER, -- n
456 * publicExponent INTEGER -- e
457 * }
458 */
459 if( ( ret = asn1_get_tag( p, end2, &len,
460 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000461 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000462
463 if( *p + len != end2 )
Paul Bakker40e46942009-01-03 21:51:57 +0000464 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY |
465 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000466
467 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
468 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000469 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000470
471 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000472 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY |
473 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000474
475 return( 0 );
476}
477
478static int x509_get_sig( unsigned char **p,
479 unsigned char *end,
480 x509_buf *sig )
481{
482 int ret, len;
483
484 sig->tag = **p;
485
486 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000487 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000488
489 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000490 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000491
492 sig->len = len;
493 sig->p = *p;
494
495 *p += len;
496
497 return( 0 );
498}
499
500/*
501 * X.509 v2/v3 unique identifier (not parsed)
502 */
503static int x509_get_uid( unsigned char **p,
504 unsigned char *end,
505 x509_buf *uid, int n )
506{
507 int ret;
508
509 if( *p == end )
510 return( 0 );
511
512 uid->tag = **p;
513
514 if( ( ret = asn1_get_tag( p, end, &uid->len,
515 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
516 {
Paul Bakker40e46942009-01-03 21:51:57 +0000517 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000518 return( 0 );
519
520 return( ret );
521 }
522
523 uid->p = *p;
524 *p += uid->len;
525
526 return( 0 );
527}
528
529/*
530 * X.509 v3 extensions (only BasicConstraints are parsed)
531 */
532static int x509_get_ext( unsigned char **p,
533 unsigned char *end,
534 x509_buf *ext,
535 int *ca_istrue,
536 int *max_pathlen )
537{
538 int ret, len;
539 int is_critical = 1;
540 int is_cacert = 0;
541 unsigned char *end2;
542
543 if( *p == end )
544 return( 0 );
545
546 ext->tag = **p;
547
548 if( ( ret = asn1_get_tag( p, end, &ext->len,
549 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) ) != 0 )
550 {
Paul Bakker40e46942009-01-03 21:51:57 +0000551 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000552 return( 0 );
553
554 return( ret );
555 }
556
557 ext->p = *p;
558 end = *p + ext->len;
559
560 /*
561 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
562 *
563 * Extension ::= SEQUENCE {
564 * extnID OBJECT IDENTIFIER,
565 * critical BOOLEAN DEFAULT FALSE,
566 * extnValue OCTET STRING }
567 */
568 if( ( ret = asn1_get_tag( p, end, &len,
569 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000570 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000571
572 if( end != *p + len )
Paul Bakker40e46942009-01-03 21:51:57 +0000573 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
574 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000575
576 while( *p < end )
577 {
578 if( ( ret = asn1_get_tag( p, end, &len,
579 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000580 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000581
582 if( memcmp( *p, "\x06\x03\x55\x1D\x13", 5 ) != 0 )
583 {
584 *p += len;
585 continue;
586 }
587
588 *p += 5;
589
590 if( ( ret = asn1_get_bool( p, end, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000591 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
592 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000593
594 if( ( ret = asn1_get_tag( p, end, &len,
595 ASN1_OCTET_STRING ) ) != 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 /*
599 * BasicConstraints ::= SEQUENCE {
600 * cA BOOLEAN DEFAULT FALSE,
601 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
602 */
603 end2 = *p + len;
604
605 if( ( ret = asn1_get_tag( p, end2, &len,
606 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000607 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000608
609 if( *p == end2 )
610 continue;
611
612 if( ( ret = asn1_get_bool( p, end2, &is_cacert ) ) != 0 )
613 {
Paul Bakker40e46942009-01-03 21:51:57 +0000614 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000615 ret = asn1_get_int( p, end2, &is_cacert );
616
617 if( ret != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000618 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000619
620 if( is_cacert != 0 )
621 is_cacert = 1;
622 }
623
624 if( *p == end2 )
625 continue;
626
627 if( ( ret = asn1_get_int( p, end2, max_pathlen ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000628 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000629
630 if( *p != end2 )
Paul Bakker40e46942009-01-03 21:51:57 +0000631 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
632 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000633
634 max_pathlen++;
635 }
636
637 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000638 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
639 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000640
641 *ca_istrue = is_critical & is_cacert;
642
643 return( 0 );
644}
645
646/*
647 * Parse one or more certificates and add them to the chained list
648 */
649int x509parse_crt( x509_cert *chain, unsigned char *buf, int buflen )
650{
651 int ret, len;
652 unsigned char *s1, *s2;
653 unsigned char *p, *end;
654 x509_cert *crt;
655
656 crt = chain;
657
658 while( crt->version != 0 )
659 crt = crt->next;
660
661 /*
662 * check if the certificate is encoded in base64
663 */
664 s1 = (unsigned char *) strstr( (char *) buf,
665 "-----BEGIN CERTIFICATE-----" );
666
667 if( s1 != NULL )
668 {
669 s2 = (unsigned char *) strstr( (char *) buf,
670 "-----END CERTIFICATE-----" );
671
672 if( s2 == NULL || s2 <= s1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000673 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +0000674
675 s1 += 27;
676 if( *s1 == '\r' ) s1++;
677 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +0000678 else return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +0000679
680 /*
681 * get the DER data length and decode the buffer
682 */
683 len = 0;
684 ret = base64_decode( NULL, &len, s1, s2 - s1 );
685
Paul Bakker40e46942009-01-03 21:51:57 +0000686 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
687 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000688
689 if( ( p = (unsigned char *) malloc( len ) ) == NULL )
690 return( 1 );
691
692 if( ( ret = base64_decode( p, &len, s1, s2 - s1 ) ) != 0 )
693 {
694 free( p );
Paul Bakker40e46942009-01-03 21:51:57 +0000695 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000696 }
697
698 /*
699 * update the buffer size and offset
700 */
701 s2 += 25;
702 if( *s2 == '\r' ) s2++;
703 if( *s2 == '\n' ) s2++;
704 else
705 {
706 free( p );
Paul Bakker40e46942009-01-03 21:51:57 +0000707 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +0000708 }
709
710 buflen -= s2 - buf;
711 buf = s2;
712 }
713 else
714 {
715 /*
716 * nope, copy the raw DER data
717 */
718 p = (unsigned char *) malloc( len = buflen );
719
720 if( p == NULL )
721 return( 1 );
722
723 memcpy( p, buf, buflen );
724
725 buflen = 0;
726 }
727
728 crt->raw.p = p;
729 crt->raw.len = len;
730 end = p + len;
731
732 /*
733 * Certificate ::= SEQUENCE {
734 * tbsCertificate TBSCertificate,
735 * signatureAlgorithm AlgorithmIdentifier,
736 * signatureValue BIT STRING }
737 */
738 if( ( ret = asn1_get_tag( &p, end, &len,
739 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
740 {
741 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000742 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +0000743 }
744
745 if( len != (int) ( end - p ) )
746 {
747 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000748 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
749 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000750 }
751
752 /*
753 * TBSCertificate ::= SEQUENCE {
754 */
755 crt->tbs.p = p;
756
757 if( ( ret = asn1_get_tag( &p, end, &len,
758 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
759 {
760 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000761 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000762 }
763
764 end = p + len;
765 crt->tbs.len = end - crt->tbs.p;
766
767 /*
768 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
769 *
770 * CertificateSerialNumber ::= INTEGER
771 *
772 * signature AlgorithmIdentifier
773 */
774 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
775 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
776 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
777 {
778 x509_free( crt );
779 return( ret );
780 }
781
782 crt->version++;
783
784 if( crt->version > 3 )
785 {
786 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000787 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +0000788 }
789
790 if( crt->sig_oid1.len != 9 ||
791 memcmp( crt->sig_oid1.p, OID_PKCS1, 8 ) != 0 )
792 {
793 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000794 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000795 }
796
797 if( crt->sig_oid1.p[8] < 2 ||
Paul Bakker4593aea2009-02-09 22:32:35 +0000798 ( crt->sig_oid1.p[8] > 5 && crt->sig_oid1.p[8] < 11 ) ||
799 crt->sig_oid1.p[8] > 14 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000800 {
801 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000802 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000803 }
804
805 /*
806 * issuer Name
807 */
808 crt->issuer_raw.p = p;
809
810 if( ( ret = asn1_get_tag( &p, end, &len,
811 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
812 {
813 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000814 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000815 }
816
817 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
818 {
819 x509_free( crt );
820 return( ret );
821 }
822
823 crt->issuer_raw.len = p - crt->issuer_raw.p;
824
825 /*
826 * Validity ::= SEQUENCE {
827 * notBefore Time,
828 * notAfter Time }
829 *
830 */
831 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
832 &crt->valid_to ) ) != 0 )
833 {
834 x509_free( crt );
835 return( ret );
836 }
837
838 /*
839 * subject Name
840 */
841 crt->subject_raw.p = p;
842
843 if( ( ret = asn1_get_tag( &p, end, &len,
844 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
845 {
846 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000847 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000848 }
849
850 if( ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
851 {
852 x509_free( crt );
853 return( ret );
854 }
855
856 crt->subject_raw.len = p - crt->subject_raw.p;
857
858 /*
859 * SubjectPublicKeyInfo ::= SEQUENCE
860 * algorithm AlgorithmIdentifier,
861 * subjectPublicKey BIT STRING }
862 */
863 if( ( ret = asn1_get_tag( &p, end, &len,
864 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
865 {
866 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000867 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000868 }
869
870 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
871 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
872 {
873 x509_free( crt );
874 return( ret );
875 }
876
877 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
878 {
879 x509_free( crt );
880 return( ret );
881 }
882
883 crt->rsa.len = mpi_size( &crt->rsa.N );
884
885 /*
886 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
887 * -- If present, version shall be v2 or v3
888 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
889 * -- If present, version shall be v2 or v3
890 * extensions [3] EXPLICIT Extensions OPTIONAL
891 * -- If present, version shall be v3
892 */
893 if( crt->version == 2 || crt->version == 3 )
894 {
895 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
896 if( ret != 0 )
897 {
898 x509_free( crt );
899 return( ret );
900 }
901 }
902
903 if( crt->version == 2 || crt->version == 3 )
904 {
905 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
906 if( ret != 0 )
907 {
908 x509_free( crt );
909 return( ret );
910 }
911 }
912
913 if( crt->version == 3 )
914 {
915 ret = x509_get_ext( &p, end, &crt->v3_ext,
916 &crt->ca_istrue, &crt->max_pathlen );
917 if( ret != 0 )
918 {
919 x509_free( crt );
920 return( ret );
921 }
922 }
923
924 if( p != end )
925 {
926 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000927 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
928 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000929 }
930
931 end = crt->raw.p + crt->raw.len;
932
933 /*
934 * signatureAlgorithm AlgorithmIdentifier,
935 * signatureValue BIT STRING
936 */
937 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
938 {
939 x509_free( crt );
940 return( ret );
941 }
942
943 if( memcmp( crt->sig_oid1.p, crt->sig_oid2.p, 9 ) != 0 )
944 {
945 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000946 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000947 }
948
949 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
950 {
951 x509_free( crt );
952 return( ret );
953 }
954
955 if( p != end )
956 {
957 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000958 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
959 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000960 }
961
962 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
963
964 if( crt->next == NULL )
965 {
966 x509_free( crt );
967 return( 1 );
968 }
969
970 crt = crt->next;
971 memset( crt, 0, sizeof( x509_cert ) );
972
973 if( buflen > 0 )
974 return( x509parse_crt( crt, buf, buflen ) );
975
976 return( 0 );
977}
978
979/*
980 * Load one or more certificates and add them to the chained list
981 */
982int x509parse_crtfile( x509_cert *chain, char *path )
983{
984 int ret;
985 FILE *f;
986 size_t n;
987 unsigned char *buf;
988
989 if( ( f = fopen( path, "rb" ) ) == NULL )
990 return( 1 );
991
992 fseek( f, 0, SEEK_END );
993 n = (size_t) ftell( f );
994 fseek( f, 0, SEEK_SET );
995
996 if( ( buf = (unsigned char *) malloc( n + 1 ) ) == NULL )
997 return( 1 );
998
999 if( fread( buf, 1, n, f ) != n )
1000 {
1001 fclose( f );
1002 free( buf );
1003 return( 1 );
1004 }
1005
1006 buf[n] = '\0';
1007
1008 ret = x509parse_crt( chain, buf, (int) n );
1009
1010 memset( buf, 0, n + 1 );
1011 free( buf );
1012 fclose( f );
1013
1014 return( ret );
1015}
1016
Paul Bakker40e46942009-01-03 21:51:57 +00001017#if defined(POLARSSL_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001018/*
1019 * Read a 16-byte hex string and convert it to binary
1020 */
1021static int x509_get_iv( unsigned char *s, unsigned char iv[8] )
1022{
1023 int i, j, k;
1024
1025 memset( iv, 0, 8 );
1026
1027 for( i = 0; i < 16; i++, s++ )
1028 {
1029 if( *s >= '0' && *s <= '9' ) j = *s - '0'; else
1030 if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else
1031 if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else
Paul Bakker40e46942009-01-03 21:51:57 +00001032 return( POLARSSL_ERR_X509_KEY_INVALID_ENC_IV );
Paul Bakker5121ce52009-01-03 21:22:43 +00001033
1034 k = ( ( i & 1 ) != 0 ) ? j : j << 4;
1035
1036 iv[i >> 1] = (unsigned char)( iv[i >> 1] | k );
1037 }
1038
1039 return( 0 );
1040}
1041
1042/*
1043 * Decrypt with 3DES-CBC, using PBKDF1 for key derivation
1044 */
1045static void x509_des3_decrypt( unsigned char des3_iv[8],
1046 unsigned char *buf, int buflen,
1047 unsigned char *pwd, int pwdlen )
1048{
1049 md5_context md5_ctx;
1050 des3_context des3_ctx;
1051 unsigned char md5sum[16];
1052 unsigned char des3_key[24];
1053
1054 /*
1055 * 3DES key[ 0..15] = MD5(pwd || IV)
1056 * key[16..23] = MD5(pwd || IV || 3DES key[ 0..15])
1057 */
1058 md5_starts( &md5_ctx );
1059 md5_update( &md5_ctx, pwd, pwdlen );
1060 md5_update( &md5_ctx, des3_iv, 8 );
1061 md5_finish( &md5_ctx, md5sum );
1062 memcpy( des3_key, md5sum, 16 );
1063
1064 md5_starts( &md5_ctx );
1065 md5_update( &md5_ctx, md5sum, 16 );
1066 md5_update( &md5_ctx, pwd, pwdlen );
1067 md5_update( &md5_ctx, des3_iv, 8 );
1068 md5_finish( &md5_ctx, md5sum );
1069 memcpy( des3_key + 16, md5sum, 8 );
1070
1071 des3_set3key_dec( &des3_ctx, des3_key );
1072 des3_crypt_cbc( &des3_ctx, DES_DECRYPT, buflen,
1073 des3_iv, buf, buf );
1074
1075 memset( &md5_ctx, 0, sizeof( md5_ctx ) );
1076 memset( &des3_ctx, 0, sizeof( des3_ctx ) );
1077 memset( md5sum, 0, 16 );
1078 memset( des3_key, 0, 24 );
1079}
1080#endif
1081
1082/*
1083 * Parse a private RSA key
1084 */
1085int x509parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
1086 unsigned char *pwd, int pwdlen )
1087{
1088 int ret, len, enc;
1089 unsigned char *s1, *s2;
1090 unsigned char *p, *end;
1091 unsigned char des3_iv[8];
1092
1093 s1 = (unsigned char *) strstr( (char *) buf,
1094 "-----BEGIN RSA PRIVATE KEY-----" );
1095
1096 if( s1 != NULL )
1097 {
1098 s2 = (unsigned char *) strstr( (char *) buf,
1099 "-----END RSA PRIVATE KEY-----" );
1100
1101 if( s2 == NULL || s2 <= s1 )
Paul Bakker40e46942009-01-03 21:51:57 +00001102 return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001103
1104 s1 += 31;
1105 if( *s1 == '\r' ) s1++;
1106 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001107 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001108
1109 enc = 0;
1110
1111 if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
1112 {
Paul Bakker40e46942009-01-03 21:51:57 +00001113#if defined(POLARSSL_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001114 enc++;
1115
1116 s1 += 22;
1117 if( *s1 == '\r' ) s1++;
1118 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001119 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001120
1121 if( memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001122 return( POLARSSL_ERR_X509_KEY_UNKNOWN_ENC_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +00001123
1124 s1 += 23;
1125 if( x509_get_iv( s1, des3_iv ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001126 return( POLARSSL_ERR_X509_KEY_INVALID_ENC_IV );
Paul Bakker5121ce52009-01-03 21:22:43 +00001127
1128 s1 += 16;
1129 if( *s1 == '\r' ) s1++;
1130 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001131 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001132#else
Paul Bakker40e46942009-01-03 21:51:57 +00001133 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001134#endif
1135 }
1136
1137 len = 0;
1138 ret = base64_decode( NULL, &len, s1, s2 - s1 );
1139
Paul Bakker40e46942009-01-03 21:51:57 +00001140 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
1141 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001142
1143 if( ( buf = (unsigned char *) malloc( len ) ) == NULL )
1144 return( 1 );
1145
1146 if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
1147 {
1148 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001149 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001150 }
1151
1152 buflen = len;
1153
1154 if( enc != 0 )
1155 {
Paul Bakker40e46942009-01-03 21:51:57 +00001156#if defined(POLARSSL_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001157 if( pwd == NULL )
1158 {
1159 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001160 return( POLARSSL_ERR_X509_KEY_PASSWORD_REQUIRED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001161 }
1162
1163 x509_des3_decrypt( des3_iv, buf, buflen, pwd, pwdlen );
1164
1165 if( buf[0] != 0x30 || buf[1] != 0x82 ||
1166 buf[4] != 0x02 || buf[5] != 0x01 )
1167 {
1168 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001169 return( POLARSSL_ERR_X509_KEY_PASSWORD_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001170 }
1171#else
Paul Bakker40e46942009-01-03 21:51:57 +00001172 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001173#endif
1174 }
1175 }
1176
1177 memset( rsa, 0, sizeof( rsa_context ) );
1178
1179 p = buf;
1180 end = buf + buflen;
1181
1182 /*
1183 * RSAPrivateKey ::= SEQUENCE {
1184 * version Version,
1185 * modulus INTEGER, -- n
1186 * publicExponent INTEGER, -- e
1187 * privateExponent INTEGER, -- d
1188 * prime1 INTEGER, -- p
1189 * prime2 INTEGER, -- q
1190 * exponent1 INTEGER, -- d mod (p-1)
1191 * exponent2 INTEGER, -- d mod (q-1)
1192 * coefficient INTEGER, -- (inverse of q) mod p
1193 * otherPrimeInfos OtherPrimeInfos OPTIONAL
1194 * }
1195 */
1196 if( ( ret = asn1_get_tag( &p, end, &len,
1197 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1198 {
1199 if( s1 != NULL )
1200 free( buf );
1201
1202 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001203 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001204 }
1205
1206 end = p + len;
1207
1208 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
1209 {
1210 if( s1 != NULL )
1211 free( buf );
1212
1213 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001214 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001215 }
1216
1217 if( rsa->ver != 0 )
1218 {
1219 if( s1 != NULL )
1220 free( buf );
1221
1222 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001223 return( ret | POLARSSL_ERR_X509_KEY_INVALID_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001224 }
1225
1226 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
1227 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
1228 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
1229 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
1230 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
1231 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
1232 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
1233 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
1234 {
1235 if( s1 != NULL )
1236 free( buf );
1237
1238 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001239 return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001240 }
1241
1242 rsa->len = mpi_size( &rsa->N );
1243
1244 if( p != end )
1245 {
1246 if( s1 != NULL )
1247 free( buf );
1248
1249 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001250 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT |
1251 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001252 }
1253
1254 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
1255 {
1256 if( s1 != NULL )
1257 free( buf );
1258
1259 rsa_free( rsa );
1260 return( ret );
1261 }
1262
1263 if( s1 != NULL )
1264 free( buf );
1265
1266 return( 0 );
1267}
1268
1269/*
1270 * Load and parse a private RSA key
1271 */
1272int x509parse_keyfile( rsa_context *rsa, char *path, char *pwd )
1273{
1274 int ret;
1275 FILE *f;
1276 size_t n;
1277 unsigned char *buf;
1278
1279 if( ( f = fopen( path, "rb" ) ) == NULL )
1280 return( 1 );
1281
1282 fseek( f, 0, SEEK_END );
1283 n = (size_t) ftell( f );
1284 fseek( f, 0, SEEK_SET );
1285
1286 if( ( buf = (unsigned char *) malloc( n + 1 ) ) == NULL )
1287 return( 1 );
1288
1289 if( fread( buf, 1, n, f ) != n )
1290 {
1291 fclose( f );
1292 free( buf );
1293 return( 1 );
1294 }
1295
1296 buf[n] = '\0';
1297
1298 if( pwd == NULL )
1299 ret = x509parse_key( rsa, buf, (int) n, NULL, 0 );
1300 else
1301 ret = x509parse_key( rsa, buf, (int) n,
1302 (unsigned char *) pwd, strlen( pwd ) );
1303
1304 memset( buf, 0, n + 1 );
1305 free( buf );
1306 fclose( f );
1307
1308 return( ret );
1309}
1310
1311#if defined _MSC_VER && !defined snprintf
1312#define snprintf _snprintf
1313#endif
1314
1315/*
1316 * Store the name in printable form into buf; no more
1317 * than (end - buf) characters will be written
1318 */
1319int x509parse_dn_gets( char *buf, char *end, x509_name *dn )
1320{
1321 int i;
1322 unsigned char c;
1323 x509_name *name;
1324 char s[128], *p;
1325
1326 memset( s, 0, sizeof( s ) );
1327
1328 name = dn;
1329 p = buf;
1330
1331 while( name != NULL )
1332 {
1333 if( name != dn )
1334 p += snprintf( p, end - p, ", " );
1335
1336 if( memcmp( name->oid.p, OID_X520, 2 ) == 0 )
1337 {
1338 switch( name->oid.p[2] )
1339 {
1340 case X520_COMMON_NAME:
1341 p += snprintf( p, end - p, "CN=" ); break;
1342
1343 case X520_COUNTRY:
1344 p += snprintf( p, end - p, "C=" ); break;
1345
1346 case X520_LOCALITY:
1347 p += snprintf( p, end - p, "L=" ); break;
1348
1349 case X520_STATE:
1350 p += snprintf( p, end - p, "ST=" ); break;
1351
1352 case X520_ORGANIZATION:
1353 p += snprintf( p, end - p, "O=" ); break;
1354
1355 case X520_ORG_UNIT:
1356 p += snprintf( p, end - p, "OU=" ); break;
1357
1358 default:
1359 p += snprintf( p, end - p, "0x%02X=",
1360 name->oid.p[2] );
1361 break;
1362 }
1363 }
1364 else if( memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
1365 {
1366 switch( name->oid.p[8] )
1367 {
1368 case PKCS9_EMAIL:
1369 p += snprintf( p, end - p, "emailAddress=" ); break;
1370
1371 default:
1372 p += snprintf( p, end - p, "0x%02X=",
1373 name->oid.p[8] );
1374 break;
1375 }
1376 }
1377 else
1378 p += snprintf( p, end - p, "\?\?=" );
1379
1380 for( i = 0; i < name->val.len; i++ )
1381 {
1382 if( i >= (int) sizeof( s ) - 1 )
1383 break;
1384
1385 c = name->val.p[i];
1386 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
1387 s[i] = '?';
1388 else s[i] = c;
1389 }
1390 s[i] = '\0';
1391 p += snprintf( p, end - p, "%s", s );
1392 name = name->next;
1393 }
1394
1395 return( p - buf );
1396}
1397
1398/*
1399 * Return an informational string about the
1400 * certificate, or NULL if memory allocation failed
1401 */
1402char *x509parse_cert_info( char *prefix, x509_cert *crt )
1403{
1404 int i, n;
1405 char *p, *end;
Paul Bakker3681b112009-02-07 17:14:21 +00001406 static char buf[1024];
Paul Bakker5121ce52009-01-03 21:22:43 +00001407
1408 p = buf;
1409 end = buf + sizeof( buf ) - 1;
1410
1411 p += snprintf( p, end - p, "%scert. version : %d\n",
1412 prefix, crt->version );
1413 p += snprintf( p, end - p, "%sserial number : ",
1414 prefix );
1415
1416 n = ( crt->serial.len <= 32 )
1417 ? crt->serial.len : 32;
1418
1419 for( i = 0; i < n; i++ )
1420 p += snprintf( p, end - p, "%02X%s",
1421 crt->serial.p[i], ( i < n - 1 ) ? ":" : "" );
1422
1423 p += snprintf( p, end - p, "\n%sissuer name : ", prefix );
1424 p += x509parse_dn_gets( p, end, &crt->issuer );
1425
1426 p += snprintf( p, end - p, "\n%ssubject name : ", prefix );
1427 p += x509parse_dn_gets( p, end, &crt->subject );
1428
1429 p += snprintf( p, end - p, "\n%sissued on : " \
1430 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1431 crt->valid_from.year, crt->valid_from.mon,
1432 crt->valid_from.day, crt->valid_from.hour,
1433 crt->valid_from.min, crt->valid_from.sec );
1434
1435 p += snprintf( p, end - p, "\n%sexpires on : " \
1436 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1437 crt->valid_to.year, crt->valid_to.mon,
1438 crt->valid_to.day, crt->valid_to.hour,
1439 crt->valid_to.min, crt->valid_to.sec );
1440
1441 p += snprintf( p, end - p, "\n%ssigned using : RSA+", prefix );
1442
1443 switch( crt->sig_oid1.p[8] )
1444 {
Paul Bakker4593aea2009-02-09 22:32:35 +00001445 case SIG_RSA_MD2 : p += snprintf( p, end - p, "MD2" ); break;
1446 case SIG_RSA_MD4 : p += snprintf( p, end - p, "MD4" ); break;
1447 case SIG_RSA_MD5 : p += snprintf( p, end - p, "MD5" ); break;
1448 case SIG_RSA_SHA1 : p += snprintf( p, end - p, "SHA1" ); break;
1449 case SIG_RSA_SHA224 : p += snprintf( p, end - p, "SHA224" ); break;
1450 case SIG_RSA_SHA256 : p += snprintf( p, end - p, "SHA256" ); break;
1451 case SIG_RSA_SHA384 : p += snprintf( p, end - p, "SHA384" ); break;
1452 case SIG_RSA_SHA512 : p += snprintf( p, end - p, "SHA512" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001453 default: p += snprintf( p, end - p, "???" ); break;
1454 }
1455
1456 p += snprintf( p, end - p, "\n%sRSA key size : %d bits\n", prefix,
1457 crt->rsa.N.n * (int) sizeof( unsigned long ) * 8 );
1458
1459 return( buf );
1460}
1461
1462/*
1463 * Return 0 if the certificate is still valid, or BADCERT_EXPIRED
1464 */
1465int x509parse_expired( x509_cert *crt )
1466{
1467 struct tm *lt;
1468 time_t tt;
1469
1470 tt = time( NULL );
1471 lt = localtime( &tt );
1472
1473 if( lt->tm_year > crt->valid_to.year - 1900 )
1474 return( BADCERT_EXPIRED );
1475
1476 if( lt->tm_year == crt->valid_to.year - 1900 &&
1477 lt->tm_mon > crt->valid_to.mon - 1 )
1478 return( BADCERT_EXPIRED );
1479
1480 if( lt->tm_year == crt->valid_to.year - 1900 &&
1481 lt->tm_mon == crt->valid_to.mon - 1 &&
1482 lt->tm_mday > crt->valid_to.day )
1483 return( BADCERT_EXPIRED );
1484
1485 return( 0 );
1486}
1487
1488static void x509_hash( unsigned char *in, int len, int alg,
1489 unsigned char *out )
1490{
1491 switch( alg )
1492 {
Paul Bakker40e46942009-01-03 21:51:57 +00001493#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00001494 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001495#endif
Paul Bakker40e46942009-01-03 21:51:57 +00001496#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00001497 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001498#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00001499 case SIG_RSA_MD5 : md5( in, len, out ); break;
1500 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
1501#if defined(POLARSSL_SHA2_C)
1502 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
1503 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
1504#endif
1505#if defined(POLARSSL_SHA2_C)
1506 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
1507 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
1508#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001509 default:
1510 memset( out, '\xFF', len );
1511 break;
1512 }
1513}
1514
1515/*
1516 * Verify the certificate validity
1517 */
1518int x509parse_verify( x509_cert *crt,
1519 x509_cert *trust_ca,
1520 char *cn, int *flags )
1521{
1522 int cn_len;
1523 int hash_id;
1524 int pathlen;
1525 x509_cert *cur;
1526 x509_name *name;
Paul Bakker4593aea2009-02-09 22:32:35 +00001527 unsigned char hash[64];
Paul Bakker5121ce52009-01-03 21:22:43 +00001528
1529 *flags = x509parse_expired( crt );
1530
1531 if( cn != NULL )
1532 {
1533 name = &crt->subject;
1534 cn_len = strlen( cn );
1535
1536 while( name != NULL )
1537 {
1538 if( memcmp( name->oid.p, OID_CN, 3 ) == 0 &&
1539 memcmp( name->val.p, cn, cn_len ) == 0 &&
1540 name->val.len == cn_len )
1541 break;
1542
1543 name = name->next;
1544 }
1545
1546 if( name == NULL )
1547 *flags |= BADCERT_CN_MISMATCH;
1548 }
1549
1550 *flags |= BADCERT_NOT_TRUSTED;
1551
1552 /*
1553 * Iterate upwards in the given cert chain,
1554 * ignoring any upper cert with CA != TRUE.
1555 */
1556 cur = crt->next;
1557
1558 pathlen = 1;
1559
1560 while( cur->version != 0 )
1561 {
1562 if( cur->ca_istrue == 0 ||
1563 crt->issuer_raw.len != cur->subject_raw.len ||
1564 memcmp( crt->issuer_raw.p, cur->subject_raw.p,
1565 crt->issuer_raw.len ) != 0 )
1566 {
1567 cur = cur->next;
1568 continue;
1569 }
1570
1571 hash_id = crt->sig_oid1.p[8];
1572
1573 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
1574
1575 if( rsa_pkcs1_verify( &cur->rsa, RSA_PUBLIC, hash_id,
1576 0, hash, crt->sig.p ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001577 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001578
1579 pathlen++;
1580
1581 crt = cur;
1582 cur = crt->next;
1583 }
1584
1585 /*
1586 * Atempt to validate topmost cert with our CA chain.
1587 */
1588 while( trust_ca->version != 0 )
1589 {
1590 if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
1591 memcmp( crt->issuer_raw.p, trust_ca->subject_raw.p,
1592 crt->issuer_raw.len ) != 0 )
1593 {
1594 trust_ca = trust_ca->next;
1595 continue;
1596 }
1597
1598 if( trust_ca->max_pathlen > 0 &&
1599 trust_ca->max_pathlen < pathlen )
1600 break;
1601
1602 hash_id = crt->sig_oid1.p[8];
1603
1604 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
1605
1606 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
1607 0, hash, crt->sig.p ) == 0 )
1608 {
1609 /*
1610 * cert. is signed by a trusted CA
1611 */
1612 *flags &= ~BADCERT_NOT_TRUSTED;
1613 break;
1614 }
1615
1616 trust_ca = trust_ca->next;
1617 }
1618
1619 if( *flags != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001620 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001621
1622 return( 0 );
1623}
1624
1625/*
1626 * Unallocate all certificate data
1627 */
1628void x509_free( x509_cert *crt )
1629{
1630 x509_cert *cert_cur = crt;
1631 x509_cert *cert_prv;
1632 x509_name *name_cur;
1633 x509_name *name_prv;
1634
1635 if( crt == NULL )
1636 return;
1637
1638 do
1639 {
1640 rsa_free( &cert_cur->rsa );
1641
1642 name_cur = cert_cur->issuer.next;
1643 while( name_cur != NULL )
1644 {
1645 name_prv = name_cur;
1646 name_cur = name_cur->next;
1647 memset( name_prv, 0, sizeof( x509_name ) );
1648 free( name_prv );
1649 }
1650
1651 name_cur = cert_cur->subject.next;
1652 while( name_cur != NULL )
1653 {
1654 name_prv = name_cur;
1655 name_cur = name_cur->next;
1656 memset( name_prv, 0, sizeof( x509_name ) );
1657 free( name_prv );
1658 }
1659
1660 if( cert_cur->raw.p != NULL )
1661 {
1662 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
1663 free( cert_cur->raw.p );
1664 }
1665
1666 cert_cur = cert_cur->next;
1667 }
1668 while( cert_cur != NULL );
1669
1670 cert_cur = crt;
1671 do
1672 {
1673 cert_prv = cert_cur;
1674 cert_cur = cert_cur->next;
1675
1676 memset( cert_prv, 0, sizeof( x509_cert ) );
1677 if( cert_prv != crt )
1678 free( cert_prv );
1679 }
1680 while( cert_cur != NULL );
1681}
1682
Paul Bakker40e46942009-01-03 21:51:57 +00001683#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001684
Paul Bakker40e46942009-01-03 21:51:57 +00001685#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00001686
1687/*
1688 * Checkup routine
1689 */
1690int x509_self_test( int verbose )
1691{
1692 int ret, i, j;
1693 x509_cert cacert;
1694 x509_cert clicert;
1695 rsa_context rsa;
1696
1697 if( verbose != 0 )
1698 printf( " X.509 certificate load: " );
1699
1700 memset( &clicert, 0, sizeof( x509_cert ) );
1701
1702 ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
1703 strlen( test_cli_crt ) );
1704 if( ret != 0 )
1705 {
1706 if( verbose != 0 )
1707 printf( "failed\n" );
1708
1709 return( ret );
1710 }
1711
1712 memset( &cacert, 0, sizeof( x509_cert ) );
1713
1714 ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
1715 strlen( test_ca_crt ) );
1716 if( ret != 0 )
1717 {
1718 if( verbose != 0 )
1719 printf( "failed\n" );
1720
1721 return( ret );
1722 }
1723
1724 if( verbose != 0 )
1725 printf( "passed\n X.509 private key load: " );
1726
1727 i = strlen( test_ca_key );
1728 j = strlen( test_ca_pwd );
1729
1730 if( ( ret = x509parse_key( &rsa,
1731 (unsigned char *) test_ca_key, i,
1732 (unsigned char *) test_ca_pwd, j ) ) != 0 )
1733 {
1734 if( verbose != 0 )
1735 printf( "failed\n" );
1736
1737 return( ret );
1738 }
1739
1740 if( verbose != 0 )
1741 printf( "passed\n X.509 signature verify: ");
1742
1743 ret = x509parse_verify( &clicert, &cacert, "Joe User", &i );
1744 if( ret != 0 )
1745 {
1746 if( verbose != 0 )
1747 printf( "failed\n" );
1748
1749 return( ret );
1750 }
1751
1752 if( verbose != 0 )
1753 printf( "passed\n\n" );
1754
1755 x509_free( &cacert );
1756 x509_free( &clicert );
1757 rsa_free( &rsa );
1758
1759 return( 0 );
1760}
1761
1762#endif
1763
1764#endif