blob: 97a1755e31e9f61b3f5c354a64a44dc237da7fa9 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * X.509 certificate and private key decoding
3 *
Paul Bakker77b385e2009-07-28 17:23:11 +00004 * Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org>
5 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +00006 *
Paul Bakker77b385e2009-07-28 17:23:11 +00007 * Joined copyright on original XySSL code with: Christophe Devine
Paul Bakker5121ce52009-01-03 21:22:43 +00008 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
23/*
24 * The ITU-T X.509 standard defines a certificat format for PKI.
25 *
26 * http://www.ietf.org/rfc/rfc2459.txt
27 * http://www.ietf.org/rfc/rfc3279.txt
28 *
29 * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
30 *
31 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
32 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
33 */
34
Paul Bakker40e46942009-01-03 21:51:57 +000035#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000036
Paul Bakker40e46942009-01-03 21:51:57 +000037#if defined(POLARSSL_X509_PARSE_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000038
Paul Bakker40e46942009-01-03 21:51:57 +000039#include "polarssl/x509.h"
40#include "polarssl/base64.h"
41#include "polarssl/des.h"
42#include "polarssl/md2.h"
43#include "polarssl/md4.h"
44#include "polarssl/md5.h"
45#include "polarssl/sha1.h"
Paul Bakker026c03b2009-03-28 17:53:03 +000046#include "polarssl/sha2.h"
47#include "polarssl/sha4.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000048
49#include <string.h>
50#include <stdlib.h>
51#include <stdio.h>
52#include <time.h>
53
54/*
55 * ASN.1 DER decoding routines
56 */
57static int asn1_get_len( unsigned char **p,
58 unsigned char *end,
59 int *len )
60{
61 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +000062 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000063
64 if( ( **p & 0x80 ) == 0 )
65 *len = *(*p)++;
66 else
67 {
68 switch( **p & 0x7F )
69 {
70 case 1:
71 if( ( end - *p ) < 2 )
Paul Bakker40e46942009-01-03 21:51:57 +000072 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000073
74 *len = (*p)[1];
75 (*p) += 2;
76 break;
77
78 case 2:
79 if( ( end - *p ) < 3 )
Paul Bakker40e46942009-01-03 21:51:57 +000080 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000081
82 *len = ( (*p)[1] << 8 ) | (*p)[2];
83 (*p) += 3;
84 break;
85
86 default:
Paul Bakker40e46942009-01-03 21:51:57 +000087 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +000088 break;
89 }
90 }
91
92 if( *len > (int) ( end - *p ) )
Paul Bakker40e46942009-01-03 21:51:57 +000093 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000094
95 return( 0 );
96}
97
98static int asn1_get_tag( unsigned char **p,
99 unsigned char *end,
100 int *len, int tag )
101{
102 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000103 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000104
105 if( **p != tag )
Paul Bakker40e46942009-01-03 21:51:57 +0000106 return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000107
108 (*p)++;
109
110 return( asn1_get_len( p, end, len ) );
111}
112
113static int asn1_get_bool( unsigned char **p,
114 unsigned char *end,
115 int *val )
116{
117 int ret, len;
118
119 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 )
120 return( ret );
121
122 if( len != 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000123 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000124
125 *val = ( **p != 0 ) ? 1 : 0;
126 (*p)++;
127
128 return( 0 );
129}
130
131static int asn1_get_int( unsigned char **p,
132 unsigned char *end,
133 int *val )
134{
135 int ret, len;
136
137 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
138 return( ret );
139
140 if( len > (int) sizeof( int ) || ( **p & 0x80 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000141 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000142
143 *val = 0;
144
145 while( len-- > 0 )
146 {
147 *val = ( *val << 8 ) | **p;
148 (*p)++;
149 }
150
151 return( 0 );
152}
153
154static int asn1_get_mpi( unsigned char **p,
155 unsigned char *end,
156 mpi *X )
157{
158 int ret, len;
159
160 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
161 return( ret );
162
163 ret = mpi_read_binary( X, *p, len );
164
165 *p += len;
166
167 return( ret );
168}
169
170/*
171 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
172 */
173static int x509_get_version( unsigned char **p,
174 unsigned char *end,
175 int *ver )
176{
177 int ret, len;
178
179 if( ( ret = asn1_get_tag( p, end, &len,
180 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
181 {
Paul Bakker40e46942009-01-03 21:51:57 +0000182 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000183 return( *ver = 0 );
184
185 return( ret );
186 }
187
188 end = *p + len;
189
190 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000191 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000192
193 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000194 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION |
195 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000196
197 return( 0 );
198}
199
200/*
201 * CertificateSerialNumber ::= INTEGER
202 */
203static int x509_get_serial( unsigned char **p,
204 unsigned char *end,
205 x509_buf *serial )
206{
207 int ret;
208
209 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000210 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL |
211 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000212
213 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
214 **p != ASN1_INTEGER )
Paul Bakker40e46942009-01-03 21:51:57 +0000215 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL |
216 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000217
218 serial->tag = *(*p)++;
219
220 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000221 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000222
223 serial->p = *p;
224 *p += serial->len;
225
226 return( 0 );
227}
228
229/*
230 * AlgorithmIdentifier ::= SEQUENCE {
231 * algorithm OBJECT IDENTIFIER,
232 * parameters ANY DEFINED BY algorithm OPTIONAL }
233 */
234static int x509_get_alg( unsigned char **p,
235 unsigned char *end,
236 x509_buf *alg )
237{
238 int ret, len;
239
240 if( ( ret = asn1_get_tag( p, end, &len,
241 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000242 return( POLARSSL_ERR_X509_CERT_INVALID_ALG | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000243
244 end = *p + len;
245 alg->tag = **p;
246
247 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000248 return( POLARSSL_ERR_X509_CERT_INVALID_ALG | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000249
250 alg->p = *p;
251 *p += alg->len;
252
253 if( *p == end )
254 return( 0 );
255
256 /*
257 * assume the algorithm parameters must be NULL
258 */
259 if( ( ret = asn1_get_tag( p, end, &len, ASN1_NULL ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000260 return( POLARSSL_ERR_X509_CERT_INVALID_ALG | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000261
262 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000263 return( POLARSSL_ERR_X509_CERT_INVALID_ALG |
264 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000265
266 return( 0 );
267}
268
269/*
270 * RelativeDistinguishedName ::=
271 * SET OF AttributeTypeAndValue
272 *
273 * AttributeTypeAndValue ::= SEQUENCE {
274 * type AttributeType,
275 * value AttributeValue }
276 *
277 * AttributeType ::= OBJECT IDENTIFIER
278 *
279 * AttributeValue ::= ANY DEFINED BY AttributeType
280 */
281static int x509_get_name( unsigned char **p,
282 unsigned char *end,
283 x509_name *cur )
284{
285 int ret, len;
286 unsigned char *end2;
287 x509_buf *oid;
288 x509_buf *val;
289
290 if( ( ret = asn1_get_tag( p, end, &len,
291 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000292 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000293
294 end2 = end;
295 end = *p + len;
296
297 if( ( ret = asn1_get_tag( p, end, &len,
298 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000299 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000300
301 if( *p + len != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000302 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
303 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000304
305 oid = &cur->oid;
306 oid->tag = **p;
307
308 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000309 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000310
311 oid->p = *p;
312 *p += oid->len;
313
314 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000315 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
316 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000317
318 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
319 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
320 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker40e46942009-01-03 21:51:57 +0000321 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
322 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000323
324 val = &cur->val;
325 val->tag = *(*p)++;
326
327 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000328 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000329
330 val->p = *p;
331 *p += val->len;
332
333 cur->next = NULL;
334
335 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000336 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
337 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000338
339 /*
340 * recurse until end of SEQUENCE is reached
341 */
342 if( *p == end2 )
343 return( 0 );
344
345 cur->next = (x509_name *) malloc(
346 sizeof( x509_name ) );
347
348 if( cur->next == NULL )
349 return( 1 );
350
351 return( x509_get_name( p, end2, cur->next ) );
352}
353
354/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000355 * Time ::= CHOICE {
356 * utcTime UTCTime,
357 * generalTime GeneralizedTime }
358 */
Paul Bakkerd98030e2009-05-02 15:13:40 +0000359static int x509_get_UTCTime( unsigned char **p,
360 unsigned char *end,
361 x509_time *time )
362{
363 int ret, len;
364 char date[64];
365
366 if( ( ret = asn1_get_tag( p, end, &len, ASN1_UTC_TIME ) ) != 0 )
367 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret );
368
369 memset( date, 0, sizeof( date ) );
370 memcpy( date, *p, ( len < (int) sizeof( date ) - 1 ) ?
371 len : (int) sizeof( date ) - 1 );
372
373 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
374 &time->year, &time->mon, &time->day,
375 &time->hour, &time->min, &time->sec ) < 5 )
376 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
377
378 time->year += 100 * ( time->year < 90 );
379 time->year += 1900;
380
381 *p += len;
382
383 return( 0 );
384}
385
386
387/*
388 * Validity ::= SEQUENCE {
389 * notBefore Time,
390 * notAfter Time }
391 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000392static int x509_get_dates( unsigned char **p,
393 unsigned char *end,
394 x509_time *from,
395 x509_time *to )
396{
397 int ret, len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000398
399 if( ( ret = asn1_get_tag( p, end, &len,
400 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000401 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000402
403 end = *p + len;
404
405 /*
406 * TODO: also handle GeneralizedTime
407 */
Paul Bakkerd98030e2009-05-02 15:13:40 +0000408 if( ( ret = x509_get_UTCTime( p, end, from ) ) != 0 )
409 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000410
Paul Bakkerd98030e2009-05-02 15:13:40 +0000411 if( ( ret = x509_get_UTCTime( p, end, to ) ) != 0 )
412 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000413
414 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000415 return( POLARSSL_ERR_X509_CERT_INVALID_DATE |
416 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000417
418 return( 0 );
419}
420
421/*
422 * SubjectPublicKeyInfo ::= SEQUENCE {
423 * algorithm AlgorithmIdentifier,
424 * subjectPublicKey BIT STRING }
425 */
426static int x509_get_pubkey( unsigned char **p,
427 unsigned char *end,
428 x509_buf *pk_alg_oid,
429 mpi *N, mpi *E )
430{
431 int ret, len;
432 unsigned char *end2;
433
434 if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 )
435 return( ret );
436
437 /*
438 * only RSA public keys handled at this time
439 */
440 if( pk_alg_oid->len != 9 ||
441 memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000442 return( POLARSSL_ERR_X509_CERT_UNKNOWN_PK_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000443
444 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000445 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000446
447 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000448 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY |
449 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000450
451 end2 = *p + len;
452
453 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000454 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000455
456 /*
457 * RSAPublicKey ::= SEQUENCE {
458 * modulus INTEGER, -- n
459 * publicExponent INTEGER -- e
460 * }
461 */
462 if( ( ret = asn1_get_tag( p, end2, &len,
463 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000464 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000465
466 if( *p + len != end2 )
Paul Bakker40e46942009-01-03 21:51:57 +0000467 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY |
468 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000469
470 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
471 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000472 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000473
474 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000475 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY |
476 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000477
478 return( 0 );
479}
480
481static int x509_get_sig( unsigned char **p,
482 unsigned char *end,
483 x509_buf *sig )
484{
485 int ret, len;
486
487 sig->tag = **p;
488
489 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000490 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000491
492 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000493 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000494
495 sig->len = len;
496 sig->p = *p;
497
498 *p += len;
499
500 return( 0 );
501}
502
503/*
504 * X.509 v2/v3 unique identifier (not parsed)
505 */
506static int x509_get_uid( unsigned char **p,
507 unsigned char *end,
508 x509_buf *uid, int n )
509{
510 int ret;
511
512 if( *p == end )
513 return( 0 );
514
515 uid->tag = **p;
516
517 if( ( ret = asn1_get_tag( p, end, &uid->len,
518 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
519 {
Paul Bakker40e46942009-01-03 21:51:57 +0000520 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000521 return( 0 );
522
523 return( ret );
524 }
525
526 uid->p = *p;
527 *p += uid->len;
528
529 return( 0 );
530}
531
532/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000533 * X.509 Extensions (No parsing of extensions, pointer should
534 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000535 */
536static int x509_get_ext( unsigned char **p,
537 unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000538 x509_buf *ext )
Paul Bakker5121ce52009-01-03 21:22:43 +0000539{
540 int ret, len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000541
542 if( *p == end )
543 return( 0 );
544
545 ext->tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000546
Paul Bakker5121ce52009-01-03 21:22:43 +0000547 if( ( ret = asn1_get_tag( p, end, &ext->len,
548 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000549 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000550
551 ext->p = *p;
552 end = *p + ext->len;
553
554 /*
555 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
556 *
557 * Extension ::= SEQUENCE {
558 * extnID OBJECT IDENTIFIER,
559 * critical BOOLEAN DEFAULT FALSE,
560 * extnValue OCTET STRING }
561 */
562 if( ( ret = asn1_get_tag( p, end, &len,
563 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000564 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000565
566 if( end != *p + len )
Paul Bakker40e46942009-01-03 21:51:57 +0000567 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
568 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000569
Paul Bakkerd98030e2009-05-02 15:13:40 +0000570 return( 0 );
571}
572
573/*
574 * X.509 CRL v2 extensions (no extensions parsed yet.)
575 */
576static int x509_get_crl_ext( unsigned char **p,
577 unsigned char *end,
578 x509_buf *ext )
579{
580 int ret, len;
581
582 if( ( ret = x509_get_ext( p, end, ext ) ) != 0 )
583 {
584 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
585 return( 0 );
586
587 return( ret );
588 }
589
590 while( *p < end )
591 {
592 if( ( ret = asn1_get_tag( p, end, &len,
593 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
594 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
595
596 *p += len;
597 }
598
599 if( *p != end )
600 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
601 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
602
603 return( 0 );
604}
605
606/*
607 * X.509 v3 extensions (only BasicConstraints are parsed)
608 */
609static int x509_get_crt_ext( unsigned char **p,
610 unsigned char *end,
611 x509_buf *ext,
612 int *ca_istrue,
613 int *max_pathlen )
614{
615 int ret, len;
616 int is_critical = 1;
617 int is_cacert = 0;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000618 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000619
620 if( ( ret = x509_get_ext( p, end, ext ) ) != 0 )
621 {
622 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
623 return( 0 );
624
625 return( ret );
626 }
627
Paul Bakker5121ce52009-01-03 21:22:43 +0000628 while( *p < end )
629 {
630 if( ( ret = asn1_get_tag( p, end, &len,
631 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000632 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000633
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000634 end_ext_data = *p + len;
635
Paul Bakker5121ce52009-01-03 21:22:43 +0000636 if( memcmp( *p, "\x06\x03\x55\x1D\x13", 5 ) != 0 )
637 {
638 *p += len;
639 continue;
640 }
641
642 *p += 5;
643
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000644 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000645 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
646 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000647
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000648 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000649 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000650 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000651
652 /*
653 * BasicConstraints ::= SEQUENCE {
654 * cA BOOLEAN DEFAULT FALSE,
655 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
656 */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000657 end_ext_octet = *p + len;
658
659 if( end_ext_octet != end_ext_data )
660 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
661 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000662
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000663 if( ( ret = asn1_get_tag( p, end_ext_octet, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000664 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000665 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000666
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000667 if( *p == end_ext_octet )
Paul Bakker5121ce52009-01-03 21:22:43 +0000668 continue;
669
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000670 if( ( ret = asn1_get_bool( p, end_ext_octet, &is_cacert ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000671 {
Paul Bakker40e46942009-01-03 21:51:57 +0000672 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000673 ret = asn1_get_int( p, end_ext_octet, &is_cacert );
Paul Bakker5121ce52009-01-03 21:22:43 +0000674
675 if( ret != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000676 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000677
678 if( is_cacert != 0 )
679 is_cacert = 1;
680 }
681
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000682 if( *p == end_ext_octet )
Paul Bakker5121ce52009-01-03 21:22:43 +0000683 continue;
684
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000685 if( ( ret = asn1_get_int( p, end_ext_octet, max_pathlen ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000686 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000687
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000688 if( *p != end_ext_octet )
Paul Bakker40e46942009-01-03 21:51:57 +0000689 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
690 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000691
692 max_pathlen++;
693 }
694
695 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000696 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
697 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000698
699 *ca_istrue = is_critical & is_cacert;
700
701 return( 0 );
702}
703
704/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000705 * X.509 CRL Entries
706 */
707static int x509_get_entries( unsigned char **p,
708 unsigned char *end,
709 x509_crl_entry *entry )
710{
Paul Bakker9be19372009-07-27 20:21:53 +0000711 int ret, entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000712 x509_crl_entry *cur_entry = entry;
713
714 if( *p == end )
715 return( 0 );
716
Paul Bakker9be19372009-07-27 20:21:53 +0000717 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000718 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
719 {
720 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
721 return( 0 );
722
723 return( ret );
724 }
725
Paul Bakker9be19372009-07-27 20:21:53 +0000726 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000727
728 while( *p < end )
729 {
730 int len2;
731
732 if( ( ret = asn1_get_tag( p, end, &len2,
733 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
734 {
Paul Bakkerd98030e2009-05-02 15:13:40 +0000735 return( ret );
736 }
737
Paul Bakker9be19372009-07-27 20:21:53 +0000738 cur_entry->raw.tag = **p;
739 cur_entry->raw.p = *p;
740 cur_entry->raw.len = len2;
741
Paul Bakkerd98030e2009-05-02 15:13:40 +0000742 if( ( ret = x509_get_serial( p, end, &cur_entry->serial ) ) != 0 )
743 return( ret );
744
745 if( ( ret = x509_get_UTCTime( p, end, &cur_entry->revocation_date ) ) != 0 )
746 return( ret );
747
748 if( ( ret = x509_get_crl_ext( p, end, &cur_entry->entry_ext ) ) != 0 )
749 return( ret );
750
751 if ( *p < end ) {
752 cur_entry->next = malloc( sizeof( x509_crl_entry ) );
753 cur_entry = cur_entry->next;
754 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
755 }
756 }
757
758 return( 0 );
759}
760
761/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000762 * Parse one or more certificates and add them to the chained list
763 */
764int x509parse_crt( x509_cert *chain, unsigned char *buf, int buflen )
765{
766 int ret, len;
767 unsigned char *s1, *s2;
768 unsigned char *p, *end;
769 x509_cert *crt;
770
771 crt = chain;
772
Paul Bakker320a4b52009-03-28 18:52:39 +0000773 /*
774 * Check for valid input
775 */
776 if( crt == NULL || buf == NULL )
777 return( 1 );
778
Paul Bakkere9581d62009-03-28 20:29:25 +0000779 while( crt->version != 0 && crt->next != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +0000780 crt = crt->next;
781
782 /*
Paul Bakker320a4b52009-03-28 18:52:39 +0000783 * Add new certificate on the end of the chain if needed.
784 */
Paul Bakkere9581d62009-03-28 20:29:25 +0000785 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +0000786 {
787 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
788
Paul Bakker7d06ad22009-05-02 15:53:56 +0000789 if( crt->next == NULL )
790 {
Paul Bakker320a4b52009-03-28 18:52:39 +0000791 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +0000792 return( 1 );
793 }
Paul Bakker320a4b52009-03-28 18:52:39 +0000794
Paul Bakker7d06ad22009-05-02 15:53:56 +0000795 crt = crt->next;
796 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +0000797 }
798
799 /*
Paul Bakker5121ce52009-01-03 21:22:43 +0000800 * check if the certificate is encoded in base64
801 */
802 s1 = (unsigned char *) strstr( (char *) buf,
803 "-----BEGIN CERTIFICATE-----" );
804
805 if( s1 != NULL )
806 {
807 s2 = (unsigned char *) strstr( (char *) buf,
808 "-----END CERTIFICATE-----" );
809
810 if( s2 == NULL || s2 <= s1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000811 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +0000812
813 s1 += 27;
814 if( *s1 == '\r' ) s1++;
815 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +0000816 else return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +0000817
818 /*
819 * get the DER data length and decode the buffer
820 */
821 len = 0;
822 ret = base64_decode( NULL, &len, s1, s2 - s1 );
823
Paul Bakker40e46942009-01-03 21:51:57 +0000824 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
825 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000826
827 if( ( p = (unsigned char *) malloc( len ) ) == NULL )
828 return( 1 );
829
830 if( ( ret = base64_decode( p, &len, s1, s2 - s1 ) ) != 0 )
831 {
832 free( p );
Paul Bakker40e46942009-01-03 21:51:57 +0000833 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000834 }
835
836 /*
837 * update the buffer size and offset
838 */
839 s2 += 25;
840 if( *s2 == '\r' ) s2++;
841 if( *s2 == '\n' ) s2++;
842 else
843 {
844 free( p );
Paul Bakker40e46942009-01-03 21:51:57 +0000845 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +0000846 }
847
848 buflen -= s2 - buf;
849 buf = s2;
850 }
851 else
852 {
853 /*
854 * nope, copy the raw DER data
855 */
856 p = (unsigned char *) malloc( len = buflen );
857
858 if( p == NULL )
859 return( 1 );
860
861 memcpy( p, buf, buflen );
862
863 buflen = 0;
864 }
865
866 crt->raw.p = p;
867 crt->raw.len = len;
868 end = p + len;
869
870 /*
871 * Certificate ::= SEQUENCE {
872 * tbsCertificate TBSCertificate,
873 * signatureAlgorithm AlgorithmIdentifier,
874 * signatureValue BIT STRING }
875 */
876 if( ( ret = asn1_get_tag( &p, end, &len,
877 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
878 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000879 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000880 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +0000881 }
882
883 if( len != (int) ( end - p ) )
884 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000885 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000886 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
887 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000888 }
889
890 /*
891 * TBSCertificate ::= SEQUENCE {
892 */
893 crt->tbs.p = p;
894
895 if( ( ret = asn1_get_tag( &p, end, &len,
896 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
897 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000898 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000899 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000900 }
901
902 end = p + len;
903 crt->tbs.len = end - crt->tbs.p;
904
905 /*
906 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
907 *
908 * CertificateSerialNumber ::= INTEGER
909 *
910 * signature AlgorithmIdentifier
911 */
912 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
913 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
914 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
915 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000916 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +0000917 return( ret );
918 }
919
920 crt->version++;
921
922 if( crt->version > 3 )
923 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000924 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000925 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +0000926 }
927
928 if( crt->sig_oid1.len != 9 ||
929 memcmp( crt->sig_oid1.p, OID_PKCS1, 8 ) != 0 )
930 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000931 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000932 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000933 }
934
935 if( crt->sig_oid1.p[8] < 2 ||
Paul Bakker4593aea2009-02-09 22:32:35 +0000936 ( crt->sig_oid1.p[8] > 5 && crt->sig_oid1.p[8] < 11 ) ||
Paul Bakker7d06ad22009-05-02 15:53:56 +0000937 crt->sig_oid1.p[8] > 14 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000938 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000939 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000940 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000941 }
942
943 /*
944 * issuer Name
945 */
946 crt->issuer_raw.p = p;
947
948 if( ( ret = asn1_get_tag( &p, end, &len,
949 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
950 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000951 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000952 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000953 }
954
955 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
956 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000957 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +0000958 return( ret );
959 }
960
961 crt->issuer_raw.len = p - crt->issuer_raw.p;
962
963 /*
964 * Validity ::= SEQUENCE {
965 * notBefore Time,
966 * notAfter Time }
967 *
968 */
969 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
970 &crt->valid_to ) ) != 0 )
971 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000972 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +0000973 return( ret );
974 }
975
976 /*
977 * subject Name
978 */
979 crt->subject_raw.p = p;
980
981 if( ( ret = asn1_get_tag( &p, end, &len,
982 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
983 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000984 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000985 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000986 }
987
988 if( ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
989 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000990 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +0000991 return( ret );
992 }
993
994 crt->subject_raw.len = p - crt->subject_raw.p;
995
996 /*
997 * SubjectPublicKeyInfo ::= SEQUENCE
998 * algorithm AlgorithmIdentifier,
999 * subjectPublicKey BIT STRING }
1000 */
1001 if( ( ret = asn1_get_tag( &p, end, &len,
1002 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1003 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001004 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001005 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001006 }
1007
1008 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1009 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1010 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001011 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001012 return( ret );
1013 }
1014
1015 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1016 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001017 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001018 return( ret );
1019 }
1020
1021 crt->rsa.len = mpi_size( &crt->rsa.N );
1022
1023 /*
1024 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1025 * -- If present, version shall be v2 or v3
1026 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1027 * -- If present, version shall be v2 or v3
1028 * extensions [3] EXPLICIT Extensions OPTIONAL
1029 * -- If present, version shall be v3
1030 */
1031 if( crt->version == 2 || crt->version == 3 )
1032 {
1033 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1034 if( ret != 0 )
1035 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001036 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001037 return( ret );
1038 }
1039 }
1040
1041 if( crt->version == 2 || crt->version == 3 )
1042 {
1043 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1044 if( ret != 0 )
1045 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001046 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001047 return( ret );
1048 }
1049 }
1050
1051 if( crt->version == 3 )
1052 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001053 ret = x509_get_crt_ext( &p, end, &crt->v3_ext,
Paul Bakker5121ce52009-01-03 21:22:43 +00001054 &crt->ca_istrue, &crt->max_pathlen );
1055 if( ret != 0 )
1056 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001057 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001058 return( ret );
1059 }
1060 }
1061
1062 if( p != end )
1063 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001064 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001065 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1066 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001067 }
1068
1069 end = crt->raw.p + crt->raw.len;
1070
1071 /*
1072 * signatureAlgorithm AlgorithmIdentifier,
1073 * signatureValue BIT STRING
1074 */
1075 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1076 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001077 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001078 return( ret );
1079 }
1080
Paul Bakker320a4b52009-03-28 18:52:39 +00001081 if( memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001082 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001083 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001084 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001085 }
1086
1087 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1088 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001089 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001090 return( ret );
1091 }
1092
1093 if( p != end )
1094 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001095 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001096 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1097 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001098 }
1099
Paul Bakker5121ce52009-01-03 21:22:43 +00001100 if( buflen > 0 )
Paul Bakker320a4b52009-03-28 18:52:39 +00001101 {
1102 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1103
Paul Bakker7d06ad22009-05-02 15:53:56 +00001104 if( crt->next == NULL )
1105 {
Paul Bakker320a4b52009-03-28 18:52:39 +00001106 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001107 return( 1 );
1108 }
Paul Bakker320a4b52009-03-28 18:52:39 +00001109
Paul Bakker7d06ad22009-05-02 15:53:56 +00001110 crt = crt->next;
1111 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001112
Paul Bakker5121ce52009-01-03 21:22:43 +00001113 return( x509parse_crt( crt, buf, buflen ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001114 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001115
1116 return( 0 );
1117}
1118
1119/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001120 * Parse one or more CRLs and add them to the chained list
1121 */
1122int x509parse_crl( x509_crl *chain, unsigned char *buf, int buflen )
1123{
1124 int ret, len;
1125 unsigned char *s1, *s2;
1126 unsigned char *p, *end;
1127 x509_crl *crl;
1128
1129 crl = chain;
1130
1131 /*
1132 * Check for valid input
1133 */
1134 if( crl == NULL || buf == NULL )
1135 return( 1 );
1136
1137 while( crl->version != 0 && crl->next != NULL )
1138 crl = crl->next;
1139
1140 /*
1141 * Add new CRL on the end of the chain if needed.
1142 */
1143 if ( crl->version != 0 && crl->next == NULL)
1144 {
1145 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1146
Paul Bakker7d06ad22009-05-02 15:53:56 +00001147 if( crl->next == NULL )
1148 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001149 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001150 return( 1 );
1151 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001152
Paul Bakker7d06ad22009-05-02 15:53:56 +00001153 crl = crl->next;
1154 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001155 }
1156
1157 /*
1158 * check if the CRL is encoded in base64
1159 */
1160 s1 = (unsigned char *) strstr( (char *) buf,
1161 "-----BEGIN X509 CRL-----" );
1162
1163 if( s1 != NULL )
1164 {
1165 s2 = (unsigned char *) strstr( (char *) buf,
1166 "-----END X509 CRL-----" );
1167
1168 if( s2 == NULL || s2 <= s1 )
1169 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1170
1171 s1 += 24;
1172 if( *s1 == '\r' ) s1++;
1173 if( *s1 == '\n' ) s1++;
1174 else return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1175
1176 /*
1177 * get the DER data length and decode the buffer
1178 */
1179 len = 0;
1180 ret = base64_decode( NULL, &len, s1, s2 - s1 );
1181
1182 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
1183 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
1184
1185 if( ( p = (unsigned char *) malloc( len ) ) == NULL )
1186 return( 1 );
1187
1188 if( ( ret = base64_decode( p, &len, s1, s2 - s1 ) ) != 0 )
1189 {
1190 free( p );
1191 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
1192 }
1193
1194 /*
1195 * update the buffer size and offset
1196 */
1197 s2 += 22;
1198 if( *s2 == '\r' ) s2++;
1199 if( *s2 == '\n' ) s2++;
1200 else
1201 {
1202 free( p );
1203 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1204 }
1205
1206 buflen -= s2 - buf;
1207 buf = s2;
1208 }
1209 else
1210 {
1211 /*
1212 * nope, copy the raw DER data
1213 */
1214 p = (unsigned char *) malloc( len = buflen );
1215
1216 if( p == NULL )
1217 return( 1 );
1218
1219 memcpy( p, buf, buflen );
1220
1221 buflen = 0;
1222 }
1223
1224 crl->raw.p = p;
1225 crl->raw.len = len;
1226 end = p + len;
1227
1228 /*
1229 * CertificateList ::= SEQUENCE {
1230 * tbsCertList TBSCertList,
1231 * signatureAlgorithm AlgorithmIdentifier,
1232 * signatureValue BIT STRING }
1233 */
1234 if( ( ret = asn1_get_tag( &p, end, &len,
1235 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1236 {
1237 x509_crl_free( crl );
1238 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1239 }
1240
1241 if( len != (int) ( end - p ) )
1242 {
1243 x509_crl_free( crl );
1244 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1245 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1246 }
1247
1248 /*
1249 * TBSCertList ::= SEQUENCE {
1250 */
1251 crl->tbs.p = p;
1252
1253 if( ( ret = asn1_get_tag( &p, end, &len,
1254 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1255 {
1256 x509_crl_free( crl );
1257 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
1258 }
1259
1260 end = p + len;
1261 crl->tbs.len = end - crl->tbs.p;
1262
1263 /*
1264 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1265 * -- if present, MUST be v2
1266 *
1267 * signature AlgorithmIdentifier
1268 */
1269 if( ( ret = x509_get_version( &p, end, &crl->version ) ) != 0 ||
1270 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1271 {
1272 x509_crl_free( crl );
1273 return( ret );
1274 }
1275
1276 crl->version++;
1277
1278 if( crl->version > 2 )
1279 {
1280 x509_crl_free( crl );
1281 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1282 }
1283
1284 if( crl->sig_oid1.len != 9 ||
1285 memcmp( crl->sig_oid1.p, OID_PKCS1, 8 ) != 0 )
1286 {
1287 x509_crl_free( crl );
1288 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1289 }
1290
1291 if( crl->sig_oid1.p[8] < 2 ||
1292 ( crl->sig_oid1.p[8] > 5 && crl->sig_oid1.p[8] < 11 ) ||
1293 crl->sig_oid1.p[8] > 14 )
1294 {
1295 x509_crl_free( crl );
1296 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1297 }
1298
1299 /*
1300 * issuer Name
1301 */
1302 crl->issuer_raw.p = p;
1303
1304 if( ( ret = asn1_get_tag( &p, end, &len,
1305 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1306 {
1307 x509_crl_free( crl );
1308 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
1309 }
1310
1311 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1312 {
1313 x509_crl_free( crl );
1314 return( ret );
1315 }
1316
1317 crl->issuer_raw.len = p - crl->issuer_raw.p;
1318
1319 /*
1320 * thisUpdate Time
1321 * nextUpdate Time OPTIONAL
1322 */
1323 if( ( ret = x509_get_UTCTime( &p, end, &crl->this_update ) ) != 0 )
1324 {
1325 x509_crl_free( crl );
1326 return( ret );
1327 }
1328
1329 if( ( ret = x509_get_UTCTime( &p, end, &crl->next_update ) ) != 0 )
1330 {
Paul Bakker635f4b42009-07-20 20:34:41 +00001331 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE |
Paul Bakker9be19372009-07-27 20:21:53 +00001332 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
1333 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE |
1334 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001335 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001336 x509_crl_free( crl );
1337 return( ret );
1338 }
1339 }
1340
1341 /*
1342 * revokedCertificates SEQUENCE OF SEQUENCE {
1343 * userCertificate CertificateSerialNumber,
1344 * revocationDate Time,
1345 * crlEntryExtensions Extensions OPTIONAL
1346 * -- if present, MUST be v2
1347 * } OPTIONAL
1348 */
1349 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1350 {
1351 x509_crl_free( crl );
1352 return( ret );
1353 }
1354
1355 /*
1356 * crlExtensions EXPLICIT Extensions OPTIONAL
1357 * -- if present, MUST be v2
1358 */
1359 if( crl->version == 2 )
1360 {
1361 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1362
1363 if( ret != 0 )
1364 {
1365 x509_crl_free( crl );
1366 return( ret );
1367 }
1368 }
1369
1370 if( p != end )
1371 {
1372 x509_crl_free( crl );
1373 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1374 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1375 }
1376
1377 end = crl->raw.p + crl->raw.len;
1378
1379 /*
1380 * signatureAlgorithm AlgorithmIdentifier,
1381 * signatureValue BIT STRING
1382 */
1383 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1384 {
1385 x509_crl_free( crl );
1386 return( ret );
1387 }
1388
1389 if( memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
1390 {
1391 x509_crl_free( crl );
1392 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1393 }
1394
1395 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1396 {
1397 x509_crl_free( crl );
1398 return( ret );
1399 }
1400
1401 if( p != end )
1402 {
1403 x509_crl_free( crl );
1404 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1405 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1406 }
1407
1408 if( buflen > 0 )
1409 {
1410 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1411
Paul Bakker7d06ad22009-05-02 15:53:56 +00001412 if( crl->next == NULL )
1413 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001414 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001415 return( 1 );
1416 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001417
Paul Bakker7d06ad22009-05-02 15:53:56 +00001418 crl = crl->next;
1419 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001420
1421 return( x509parse_crl( crl, buf, buflen ) );
1422 }
1423
1424 return( 0 );
1425}
1426
1427/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001428 * Load all data from a file into a given buffer.
1429 */
1430int load_file( char *path, unsigned char **buf, size_t *n )
1431{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001432 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001433
Paul Bakkerd98030e2009-05-02 15:13:40 +00001434 if( ( f = fopen( path, "rb" ) ) == NULL )
1435 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001436
Paul Bakkerd98030e2009-05-02 15:13:40 +00001437 fseek( f, 0, SEEK_END );
1438 *n = (size_t) ftell( f );
1439 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001440
Paul Bakkerd98030e2009-05-02 15:13:40 +00001441 if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
1442 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001443
Paul Bakkerd98030e2009-05-02 15:13:40 +00001444 if( fread( *buf, 1, *n, f ) != *n )
1445 {
1446 fclose( f );
1447 free( *buf );
1448 return( 1 );
1449 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001450
Paul Bakkerd98030e2009-05-02 15:13:40 +00001451 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001452
Paul Bakkerd98030e2009-05-02 15:13:40 +00001453 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001454
Paul Bakkerd98030e2009-05-02 15:13:40 +00001455 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001456}
1457
1458/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001459 * Load one or more certificates and add them to the chained list
1460 */
1461int x509parse_crtfile( x509_cert *chain, char *path )
1462{
1463 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001464 size_t n;
1465 unsigned char *buf;
1466
Paul Bakker2b245eb2009-04-19 18:44:26 +00001467 if ( load_file( path, &buf, &n ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001468 return( 1 );
1469
Paul Bakker5121ce52009-01-03 21:22:43 +00001470 ret = x509parse_crt( chain, buf, (int) n );
1471
1472 memset( buf, 0, n + 1 );
1473 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001474
1475 return( ret );
1476}
1477
Paul Bakkerd98030e2009-05-02 15:13:40 +00001478/*
1479 * Load one or more CRLs and add them to the chained list
1480 */
1481int x509parse_crlfile( x509_crl *chain, char *path )
1482{
1483 int ret;
1484 size_t n;
1485 unsigned char *buf;
1486
1487 if ( load_file( path, &buf, &n ) )
1488 return( 1 );
1489
1490 ret = x509parse_crl( chain, buf, (int) n );
1491
1492 memset( buf, 0, n + 1 );
1493 free( buf );
1494
1495 return( ret );
1496}
1497
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001498#if defined(POLARSSL_DES_C) && defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001499/*
1500 * Read a 16-byte hex string and convert it to binary
1501 */
1502static int x509_get_iv( unsigned char *s, unsigned char iv[8] )
1503{
1504 int i, j, k;
1505
1506 memset( iv, 0, 8 );
1507
1508 for( i = 0; i < 16; i++, s++ )
1509 {
1510 if( *s >= '0' && *s <= '9' ) j = *s - '0'; else
1511 if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else
1512 if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else
Paul Bakker40e46942009-01-03 21:51:57 +00001513 return( POLARSSL_ERR_X509_KEY_INVALID_ENC_IV );
Paul Bakker5121ce52009-01-03 21:22:43 +00001514
1515 k = ( ( i & 1 ) != 0 ) ? j : j << 4;
1516
1517 iv[i >> 1] = (unsigned char)( iv[i >> 1] | k );
1518 }
1519
1520 return( 0 );
1521}
1522
1523/*
1524 * Decrypt with 3DES-CBC, using PBKDF1 for key derivation
1525 */
1526static void x509_des3_decrypt( unsigned char des3_iv[8],
1527 unsigned char *buf, int buflen,
1528 unsigned char *pwd, int pwdlen )
1529{
1530 md5_context md5_ctx;
1531 des3_context des3_ctx;
1532 unsigned char md5sum[16];
1533 unsigned char des3_key[24];
1534
1535 /*
1536 * 3DES key[ 0..15] = MD5(pwd || IV)
1537 * key[16..23] = MD5(pwd || IV || 3DES key[ 0..15])
1538 */
1539 md5_starts( &md5_ctx );
1540 md5_update( &md5_ctx, pwd, pwdlen );
1541 md5_update( &md5_ctx, des3_iv, 8 );
1542 md5_finish( &md5_ctx, md5sum );
1543 memcpy( des3_key, md5sum, 16 );
1544
1545 md5_starts( &md5_ctx );
1546 md5_update( &md5_ctx, md5sum, 16 );
1547 md5_update( &md5_ctx, pwd, pwdlen );
1548 md5_update( &md5_ctx, des3_iv, 8 );
1549 md5_finish( &md5_ctx, md5sum );
1550 memcpy( des3_key + 16, md5sum, 8 );
1551
1552 des3_set3key_dec( &des3_ctx, des3_key );
1553 des3_crypt_cbc( &des3_ctx, DES_DECRYPT, buflen,
1554 des3_iv, buf, buf );
1555
1556 memset( &md5_ctx, 0, sizeof( md5_ctx ) );
1557 memset( &des3_ctx, 0, sizeof( des3_ctx ) );
1558 memset( md5sum, 0, 16 );
1559 memset( des3_key, 0, 24 );
1560}
1561#endif
1562
1563/*
1564 * Parse a private RSA key
1565 */
1566int x509parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
1567 unsigned char *pwd, int pwdlen )
1568{
1569 int ret, len, enc;
1570 unsigned char *s1, *s2;
1571 unsigned char *p, *end;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001572#if defined(POLARSSL_DES_C) && defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001573 unsigned char des3_iv[8];
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001574#else
1575 ((void) pwd);
1576 ((void) pwdlen);
1577#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001578
1579 s1 = (unsigned char *) strstr( (char *) buf,
1580 "-----BEGIN RSA PRIVATE KEY-----" );
1581
1582 if( s1 != NULL )
1583 {
1584 s2 = (unsigned char *) strstr( (char *) buf,
1585 "-----END RSA PRIVATE KEY-----" );
1586
1587 if( s2 == NULL || s2 <= s1 )
Paul Bakker40e46942009-01-03 21:51:57 +00001588 return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001589
1590 s1 += 31;
1591 if( *s1 == '\r' ) s1++;
1592 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001593 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001594
1595 enc = 0;
1596
1597 if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
1598 {
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001599#if defined(POLARSSL_DES_C) && defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001600 enc++;
1601
1602 s1 += 22;
1603 if( *s1 == '\r' ) s1++;
1604 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001605 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001606
1607 if( memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001608 return( POLARSSL_ERR_X509_KEY_UNKNOWN_ENC_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +00001609
1610 s1 += 23;
1611 if( x509_get_iv( s1, des3_iv ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001612 return( POLARSSL_ERR_X509_KEY_INVALID_ENC_IV );
Paul Bakker5121ce52009-01-03 21:22:43 +00001613
1614 s1 += 16;
1615 if( *s1 == '\r' ) s1++;
1616 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001617 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001618#else
Paul Bakker40e46942009-01-03 21:51:57 +00001619 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001620#endif
1621 }
1622
1623 len = 0;
1624 ret = base64_decode( NULL, &len, s1, s2 - s1 );
1625
Paul Bakker40e46942009-01-03 21:51:57 +00001626 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
1627 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001628
1629 if( ( buf = (unsigned char *) malloc( len ) ) == NULL )
1630 return( 1 );
1631
1632 if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
1633 {
1634 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001635 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001636 }
1637
1638 buflen = len;
1639
1640 if( enc != 0 )
1641 {
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00001642#if defined(POLARSSL_DES_C) && defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001643 if( pwd == NULL )
1644 {
1645 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001646 return( POLARSSL_ERR_X509_KEY_PASSWORD_REQUIRED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001647 }
1648
1649 x509_des3_decrypt( des3_iv, buf, buflen, pwd, pwdlen );
1650
1651 if( buf[0] != 0x30 || buf[1] != 0x82 ||
1652 buf[4] != 0x02 || buf[5] != 0x01 )
1653 {
1654 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001655 return( POLARSSL_ERR_X509_KEY_PASSWORD_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001656 }
1657#else
Paul Bakker40e46942009-01-03 21:51:57 +00001658 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001659#endif
1660 }
1661 }
1662
1663 memset( rsa, 0, sizeof( rsa_context ) );
1664
1665 p = buf;
1666 end = buf + buflen;
1667
1668 /*
1669 * RSAPrivateKey ::= SEQUENCE {
1670 * version Version,
1671 * modulus INTEGER, -- n
1672 * publicExponent INTEGER, -- e
1673 * privateExponent INTEGER, -- d
1674 * prime1 INTEGER, -- p
1675 * prime2 INTEGER, -- q
1676 * exponent1 INTEGER, -- d mod (p-1)
1677 * exponent2 INTEGER, -- d mod (q-1)
1678 * coefficient INTEGER, -- (inverse of q) mod p
1679 * otherPrimeInfos OtherPrimeInfos OPTIONAL
1680 * }
1681 */
1682 if( ( ret = asn1_get_tag( &p, end, &len,
1683 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1684 {
1685 if( s1 != NULL )
1686 free( buf );
1687
1688 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001689 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001690 }
1691
1692 end = p + len;
1693
1694 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
1695 {
1696 if( s1 != NULL )
1697 free( buf );
1698
1699 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001700 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001701 }
1702
1703 if( rsa->ver != 0 )
1704 {
1705 if( s1 != NULL )
1706 free( buf );
1707
1708 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001709 return( ret | POLARSSL_ERR_X509_KEY_INVALID_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001710 }
1711
1712 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
1713 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
1714 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
1715 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
1716 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
1717 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
1718 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
1719 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
1720 {
1721 if( s1 != NULL )
1722 free( buf );
1723
1724 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001725 return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001726 }
1727
1728 rsa->len = mpi_size( &rsa->N );
1729
1730 if( p != end )
1731 {
1732 if( s1 != NULL )
1733 free( buf );
1734
1735 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001736 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT |
1737 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001738 }
1739
1740 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
1741 {
1742 if( s1 != NULL )
1743 free( buf );
1744
1745 rsa_free( rsa );
1746 return( ret );
1747 }
1748
1749 if( s1 != NULL )
1750 free( buf );
1751
1752 return( 0 );
1753}
1754
1755/*
1756 * Load and parse a private RSA key
1757 */
1758int x509parse_keyfile( rsa_context *rsa, char *path, char *pwd )
1759{
1760 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001761 size_t n;
1762 unsigned char *buf;
1763
Paul Bakker2b245eb2009-04-19 18:44:26 +00001764 if ( load_file( path, &buf, &n ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001765 return( 1 );
1766
Paul Bakker5121ce52009-01-03 21:22:43 +00001767 if( pwd == NULL )
1768 ret = x509parse_key( rsa, buf, (int) n, NULL, 0 );
1769 else
1770 ret = x509parse_key( rsa, buf, (int) n,
1771 (unsigned char *) pwd, strlen( pwd ) );
1772
1773 memset( buf, 0, n + 1 );
1774 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001775
1776 return( ret );
1777}
1778
1779#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00001780#include <stdarg.h>
1781
1782#if !defined vsnprintf
1783#define vsnprintf _vsnprintf
1784#endif // vsnprintf
1785
1786/*
1787 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
1788 * Result value is not size of buffer needed, but -1 if no fit is possible.
1789 *
1790 * This fuction tries to 'fix' this by at least suggesting enlarging the
1791 * size by 20.
1792 */
1793int compat_snprintf(char *str, size_t size, const char *format, ...)
1794{
1795 va_list ap;
1796 int res = -1;
1797
1798 va_start( ap, format );
1799
1800 res = vsnprintf( str, size, format, ap );
1801
1802 va_end( ap );
1803
1804 // No quick fix possible
1805 if ( res < 0 )
1806 return( size + 20 );
1807
1808 return res;
1809}
1810
1811#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00001812#endif
1813
Paul Bakkerd98030e2009-05-02 15:13:40 +00001814#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
1815
1816#define SAFE_SNPRINTF() \
1817{ \
1818 if( ret == -1 ) \
1819 return( -1 ); \
1820 \
1821 if ( ret > n ) { \
1822 p[n - 1] = '\0'; \
1823 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
1824 } \
1825 \
1826 n -= ret; \
1827 p += ret; \
1828}
1829
Paul Bakker5121ce52009-01-03 21:22:43 +00001830/*
1831 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00001832 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00001833 */
Paul Bakkerd98030e2009-05-02 15:13:40 +00001834int x509parse_dn_gets( char *buf, size_t size, x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00001835{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001836 int i, ret, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00001837 unsigned char c;
1838 x509_name *name;
1839 char s[128], *p;
1840
1841 memset( s, 0, sizeof( s ) );
1842
1843 name = dn;
1844 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001845 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00001846
1847 while( name != NULL )
1848 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001849 if( name != dn ) {
1850 ret = snprintf( p, n, ", " );
1851 SAFE_SNPRINTF();
1852 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001853
1854 if( memcmp( name->oid.p, OID_X520, 2 ) == 0 )
1855 {
1856 switch( name->oid.p[2] )
1857 {
1858 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001859 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001860
1861 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001862 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001863
1864 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001865 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001866
1867 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001868 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001869
1870 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001871 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001872
1873 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001874 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001875
1876 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001877 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00001878 name->oid.p[2] );
1879 break;
1880 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001881 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001882 }
1883 else if( memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
1884 {
1885 switch( name->oid.p[8] )
1886 {
1887 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001888 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001889
1890 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001891 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00001892 name->oid.p[8] );
1893 break;
1894 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001895 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001896 }
1897 else
Paul Bakkerd98030e2009-05-02 15:13:40 +00001898 {
1899 ret = snprintf( p, n, "\?\?=" );
1900 SAFE_SNPRINTF();
1901 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001902
1903 for( i = 0; i < name->val.len; i++ )
1904 {
1905 if( i >= (int) sizeof( s ) - 1 )
1906 break;
1907
1908 c = name->val.p[i];
1909 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
1910 s[i] = '?';
1911 else s[i] = c;
1912 }
1913 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00001914 ret = snprintf( p, n, "%s", s );
1915 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001916 name = name->next;
1917 }
1918
Paul Bakkerd98030e2009-05-02 15:13:40 +00001919 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001920}
1921
1922/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001923 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00001924 */
Paul Bakkerd98030e2009-05-02 15:13:40 +00001925int x509parse_cert_info( char *buf, size_t size, char *prefix, x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00001926{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001927 int i, n, nr, ret;
1928 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00001929
1930 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001931 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00001932
Paul Bakkerd98030e2009-05-02 15:13:40 +00001933 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00001934 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001935 SAFE_SNPRINTF();
1936 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00001937 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001938 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001939
Paul Bakkerd98030e2009-05-02 15:13:40 +00001940 nr = ( crt->serial.len <= 32 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001941 ? crt->serial.len : 32;
1942
Paul Bakkerd98030e2009-05-02 15:13:40 +00001943 for( i = 0; i < nr; i++ )
1944 {
1945 ret = snprintf( p, n, "%02X%s",
1946 crt->serial.p[i], ( i < nr - 1 ) ? ":" : "" );
1947 SAFE_SNPRINTF();
1948 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001949
Paul Bakkerd98030e2009-05-02 15:13:40 +00001950 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
1951 SAFE_SNPRINTF();
1952 ret = x509parse_dn_gets( p, n, &crt->issuer );
1953 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001954
Paul Bakkerd98030e2009-05-02 15:13:40 +00001955 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
1956 SAFE_SNPRINTF();
1957 ret = x509parse_dn_gets( p, n, &crt->subject );
1958 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001959
Paul Bakkerd98030e2009-05-02 15:13:40 +00001960 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00001961 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1962 crt->valid_from.year, crt->valid_from.mon,
1963 crt->valid_from.day, crt->valid_from.hour,
1964 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001965 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001966
Paul Bakkerd98030e2009-05-02 15:13:40 +00001967 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00001968 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1969 crt->valid_to.year, crt->valid_to.mon,
1970 crt->valid_to.day, crt->valid_to.hour,
1971 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001972 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001973
Paul Bakkerd98030e2009-05-02 15:13:40 +00001974 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
1975 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001976
1977 switch( crt->sig_oid1.p[8] )
1978 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001979 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
1980 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
1981 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
1982 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
1983 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
1984 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
1985 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
1986 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
1987 default: ret = snprintf( p, n, "???" ); break;
1988 }
1989 SAFE_SNPRINTF();
1990
1991 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
1992 crt->rsa.N.n * (int) sizeof( unsigned long ) * 8 );
1993 SAFE_SNPRINTF();
1994
1995 return( size - n );
1996}
1997
1998/*
1999 * Return an informational string about the CRL.
2000 */
2001int x509parse_crl_info( char *buf, size_t size, char *prefix, x509_crl *crl )
2002{
2003 int i, n, nr, ret;
2004 char *p;
2005 x509_crl_entry *entry;
2006
2007 p = buf;
2008 n = size;
2009
2010 ret = snprintf( p, n, "%sCRL version : %d",
2011 prefix, crl->version );
2012 SAFE_SNPRINTF();
2013
2014 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2015 SAFE_SNPRINTF();
2016 ret = x509parse_dn_gets( p, n, &crl->issuer );
2017 SAFE_SNPRINTF();
2018
2019 ret = snprintf( p, n, "\n%sthis update : " \
2020 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2021 crl->this_update.year, crl->this_update.mon,
2022 crl->this_update.day, crl->this_update.hour,
2023 crl->this_update.min, crl->this_update.sec );
2024 SAFE_SNPRINTF();
2025
2026 ret = snprintf( p, n, "\n%snext update : " \
2027 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2028 crl->next_update.year, crl->next_update.mon,
2029 crl->next_update.day, crl->next_update.hour,
2030 crl->next_update.min, crl->next_update.sec );
2031 SAFE_SNPRINTF();
2032
2033 entry = &crl->entry;
2034
2035 ret = snprintf( p, n, "\n%sRevoked certificates:",
2036 prefix );
2037 SAFE_SNPRINTF();
2038
Paul Bakker9be19372009-07-27 20:21:53 +00002039 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002040 {
2041 ret = snprintf( p, n, "\n%sserial number: ",
2042 prefix );
2043 SAFE_SNPRINTF();
2044
2045 nr = ( entry->serial.len <= 32 )
2046 ? entry->serial.len : 32;
2047
2048 for( i = 0; i < nr; i++ ) {
2049 ret = snprintf( p, n, "%02X%s",
2050 entry->serial.p[i], ( i < nr - 1 ) ? ":" : "" );
2051 SAFE_SNPRINTF();
2052 }
2053
2054 ret = snprintf( p, n, " revocation date: " \
2055 "%04d-%02d-%02d %02d:%02d:%02d",
2056 entry->revocation_date.year, entry->revocation_date.mon,
2057 entry->revocation_date.day, entry->revocation_date.hour,
2058 entry->revocation_date.min, entry->revocation_date.sec );
2059 SAFE_SNPRINTF();
2060
2061 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002062 }
2063
Paul Bakkerd98030e2009-05-02 15:13:40 +00002064 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2065 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002066
Paul Bakkerd98030e2009-05-02 15:13:40 +00002067 switch( crl->sig_oid1.p[8] )
2068 {
2069 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2070 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2071 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2072 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2073 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2074 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2075 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2076 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2077 default: ret = snprintf( p, n, "???" ); break;
2078 }
2079 SAFE_SNPRINTF();
2080
Paul Bakker1e27bb22009-07-19 20:25:25 +00002081 ret = snprintf( p, n, "\n" );
2082 SAFE_SNPRINTF();
2083
Paul Bakkerd98030e2009-05-02 15:13:40 +00002084 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002085}
2086
2087/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00002088 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00002089 */
Paul Bakker40ea7de2009-05-03 10:18:48 +00002090int x509parse_time_expired( x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00002091{
2092 struct tm *lt;
2093 time_t tt;
2094
2095 tt = time( NULL );
2096 lt = localtime( &tt );
2097
Paul Bakker40ea7de2009-05-03 10:18:48 +00002098 if( lt->tm_year > to->year - 1900 )
2099 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002100
Paul Bakker40ea7de2009-05-03 10:18:48 +00002101 if( lt->tm_year == to->year - 1900 &&
2102 lt->tm_mon > to->mon - 1 )
2103 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002104
Paul Bakker40ea7de2009-05-03 10:18:48 +00002105 if( lt->tm_year == to->year - 1900 &&
2106 lt->tm_mon == to->mon - 1 &&
2107 lt->tm_mday > to->day )
2108 return( 1 );
2109
2110 return( 0 );
2111}
2112
2113/*
2114 * Return 1 if the certificate is revoked, or 0 otherwise.
2115 */
2116int x509parse_revoked( x509_cert *crt, x509_crl *crl )
2117{
2118 x509_crl_entry *cur = &crl->entry;
2119
2120 while( cur != NULL && cur->serial.len != 0 )
2121 {
2122 if( memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
2123 {
2124 if( x509parse_time_expired( &cur->revocation_date ) )
2125 return( 1 );
2126 }
2127
2128 cur = cur->next;
2129 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002130
2131 return( 0 );
2132}
2133
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002134/*
2135 * Wrapper for x509 hashes.
2136 *
2137 * @param out Buffer to receive the hash (Should be at least 64 bytes)
2138 */
Paul Bakker5121ce52009-01-03 21:22:43 +00002139static void x509_hash( unsigned char *in, int len, int alg,
2140 unsigned char *out )
2141{
2142 switch( alg )
2143 {
Paul Bakker40e46942009-01-03 21:51:57 +00002144#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002145 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002146#endif
Paul Bakker40e46942009-01-03 21:51:57 +00002147#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002148 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002149#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002150#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002151 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002152#endif
2153#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002154 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002155#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00002156#if defined(POLARSSL_SHA2_C)
2157 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
2158 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
2159#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00002160#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002161 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
2162 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
2163#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002164 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002165 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002166 break;
2167 }
2168}
2169
2170/*
2171 * Verify the certificate validity
2172 */
2173int x509parse_verify( x509_cert *crt,
2174 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00002175 x509_crl *ca_crl,
Paul Bakker5121ce52009-01-03 21:22:43 +00002176 char *cn, int *flags )
2177{
2178 int cn_len;
2179 int hash_id;
2180 int pathlen;
2181 x509_cert *cur;
2182 x509_name *name;
Paul Bakker4593aea2009-02-09 22:32:35 +00002183 unsigned char hash[64];
Paul Bakker5121ce52009-01-03 21:22:43 +00002184
Paul Bakker40ea7de2009-05-03 10:18:48 +00002185 *flags = 0;
2186
2187 if( x509parse_time_expired( &crt->valid_to ) )
2188 *flags = BADCERT_EXPIRED;
Paul Bakker5121ce52009-01-03 21:22:43 +00002189
2190 if( cn != NULL )
2191 {
2192 name = &crt->subject;
2193 cn_len = strlen( cn );
2194
2195 while( name != NULL )
2196 {
2197 if( memcmp( name->oid.p, OID_CN, 3 ) == 0 &&
2198 memcmp( name->val.p, cn, cn_len ) == 0 &&
2199 name->val.len == cn_len )
2200 break;
2201
2202 name = name->next;
2203 }
2204
2205 if( name == NULL )
2206 *flags |= BADCERT_CN_MISMATCH;
2207 }
2208
2209 *flags |= BADCERT_NOT_TRUSTED;
2210
2211 /*
2212 * Iterate upwards in the given cert chain,
2213 * ignoring any upper cert with CA != TRUE.
2214 */
2215 cur = crt->next;
2216
2217 pathlen = 1;
2218
Paul Bakker7c6d4a42009-03-28 20:35:47 +00002219 while( cur != NULL && cur->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002220 {
2221 if( cur->ca_istrue == 0 ||
2222 crt->issuer_raw.len != cur->subject_raw.len ||
2223 memcmp( crt->issuer_raw.p, cur->subject_raw.p,
2224 crt->issuer_raw.len ) != 0 )
2225 {
2226 cur = cur->next;
2227 continue;
2228 }
2229
2230 hash_id = crt->sig_oid1.p[8];
2231
2232 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2233
2234 if( rsa_pkcs1_verify( &cur->rsa, RSA_PUBLIC, hash_id,
2235 0, hash, crt->sig.p ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00002236 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002237
2238 pathlen++;
2239
2240 crt = cur;
2241 cur = crt->next;
2242 }
2243
2244 /*
2245 * Atempt to validate topmost cert with our CA chain.
2246 */
Paul Bakker7c6d4a42009-03-28 20:35:47 +00002247 while( trust_ca != NULL && trust_ca->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002248 {
2249 if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
2250 memcmp( crt->issuer_raw.p, trust_ca->subject_raw.p,
2251 crt->issuer_raw.len ) != 0 )
2252 {
2253 trust_ca = trust_ca->next;
2254 continue;
2255 }
2256
2257 if( trust_ca->max_pathlen > 0 &&
2258 trust_ca->max_pathlen < pathlen )
2259 break;
2260
2261 hash_id = crt->sig_oid1.p[8];
2262
2263 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2264
2265 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
2266 0, hash, crt->sig.p ) == 0 )
2267 {
2268 /*
2269 * cert. is signed by a trusted CA
2270 */
2271 *flags &= ~BADCERT_NOT_TRUSTED;
2272 break;
2273 }
2274
2275 trust_ca = trust_ca->next;
2276 }
2277
Paul Bakker40ea7de2009-05-03 10:18:48 +00002278 /*
2279 * TODO: What happens if no CRL is present?
2280 * Suggestion: Revocation state should be unknown if no CRL is present.
2281 * For backwards compatibility this is not yet implemented.
2282 */
2283
2284 /*
2285 * Check if the topmost certificate is revoked if the trusted CA is
2286 * determined.
2287 */
2288 while( trust_ca != NULL && ca_crl != NULL && ca_crl->version != 0 )
2289 {
2290 if( ca_crl->issuer_raw.len != trust_ca->subject_raw.len ||
2291 memcmp( ca_crl->issuer_raw.p, trust_ca->subject_raw.p,
2292 ca_crl->issuer_raw.len ) != 0 )
2293 {
2294 ca_crl = ca_crl->next;
2295 continue;
2296 }
2297
2298 /*
2299 * Check if CRL is correctry signed by the trusted CA
2300 */
2301 hash_id = ca_crl->sig_oid1.p[8];
2302
2303 x509_hash( ca_crl->tbs.p, ca_crl->tbs.len, hash_id, hash );
2304
2305 if( !rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
2306 0, hash, ca_crl->sig.p ) == 0 )
2307 {
2308 /*
2309 * CRL is not trusted
2310 */
2311 *flags |= BADCRL_NOT_TRUSTED;
2312 break;
2313 }
2314
2315 /*
2316 * Check for validity of CRL (Do not drop out)
2317 */
2318 if( x509parse_time_expired( &ca_crl->next_update ) )
2319 *flags |= BADCRL_EXPIRED;
2320
2321 /*
2322 * Check if certificate is revoked
2323 */
2324 if( x509parse_revoked(crt, ca_crl) )
2325 {
2326 *flags |= BADCERT_REVOKED;
2327 break;
2328 }
2329
2330 ca_crl = ca_crl->next;
2331 }
2332
Paul Bakker5121ce52009-01-03 21:22:43 +00002333 if( *flags != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00002334 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002335
2336 return( 0 );
2337}
2338
2339/*
2340 * Unallocate all certificate data
2341 */
2342void x509_free( x509_cert *crt )
2343{
2344 x509_cert *cert_cur = crt;
2345 x509_cert *cert_prv;
2346 x509_name *name_cur;
2347 x509_name *name_prv;
2348
2349 if( crt == NULL )
2350 return;
2351
2352 do
2353 {
2354 rsa_free( &cert_cur->rsa );
2355
2356 name_cur = cert_cur->issuer.next;
2357 while( name_cur != NULL )
2358 {
2359 name_prv = name_cur;
2360 name_cur = name_cur->next;
2361 memset( name_prv, 0, sizeof( x509_name ) );
2362 free( name_prv );
2363 }
2364
2365 name_cur = cert_cur->subject.next;
2366 while( name_cur != NULL )
2367 {
2368 name_prv = name_cur;
2369 name_cur = name_cur->next;
2370 memset( name_prv, 0, sizeof( x509_name ) );
2371 free( name_prv );
2372 }
2373
2374 if( cert_cur->raw.p != NULL )
2375 {
2376 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
2377 free( cert_cur->raw.p );
2378 }
2379
2380 cert_cur = cert_cur->next;
2381 }
2382 while( cert_cur != NULL );
2383
2384 cert_cur = crt;
2385 do
2386 {
2387 cert_prv = cert_cur;
2388 cert_cur = cert_cur->next;
2389
2390 memset( cert_prv, 0, sizeof( x509_cert ) );
2391 if( cert_prv != crt )
2392 free( cert_prv );
2393 }
2394 while( cert_cur != NULL );
2395}
2396
Paul Bakkerd98030e2009-05-02 15:13:40 +00002397/*
2398 * Unallocate all CRL data
2399 */
2400void x509_crl_free( x509_crl *crl )
2401{
2402 x509_crl *crl_cur = crl;
2403 x509_crl *crl_prv;
2404 x509_name *name_cur;
2405 x509_name *name_prv;
2406 x509_crl_entry *entry_cur;
2407 x509_crl_entry *entry_prv;
2408
2409 if( crl == NULL )
2410 return;
2411
2412 do
2413 {
2414 name_cur = crl_cur->issuer.next;
2415 while( name_cur != NULL )
2416 {
2417 name_prv = name_cur;
2418 name_cur = name_cur->next;
2419 memset( name_prv, 0, sizeof( x509_name ) );
2420 free( name_prv );
2421 }
2422
2423 entry_cur = crl_cur->entry.next;
2424 while( entry_cur != NULL )
2425 {
2426 entry_prv = entry_cur;
2427 entry_cur = entry_cur->next;
2428 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
2429 free( entry_prv );
2430 }
2431
2432 if( crl_cur->raw.p != NULL )
2433 {
2434 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
2435 free( crl_cur->raw.p );
2436 }
2437
2438 crl_cur = crl_cur->next;
2439 }
2440 while( crl_cur != NULL );
2441
2442 crl_cur = crl;
2443 do
2444 {
2445 crl_prv = crl_cur;
2446 crl_cur = crl_cur->next;
2447
2448 memset( crl_prv, 0, sizeof( x509_crl ) );
2449 if( crl_prv != crl )
2450 free( crl_prv );
2451 }
2452 while( crl_cur != NULL );
2453}
2454
Paul Bakker40e46942009-01-03 21:51:57 +00002455#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002456
Paul Bakker40e46942009-01-03 21:51:57 +00002457#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00002458
2459/*
2460 * Checkup routine
2461 */
2462int x509_self_test( int verbose )
2463{
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002464#if defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00002465 int ret, i, j;
2466 x509_cert cacert;
2467 x509_cert clicert;
2468 rsa_context rsa;
2469
2470 if( verbose != 0 )
2471 printf( " X.509 certificate load: " );
2472
2473 memset( &clicert, 0, sizeof( x509_cert ) );
2474
2475 ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
2476 strlen( test_cli_crt ) );
2477 if( ret != 0 )
2478 {
2479 if( verbose != 0 )
2480 printf( "failed\n" );
2481
2482 return( ret );
2483 }
2484
2485 memset( &cacert, 0, sizeof( x509_cert ) );
2486
2487 ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
2488 strlen( test_ca_crt ) );
2489 if( ret != 0 )
2490 {
2491 if( verbose != 0 )
2492 printf( "failed\n" );
2493
2494 return( ret );
2495 }
2496
2497 if( verbose != 0 )
2498 printf( "passed\n X.509 private key load: " );
2499
2500 i = strlen( test_ca_key );
2501 j = strlen( test_ca_pwd );
2502
2503 if( ( ret = x509parse_key( &rsa,
2504 (unsigned char *) test_ca_key, i,
2505 (unsigned char *) test_ca_pwd, j ) ) != 0 )
2506 {
2507 if( verbose != 0 )
2508 printf( "failed\n" );
2509
2510 return( ret );
2511 }
2512
2513 if( verbose != 0 )
2514 printf( "passed\n X.509 signature verify: ");
2515
Paul Bakker1973e4c2009-07-10 22:32:40 +00002516 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &i );
Paul Bakker5121ce52009-01-03 21:22:43 +00002517 if( ret != 0 )
2518 {
2519 if( verbose != 0 )
2520 printf( "failed\n" );
2521
2522 return( ret );
2523 }
2524
2525 if( verbose != 0 )
2526 printf( "passed\n\n" );
2527
2528 x509_free( &cacert );
2529 x509_free( &clicert );
2530 rsa_free( &rsa );
2531
2532 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002533#else
2534 ((void) verbose);
2535 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
2536#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002537}
2538
2539#endif
2540
2541#endif