blob: 8029bc5b4030669646e391a8e2a9d8c39064cad2 [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 Bakker27db1f52009-01-25 15:27:00 +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 ||
798 crt->sig_oid1.p[8] > 5 )
799 {
800 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000801 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000802 }
803
804 /*
805 * issuer Name
806 */
807 crt->issuer_raw.p = p;
808
809 if( ( ret = asn1_get_tag( &p, end, &len,
810 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
811 {
812 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000813 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000814 }
815
816 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
817 {
818 x509_free( crt );
819 return( ret );
820 }
821
822 crt->issuer_raw.len = p - crt->issuer_raw.p;
823
824 /*
825 * Validity ::= SEQUENCE {
826 * notBefore Time,
827 * notAfter Time }
828 *
829 */
830 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
831 &crt->valid_to ) ) != 0 )
832 {
833 x509_free( crt );
834 return( ret );
835 }
836
837 /*
838 * subject Name
839 */
840 crt->subject_raw.p = p;
841
842 if( ( ret = asn1_get_tag( &p, end, &len,
843 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
844 {
845 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000846 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000847 }
848
849 if( ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
850 {
851 x509_free( crt );
852 return( ret );
853 }
854
855 crt->subject_raw.len = p - crt->subject_raw.p;
856
857 /*
858 * SubjectPublicKeyInfo ::= SEQUENCE
859 * algorithm AlgorithmIdentifier,
860 * subjectPublicKey BIT STRING }
861 */
862 if( ( ret = asn1_get_tag( &p, end, &len,
863 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
864 {
865 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000866 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000867 }
868
869 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
870 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
871 {
872 x509_free( crt );
873 return( ret );
874 }
875
876 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
877 {
878 x509_free( crt );
879 return( ret );
880 }
881
882 crt->rsa.len = mpi_size( &crt->rsa.N );
883
884 /*
885 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
886 * -- If present, version shall be v2 or v3
887 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
888 * -- If present, version shall be v2 or v3
889 * extensions [3] EXPLICIT Extensions OPTIONAL
890 * -- If present, version shall be v3
891 */
892 if( crt->version == 2 || crt->version == 3 )
893 {
894 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
895 if( ret != 0 )
896 {
897 x509_free( crt );
898 return( ret );
899 }
900 }
901
902 if( crt->version == 2 || crt->version == 3 )
903 {
904 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
905 if( ret != 0 )
906 {
907 x509_free( crt );
908 return( ret );
909 }
910 }
911
912 if( crt->version == 3 )
913 {
914 ret = x509_get_ext( &p, end, &crt->v3_ext,
915 &crt->ca_istrue, &crt->max_pathlen );
916 if( ret != 0 )
917 {
918 x509_free( crt );
919 return( ret );
920 }
921 }
922
923 if( p != end )
924 {
925 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000926 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
927 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000928 }
929
930 end = crt->raw.p + crt->raw.len;
931
932 /*
933 * signatureAlgorithm AlgorithmIdentifier,
934 * signatureValue BIT STRING
935 */
936 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
937 {
938 x509_free( crt );
939 return( ret );
940 }
941
942 if( memcmp( crt->sig_oid1.p, crt->sig_oid2.p, 9 ) != 0 )
943 {
944 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000945 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000946 }
947
948 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
949 {
950 x509_free( crt );
951 return( ret );
952 }
953
954 if( p != end )
955 {
956 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000957 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
958 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000959 }
960
961 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
962
963 if( crt->next == NULL )
964 {
965 x509_free( crt );
966 return( 1 );
967 }
968
969 crt = crt->next;
970 memset( crt, 0, sizeof( x509_cert ) );
971
972 if( buflen > 0 )
973 return( x509parse_crt( crt, buf, buflen ) );
974
975 return( 0 );
976}
977
978/*
979 * Load one or more certificates and add them to the chained list
980 */
981int x509parse_crtfile( x509_cert *chain, char *path )
982{
983 int ret;
984 FILE *f;
985 size_t n;
986 unsigned char *buf;
987
988 if( ( f = fopen( path, "rb" ) ) == NULL )
989 return( 1 );
990
991 fseek( f, 0, SEEK_END );
992 n = (size_t) ftell( f );
993 fseek( f, 0, SEEK_SET );
994
995 if( ( buf = (unsigned char *) malloc( n + 1 ) ) == NULL )
996 return( 1 );
997
998 if( fread( buf, 1, n, f ) != n )
999 {
1000 fclose( f );
1001 free( buf );
1002 return( 1 );
1003 }
1004
1005 buf[n] = '\0';
1006
1007 ret = x509parse_crt( chain, buf, (int) n );
1008
1009 memset( buf, 0, n + 1 );
1010 free( buf );
1011 fclose( f );
1012
1013 return( ret );
1014}
1015
Paul Bakker40e46942009-01-03 21:51:57 +00001016#if defined(POLARSSL_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001017/*
1018 * Read a 16-byte hex string and convert it to binary
1019 */
1020static int x509_get_iv( unsigned char *s, unsigned char iv[8] )
1021{
1022 int i, j, k;
1023
1024 memset( iv, 0, 8 );
1025
1026 for( i = 0; i < 16; i++, s++ )
1027 {
1028 if( *s >= '0' && *s <= '9' ) j = *s - '0'; else
1029 if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else
1030 if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else
Paul Bakker40e46942009-01-03 21:51:57 +00001031 return( POLARSSL_ERR_X509_KEY_INVALID_ENC_IV );
Paul Bakker5121ce52009-01-03 21:22:43 +00001032
1033 k = ( ( i & 1 ) != 0 ) ? j : j << 4;
1034
1035 iv[i >> 1] = (unsigned char)( iv[i >> 1] | k );
1036 }
1037
1038 return( 0 );
1039}
1040
1041/*
1042 * Decrypt with 3DES-CBC, using PBKDF1 for key derivation
1043 */
1044static void x509_des3_decrypt( unsigned char des3_iv[8],
1045 unsigned char *buf, int buflen,
1046 unsigned char *pwd, int pwdlen )
1047{
1048 md5_context md5_ctx;
1049 des3_context des3_ctx;
1050 unsigned char md5sum[16];
1051 unsigned char des3_key[24];
1052
1053 /*
1054 * 3DES key[ 0..15] = MD5(pwd || IV)
1055 * key[16..23] = MD5(pwd || IV || 3DES key[ 0..15])
1056 */
1057 md5_starts( &md5_ctx );
1058 md5_update( &md5_ctx, pwd, pwdlen );
1059 md5_update( &md5_ctx, des3_iv, 8 );
1060 md5_finish( &md5_ctx, md5sum );
1061 memcpy( des3_key, md5sum, 16 );
1062
1063 md5_starts( &md5_ctx );
1064 md5_update( &md5_ctx, md5sum, 16 );
1065 md5_update( &md5_ctx, pwd, pwdlen );
1066 md5_update( &md5_ctx, des3_iv, 8 );
1067 md5_finish( &md5_ctx, md5sum );
1068 memcpy( des3_key + 16, md5sum, 8 );
1069
1070 des3_set3key_dec( &des3_ctx, des3_key );
1071 des3_crypt_cbc( &des3_ctx, DES_DECRYPT, buflen,
1072 des3_iv, buf, buf );
1073
1074 memset( &md5_ctx, 0, sizeof( md5_ctx ) );
1075 memset( &des3_ctx, 0, sizeof( des3_ctx ) );
1076 memset( md5sum, 0, 16 );
1077 memset( des3_key, 0, 24 );
1078}
1079#endif
1080
1081/*
1082 * Parse a private RSA key
1083 */
1084int x509parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
1085 unsigned char *pwd, int pwdlen )
1086{
1087 int ret, len, enc;
1088 unsigned char *s1, *s2;
1089 unsigned char *p, *end;
1090 unsigned char des3_iv[8];
1091
1092 s1 = (unsigned char *) strstr( (char *) buf,
1093 "-----BEGIN RSA PRIVATE KEY-----" );
1094
1095 if( s1 != NULL )
1096 {
1097 s2 = (unsigned char *) strstr( (char *) buf,
1098 "-----END RSA PRIVATE KEY-----" );
1099
1100 if( s2 == NULL || s2 <= s1 )
Paul Bakker40e46942009-01-03 21:51:57 +00001101 return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001102
1103 s1 += 31;
1104 if( *s1 == '\r' ) s1++;
1105 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001106 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001107
1108 enc = 0;
1109
1110 if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
1111 {
Paul Bakker40e46942009-01-03 21:51:57 +00001112#if defined(POLARSSL_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001113 enc++;
1114
1115 s1 += 22;
1116 if( *s1 == '\r' ) s1++;
1117 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001118 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001119
1120 if( memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001121 return( POLARSSL_ERR_X509_KEY_UNKNOWN_ENC_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +00001122
1123 s1 += 23;
1124 if( x509_get_iv( s1, des3_iv ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001125 return( POLARSSL_ERR_X509_KEY_INVALID_ENC_IV );
Paul Bakker5121ce52009-01-03 21:22:43 +00001126
1127 s1 += 16;
1128 if( *s1 == '\r' ) s1++;
1129 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001130 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001131#else
Paul Bakker40e46942009-01-03 21:51:57 +00001132 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001133#endif
1134 }
1135
1136 len = 0;
1137 ret = base64_decode( NULL, &len, s1, s2 - s1 );
1138
Paul Bakker40e46942009-01-03 21:51:57 +00001139 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
1140 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001141
1142 if( ( buf = (unsigned char *) malloc( len ) ) == NULL )
1143 return( 1 );
1144
1145 if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
1146 {
1147 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001148 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001149 }
1150
1151 buflen = len;
1152
1153 if( enc != 0 )
1154 {
Paul Bakker40e46942009-01-03 21:51:57 +00001155#if defined(POLARSSL_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001156 if( pwd == NULL )
1157 {
1158 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001159 return( POLARSSL_ERR_X509_KEY_PASSWORD_REQUIRED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001160 }
1161
1162 x509_des3_decrypt( des3_iv, buf, buflen, pwd, pwdlen );
1163
1164 if( buf[0] != 0x30 || buf[1] != 0x82 ||
1165 buf[4] != 0x02 || buf[5] != 0x01 )
1166 {
1167 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001168 return( POLARSSL_ERR_X509_KEY_PASSWORD_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001169 }
1170#else
Paul Bakker40e46942009-01-03 21:51:57 +00001171 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001172#endif
1173 }
1174 }
1175
1176 memset( rsa, 0, sizeof( rsa_context ) );
1177
1178 p = buf;
1179 end = buf + buflen;
1180
1181 /*
1182 * RSAPrivateKey ::= SEQUENCE {
1183 * version Version,
1184 * modulus INTEGER, -- n
1185 * publicExponent INTEGER, -- e
1186 * privateExponent INTEGER, -- d
1187 * prime1 INTEGER, -- p
1188 * prime2 INTEGER, -- q
1189 * exponent1 INTEGER, -- d mod (p-1)
1190 * exponent2 INTEGER, -- d mod (q-1)
1191 * coefficient INTEGER, -- (inverse of q) mod p
1192 * otherPrimeInfos OtherPrimeInfos OPTIONAL
1193 * }
1194 */
1195 if( ( ret = asn1_get_tag( &p, end, &len,
1196 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1197 {
1198 if( s1 != NULL )
1199 free( buf );
1200
1201 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001202 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001203 }
1204
1205 end = p + len;
1206
1207 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
1208 {
1209 if( s1 != NULL )
1210 free( buf );
1211
1212 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001213 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001214 }
1215
1216 if( rsa->ver != 0 )
1217 {
1218 if( s1 != NULL )
1219 free( buf );
1220
1221 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001222 return( ret | POLARSSL_ERR_X509_KEY_INVALID_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001223 }
1224
1225 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
1226 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
1227 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
1228 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
1229 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
1230 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
1231 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
1232 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
1233 {
1234 if( s1 != NULL )
1235 free( buf );
1236
1237 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001238 return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001239 }
1240
1241 rsa->len = mpi_size( &rsa->N );
1242
1243 if( p != end )
1244 {
1245 if( s1 != NULL )
1246 free( buf );
1247
1248 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001249 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT |
1250 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001251 }
1252
1253 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
1254 {
1255 if( s1 != NULL )
1256 free( buf );
1257
1258 rsa_free( rsa );
1259 return( ret );
1260 }
1261
1262 if( s1 != NULL )
1263 free( buf );
1264
1265 return( 0 );
1266}
1267
1268/*
1269 * Load and parse a private RSA key
1270 */
1271int x509parse_keyfile( rsa_context *rsa, char *path, char *pwd )
1272{
1273 int ret;
1274 FILE *f;
1275 size_t n;
1276 unsigned char *buf;
1277
1278 if( ( f = fopen( path, "rb" ) ) == NULL )
1279 return( 1 );
1280
1281 fseek( f, 0, SEEK_END );
1282 n = (size_t) ftell( f );
1283 fseek( f, 0, SEEK_SET );
1284
1285 if( ( buf = (unsigned char *) malloc( n + 1 ) ) == NULL )
1286 return( 1 );
1287
1288 if( fread( buf, 1, n, f ) != n )
1289 {
1290 fclose( f );
1291 free( buf );
1292 return( 1 );
1293 }
1294
1295 buf[n] = '\0';
1296
1297 if( pwd == NULL )
1298 ret = x509parse_key( rsa, buf, (int) n, NULL, 0 );
1299 else
1300 ret = x509parse_key( rsa, buf, (int) n,
1301 (unsigned char *) pwd, strlen( pwd ) );
1302
1303 memset( buf, 0, n + 1 );
1304 free( buf );
1305 fclose( f );
1306
1307 return( ret );
1308}
1309
1310#if defined _MSC_VER && !defined snprintf
1311#define snprintf _snprintf
1312#endif
1313
1314/*
1315 * Store the name in printable form into buf; no more
1316 * than (end - buf) characters will be written
1317 */
1318int x509parse_dn_gets( char *buf, char *end, x509_name *dn )
1319{
1320 int i;
1321 unsigned char c;
1322 x509_name *name;
1323 char s[128], *p;
1324
1325 memset( s, 0, sizeof( s ) );
1326
1327 name = dn;
1328 p = buf;
1329
1330 while( name != NULL )
1331 {
1332 if( name != dn )
1333 p += snprintf( p, end - p, ", " );
1334
1335 if( memcmp( name->oid.p, OID_X520, 2 ) == 0 )
1336 {
1337 switch( name->oid.p[2] )
1338 {
1339 case X520_COMMON_NAME:
1340 p += snprintf( p, end - p, "CN=" ); break;
1341
1342 case X520_COUNTRY:
1343 p += snprintf( p, end - p, "C=" ); break;
1344
1345 case X520_LOCALITY:
1346 p += snprintf( p, end - p, "L=" ); break;
1347
1348 case X520_STATE:
1349 p += snprintf( p, end - p, "ST=" ); break;
1350
1351 case X520_ORGANIZATION:
1352 p += snprintf( p, end - p, "O=" ); break;
1353
1354 case X520_ORG_UNIT:
1355 p += snprintf( p, end - p, "OU=" ); break;
1356
1357 default:
1358 p += snprintf( p, end - p, "0x%02X=",
1359 name->oid.p[2] );
1360 break;
1361 }
1362 }
1363 else if( memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
1364 {
1365 switch( name->oid.p[8] )
1366 {
1367 case PKCS9_EMAIL:
1368 p += snprintf( p, end - p, "emailAddress=" ); break;
1369
1370 default:
1371 p += snprintf( p, end - p, "0x%02X=",
1372 name->oid.p[8] );
1373 break;
1374 }
1375 }
1376 else
1377 p += snprintf( p, end - p, "\?\?=" );
1378
1379 for( i = 0; i < name->val.len; i++ )
1380 {
1381 if( i >= (int) sizeof( s ) - 1 )
1382 break;
1383
1384 c = name->val.p[i];
1385 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
1386 s[i] = '?';
1387 else s[i] = c;
1388 }
1389 s[i] = '\0';
1390 p += snprintf( p, end - p, "%s", s );
1391 name = name->next;
1392 }
1393
1394 return( p - buf );
1395}
1396
1397/*
1398 * Return an informational string about the
1399 * certificate, or NULL if memory allocation failed
1400 */
1401char *x509parse_cert_info( char *prefix, x509_cert *crt )
1402{
1403 int i, n;
1404 char *p, *end;
1405 static char buf[512];
1406
1407 p = buf;
1408 end = buf + sizeof( buf ) - 1;
1409
1410 p += snprintf( p, end - p, "%scert. version : %d\n",
1411 prefix, crt->version );
1412 p += snprintf( p, end - p, "%sserial number : ",
1413 prefix );
1414
1415 n = ( crt->serial.len <= 32 )
1416 ? crt->serial.len : 32;
1417
1418 for( i = 0; i < n; i++ )
1419 p += snprintf( p, end - p, "%02X%s",
1420 crt->serial.p[i], ( i < n - 1 ) ? ":" : "" );
1421
1422 p += snprintf( p, end - p, "\n%sissuer name : ", prefix );
1423 p += x509parse_dn_gets( p, end, &crt->issuer );
1424
1425 p += snprintf( p, end - p, "\n%ssubject name : ", prefix );
1426 p += x509parse_dn_gets( p, end, &crt->subject );
1427
1428 p += snprintf( p, end - p, "\n%sissued on : " \
1429 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1430 crt->valid_from.year, crt->valid_from.mon,
1431 crt->valid_from.day, crt->valid_from.hour,
1432 crt->valid_from.min, crt->valid_from.sec );
1433
1434 p += snprintf( p, end - p, "\n%sexpires on : " \
1435 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1436 crt->valid_to.year, crt->valid_to.mon,
1437 crt->valid_to.day, crt->valid_to.hour,
1438 crt->valid_to.min, crt->valid_to.sec );
1439
1440 p += snprintf( p, end - p, "\n%ssigned using : RSA+", prefix );
1441
1442 switch( crt->sig_oid1.p[8] )
1443 {
1444 case RSA_MD2 : p += snprintf( p, end - p, "MD2" ); break;
1445 case RSA_MD4 : p += snprintf( p, end - p, "MD4" ); break;
1446 case RSA_MD5 : p += snprintf( p, end - p, "MD5" ); break;
1447 case RSA_SHA1: p += snprintf( p, end - p, "SHA1" ); break;
1448 default: p += snprintf( p, end - p, "???" ); break;
1449 }
1450
1451 p += snprintf( p, end - p, "\n%sRSA key size : %d bits\n", prefix,
1452 crt->rsa.N.n * (int) sizeof( unsigned long ) * 8 );
1453
1454 return( buf );
1455}
1456
1457/*
1458 * Return 0 if the certificate is still valid, or BADCERT_EXPIRED
1459 */
1460int x509parse_expired( x509_cert *crt )
1461{
1462 struct tm *lt;
1463 time_t tt;
1464
1465 tt = time( NULL );
1466 lt = localtime( &tt );
1467
1468 if( lt->tm_year > crt->valid_to.year - 1900 )
1469 return( BADCERT_EXPIRED );
1470
1471 if( lt->tm_year == crt->valid_to.year - 1900 &&
1472 lt->tm_mon > crt->valid_to.mon - 1 )
1473 return( BADCERT_EXPIRED );
1474
1475 if( lt->tm_year == crt->valid_to.year - 1900 &&
1476 lt->tm_mon == crt->valid_to.mon - 1 &&
1477 lt->tm_mday > crt->valid_to.day )
1478 return( BADCERT_EXPIRED );
1479
1480 return( 0 );
1481}
1482
1483static void x509_hash( unsigned char *in, int len, int alg,
1484 unsigned char *out )
1485{
1486 switch( alg )
1487 {
Paul Bakker40e46942009-01-03 21:51:57 +00001488#if defined(POLARSSL_MD2_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001489 case RSA_MD2 : md2( in, len, out ); break;
1490#endif
Paul Bakker40e46942009-01-03 21:51:57 +00001491#if defined(POLARSSL_MD4_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001492 case RSA_MD4 : md4( in, len, out ); break;
1493#endif
1494 case RSA_MD5 : md5( in, len, out ); break;
1495 case RSA_SHA1 : sha1( in, len, out ); break;
1496 default:
1497 memset( out, '\xFF', len );
1498 break;
1499 }
1500}
1501
1502/*
1503 * Verify the certificate validity
1504 */
1505int x509parse_verify( x509_cert *crt,
1506 x509_cert *trust_ca,
1507 char *cn, int *flags )
1508{
1509 int cn_len;
1510 int hash_id;
1511 int pathlen;
1512 x509_cert *cur;
1513 x509_name *name;
1514 unsigned char hash[20];
1515
1516 *flags = x509parse_expired( crt );
1517
1518 if( cn != NULL )
1519 {
1520 name = &crt->subject;
1521 cn_len = strlen( cn );
1522
1523 while( name != NULL )
1524 {
1525 if( memcmp( name->oid.p, OID_CN, 3 ) == 0 &&
1526 memcmp( name->val.p, cn, cn_len ) == 0 &&
1527 name->val.len == cn_len )
1528 break;
1529
1530 name = name->next;
1531 }
1532
1533 if( name == NULL )
1534 *flags |= BADCERT_CN_MISMATCH;
1535 }
1536
1537 *flags |= BADCERT_NOT_TRUSTED;
1538
1539 /*
1540 * Iterate upwards in the given cert chain,
1541 * ignoring any upper cert with CA != TRUE.
1542 */
1543 cur = crt->next;
1544
1545 pathlen = 1;
1546
1547 while( cur->version != 0 )
1548 {
1549 if( cur->ca_istrue == 0 ||
1550 crt->issuer_raw.len != cur->subject_raw.len ||
1551 memcmp( crt->issuer_raw.p, cur->subject_raw.p,
1552 crt->issuer_raw.len ) != 0 )
1553 {
1554 cur = cur->next;
1555 continue;
1556 }
1557
1558 hash_id = crt->sig_oid1.p[8];
1559
1560 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
1561
1562 if( rsa_pkcs1_verify( &cur->rsa, RSA_PUBLIC, hash_id,
1563 0, hash, crt->sig.p ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001564 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001565
1566 pathlen++;
1567
1568 crt = cur;
1569 cur = crt->next;
1570 }
1571
1572 /*
1573 * Atempt to validate topmost cert with our CA chain.
1574 */
1575 while( trust_ca->version != 0 )
1576 {
1577 if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
1578 memcmp( crt->issuer_raw.p, trust_ca->subject_raw.p,
1579 crt->issuer_raw.len ) != 0 )
1580 {
1581 trust_ca = trust_ca->next;
1582 continue;
1583 }
1584
1585 if( trust_ca->max_pathlen > 0 &&
1586 trust_ca->max_pathlen < pathlen )
1587 break;
1588
1589 hash_id = crt->sig_oid1.p[8];
1590
1591 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
1592
1593 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
1594 0, hash, crt->sig.p ) == 0 )
1595 {
1596 /*
1597 * cert. is signed by a trusted CA
1598 */
1599 *flags &= ~BADCERT_NOT_TRUSTED;
1600 break;
1601 }
1602
1603 trust_ca = trust_ca->next;
1604 }
1605
1606 if( *flags != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001607 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001608
1609 return( 0 );
1610}
1611
1612/*
1613 * Unallocate all certificate data
1614 */
1615void x509_free( x509_cert *crt )
1616{
1617 x509_cert *cert_cur = crt;
1618 x509_cert *cert_prv;
1619 x509_name *name_cur;
1620 x509_name *name_prv;
1621
1622 if( crt == NULL )
1623 return;
1624
1625 do
1626 {
1627 rsa_free( &cert_cur->rsa );
1628
1629 name_cur = cert_cur->issuer.next;
1630 while( name_cur != NULL )
1631 {
1632 name_prv = name_cur;
1633 name_cur = name_cur->next;
1634 memset( name_prv, 0, sizeof( x509_name ) );
1635 free( name_prv );
1636 }
1637
1638 name_cur = cert_cur->subject.next;
1639 while( name_cur != NULL )
1640 {
1641 name_prv = name_cur;
1642 name_cur = name_cur->next;
1643 memset( name_prv, 0, sizeof( x509_name ) );
1644 free( name_prv );
1645 }
1646
1647 if( cert_cur->raw.p != NULL )
1648 {
1649 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
1650 free( cert_cur->raw.p );
1651 }
1652
1653 cert_cur = cert_cur->next;
1654 }
1655 while( cert_cur != NULL );
1656
1657 cert_cur = crt;
1658 do
1659 {
1660 cert_prv = cert_cur;
1661 cert_cur = cert_cur->next;
1662
1663 memset( cert_prv, 0, sizeof( x509_cert ) );
1664 if( cert_prv != crt )
1665 free( cert_prv );
1666 }
1667 while( cert_cur != NULL );
1668}
1669
Paul Bakker40e46942009-01-03 21:51:57 +00001670#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001671
Paul Bakker40e46942009-01-03 21:51:57 +00001672#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00001673
1674/*
1675 * Checkup routine
1676 */
1677int x509_self_test( int verbose )
1678{
1679 int ret, i, j;
1680 x509_cert cacert;
1681 x509_cert clicert;
1682 rsa_context rsa;
1683
1684 if( verbose != 0 )
1685 printf( " X.509 certificate load: " );
1686
1687 memset( &clicert, 0, sizeof( x509_cert ) );
1688
1689 ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
1690 strlen( test_cli_crt ) );
1691 if( ret != 0 )
1692 {
1693 if( verbose != 0 )
1694 printf( "failed\n" );
1695
1696 return( ret );
1697 }
1698
1699 memset( &cacert, 0, sizeof( x509_cert ) );
1700
1701 ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
1702 strlen( test_ca_crt ) );
1703 if( ret != 0 )
1704 {
1705 if( verbose != 0 )
1706 printf( "failed\n" );
1707
1708 return( ret );
1709 }
1710
1711 if( verbose != 0 )
1712 printf( "passed\n X.509 private key load: " );
1713
1714 i = strlen( test_ca_key );
1715 j = strlen( test_ca_pwd );
1716
1717 if( ( ret = x509parse_key( &rsa,
1718 (unsigned char *) test_ca_key, i,
1719 (unsigned char *) test_ca_pwd, j ) ) != 0 )
1720 {
1721 if( verbose != 0 )
1722 printf( "failed\n" );
1723
1724 return( ret );
1725 }
1726
1727 if( verbose != 0 )
1728 printf( "passed\n X.509 signature verify: ");
1729
1730 ret = x509parse_verify( &clicert, &cacert, "Joe User", &i );
1731 if( ret != 0 )
1732 {
1733 if( verbose != 0 )
1734 printf( "failed\n" );
1735
1736 return( ret );
1737 }
1738
1739 if( verbose != 0 )
1740 printf( "passed\n\n" );
1741
1742 x509_free( &cacert );
1743 x509_free( &clicert );
1744 rsa_free( &rsa );
1745
1746 return( 0 );
1747}
1748
1749#endif
1750
1751#endif