blob: 56fd809aff8ee2bf5d1dc86dde427f68b2fb2425 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * X.509 certificate and private key decoding
3 *
Paul Bakkere0ccd0a2009-01-04 16:27:10 +00004 * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
5 *
Paul Bakker785a9ee2009-01-25 14:15:10 +00006 * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
Paul Bakker5121ce52009-01-03 21:22:43 +00007 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22/*
23 * The ITU-T X.509 standard defines a certificat format for PKI.
24 *
25 * http://www.ietf.org/rfc/rfc2459.txt
26 * http://www.ietf.org/rfc/rfc3279.txt
27 *
28 * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
29 *
30 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
31 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
32 */
33
Paul Bakker40e46942009-01-03 21:51:57 +000034#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000035
Paul Bakker40e46942009-01-03 21:51:57 +000036#if defined(POLARSSL_X509_PARSE_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000037
Paul Bakker40e46942009-01-03 21:51:57 +000038#include "polarssl/x509.h"
39#include "polarssl/base64.h"
40#include "polarssl/des.h"
41#include "polarssl/md2.h"
42#include "polarssl/md4.h"
43#include "polarssl/md5.h"
44#include "polarssl/sha1.h"
Paul Bakker026c03b2009-03-28 17:53:03 +000045#include "polarssl/sha2.h"
46#include "polarssl/sha4.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000047
48#include <string.h>
49#include <stdlib.h>
50#include <stdio.h>
51#include <time.h>
52
53/*
54 * ASN.1 DER decoding routines
55 */
56static int asn1_get_len( unsigned char **p,
57 unsigned char *end,
58 int *len )
59{
60 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +000061 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000062
63 if( ( **p & 0x80 ) == 0 )
64 *len = *(*p)++;
65 else
66 {
67 switch( **p & 0x7F )
68 {
69 case 1:
70 if( ( end - *p ) < 2 )
Paul Bakker40e46942009-01-03 21:51:57 +000071 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000072
73 *len = (*p)[1];
74 (*p) += 2;
75 break;
76
77 case 2:
78 if( ( end - *p ) < 3 )
Paul Bakker40e46942009-01-03 21:51:57 +000079 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000080
81 *len = ( (*p)[1] << 8 ) | (*p)[2];
82 (*p) += 3;
83 break;
84
85 default:
Paul Bakker40e46942009-01-03 21:51:57 +000086 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +000087 break;
88 }
89 }
90
91 if( *len > (int) ( end - *p ) )
Paul Bakker40e46942009-01-03 21:51:57 +000092 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000093
94 return( 0 );
95}
96
97static int asn1_get_tag( unsigned char **p,
98 unsigned char *end,
99 int *len, int tag )
100{
101 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000102 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000103
104 if( **p != tag )
Paul Bakker40e46942009-01-03 21:51:57 +0000105 return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000106
107 (*p)++;
108
109 return( asn1_get_len( p, end, len ) );
110}
111
112static int asn1_get_bool( unsigned char **p,
113 unsigned char *end,
114 int *val )
115{
116 int ret, len;
117
118 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 )
119 return( ret );
120
121 if( len != 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000122 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000123
124 *val = ( **p != 0 ) ? 1 : 0;
125 (*p)++;
126
127 return( 0 );
128}
129
130static int asn1_get_int( unsigned char **p,
131 unsigned char *end,
132 int *val )
133{
134 int ret, len;
135
136 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
137 return( ret );
138
139 if( len > (int) sizeof( int ) || ( **p & 0x80 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000140 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000141
142 *val = 0;
143
144 while( len-- > 0 )
145 {
146 *val = ( *val << 8 ) | **p;
147 (*p)++;
148 }
149
150 return( 0 );
151}
152
153static int asn1_get_mpi( unsigned char **p,
154 unsigned char *end,
155 mpi *X )
156{
157 int ret, len;
158
159 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
160 return( ret );
161
162 ret = mpi_read_binary( X, *p, len );
163
164 *p += len;
165
166 return( ret );
167}
168
169/*
170 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
171 */
172static int x509_get_version( unsigned char **p,
173 unsigned char *end,
174 int *ver )
175{
176 int ret, len;
177
178 if( ( ret = asn1_get_tag( p, end, &len,
179 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
180 {
Paul Bakker40e46942009-01-03 21:51:57 +0000181 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000182 return( *ver = 0 );
183
184 return( ret );
185 }
186
187 end = *p + len;
188
189 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000190 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000191
192 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000193 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION |
194 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000195
196 return( 0 );
197}
198
199/*
200 * CertificateSerialNumber ::= INTEGER
201 */
202static int x509_get_serial( unsigned char **p,
203 unsigned char *end,
204 x509_buf *serial )
205{
206 int ret;
207
208 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000209 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL |
210 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000211
212 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
213 **p != ASN1_INTEGER )
Paul Bakker40e46942009-01-03 21:51:57 +0000214 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL |
215 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000216
217 serial->tag = *(*p)++;
218
219 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000220 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000221
222 serial->p = *p;
223 *p += serial->len;
224
225 return( 0 );
226}
227
228/*
229 * AlgorithmIdentifier ::= SEQUENCE {
230 * algorithm OBJECT IDENTIFIER,
231 * parameters ANY DEFINED BY algorithm OPTIONAL }
232 */
233static int x509_get_alg( unsigned char **p,
234 unsigned char *end,
235 x509_buf *alg )
236{
237 int ret, len;
238
239 if( ( ret = asn1_get_tag( p, end, &len,
240 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000241 return( POLARSSL_ERR_X509_CERT_INVALID_ALG | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000242
243 end = *p + len;
244 alg->tag = **p;
245
246 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000247 return( POLARSSL_ERR_X509_CERT_INVALID_ALG | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000248
249 alg->p = *p;
250 *p += alg->len;
251
252 if( *p == end )
253 return( 0 );
254
255 /*
256 * assume the algorithm parameters must be NULL
257 */
258 if( ( ret = asn1_get_tag( p, end, &len, ASN1_NULL ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000259 return( POLARSSL_ERR_X509_CERT_INVALID_ALG | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000260
261 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000262 return( POLARSSL_ERR_X509_CERT_INVALID_ALG |
263 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000264
265 return( 0 );
266}
267
268/*
269 * RelativeDistinguishedName ::=
270 * SET OF AttributeTypeAndValue
271 *
272 * AttributeTypeAndValue ::= SEQUENCE {
273 * type AttributeType,
274 * value AttributeValue }
275 *
276 * AttributeType ::= OBJECT IDENTIFIER
277 *
278 * AttributeValue ::= ANY DEFINED BY AttributeType
279 */
280static int x509_get_name( unsigned char **p,
281 unsigned char *end,
282 x509_name *cur )
283{
284 int ret, len;
285 unsigned char *end2;
286 x509_buf *oid;
287 x509_buf *val;
288
289 if( ( ret = asn1_get_tag( p, end, &len,
290 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000291 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000292
293 end2 = end;
294 end = *p + len;
295
296 if( ( ret = asn1_get_tag( p, end, &len,
297 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000298 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000299
300 if( *p + len != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000301 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
302 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000303
304 oid = &cur->oid;
305 oid->tag = **p;
306
307 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000308 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000309
310 oid->p = *p;
311 *p += oid->len;
312
313 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000314 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
315 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000316
317 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
318 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
319 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker40e46942009-01-03 21:51:57 +0000320 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
321 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000322
323 val = &cur->val;
324 val->tag = *(*p)++;
325
326 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000327 return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000328
329 val->p = *p;
330 *p += val->len;
331
332 cur->next = NULL;
333
334 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000335 return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
336 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000337
338 /*
339 * recurse until end of SEQUENCE is reached
340 */
341 if( *p == end2 )
342 return( 0 );
343
344 cur->next = (x509_name *) malloc(
345 sizeof( x509_name ) );
346
347 if( cur->next == NULL )
348 return( 1 );
349
350 return( x509_get_name( p, end2, cur->next ) );
351}
352
353/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000354 * Time ::= CHOICE {
355 * utcTime UTCTime,
356 * generalTime GeneralizedTime }
357 */
Paul Bakkerd98030e2009-05-02 15:13:40 +0000358static int x509_get_UTCTime( unsigned char **p,
359 unsigned char *end,
360 x509_time *time )
361{
362 int ret, len;
363 char date[64];
364
365 if( ( ret = asn1_get_tag( p, end, &len, ASN1_UTC_TIME ) ) != 0 )
366 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret );
367
368 memset( date, 0, sizeof( date ) );
369 memcpy( date, *p, ( len < (int) sizeof( date ) - 1 ) ?
370 len : (int) sizeof( date ) - 1 );
371
372 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
373 &time->year, &time->mon, &time->day,
374 &time->hour, &time->min, &time->sec ) < 5 )
375 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
376
377 time->year += 100 * ( time->year < 90 );
378 time->year += 1900;
379
380 *p += len;
381
382 return( 0 );
383}
384
385
386/*
387 * Validity ::= SEQUENCE {
388 * notBefore Time,
389 * notAfter Time }
390 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000391static int x509_get_dates( unsigned char **p,
392 unsigned char *end,
393 x509_time *from,
394 x509_time *to )
395{
396 int ret, len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000397
398 if( ( ret = asn1_get_tag( p, end, &len,
399 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000400 return( POLARSSL_ERR_X509_CERT_INVALID_DATE | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000401
402 end = *p + len;
403
404 /*
405 * TODO: also handle GeneralizedTime
406 */
Paul Bakkerd98030e2009-05-02 15:13:40 +0000407 if( ( ret = x509_get_UTCTime( p, end, from ) ) != 0 )
408 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000409
Paul Bakkerd98030e2009-05-02 15:13:40 +0000410 if( ( ret = x509_get_UTCTime( p, end, to ) ) != 0 )
411 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000412
413 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000414 return( POLARSSL_ERR_X509_CERT_INVALID_DATE |
415 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000416
417 return( 0 );
418}
419
420/*
421 * SubjectPublicKeyInfo ::= SEQUENCE {
422 * algorithm AlgorithmIdentifier,
423 * subjectPublicKey BIT STRING }
424 */
425static int x509_get_pubkey( unsigned char **p,
426 unsigned char *end,
427 x509_buf *pk_alg_oid,
428 mpi *N, mpi *E )
429{
430 int ret, len;
431 unsigned char *end2;
432
433 if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 )
434 return( ret );
435
436 /*
437 * only RSA public keys handled at this time
438 */
439 if( pk_alg_oid->len != 9 ||
440 memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000441 return( POLARSSL_ERR_X509_CERT_UNKNOWN_PK_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000442
443 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000444 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000445
446 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000447 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY |
448 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000449
450 end2 = *p + len;
451
452 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000453 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000454
455 /*
456 * RSAPublicKey ::= SEQUENCE {
457 * modulus INTEGER, -- n
458 * publicExponent INTEGER -- e
459 * }
460 */
461 if( ( ret = asn1_get_tag( p, end2, &len,
462 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000463 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000464
465 if( *p + len != end2 )
Paul Bakker40e46942009-01-03 21:51:57 +0000466 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY |
467 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000468
469 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
470 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000471 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000472
473 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000474 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY |
475 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000476
477 return( 0 );
478}
479
480static int x509_get_sig( unsigned char **p,
481 unsigned char *end,
482 x509_buf *sig )
483{
484 int ret, len;
485
486 sig->tag = **p;
487
488 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000489 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000490
491 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000492 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000493
494 sig->len = len;
495 sig->p = *p;
496
497 *p += len;
498
499 return( 0 );
500}
501
502/*
503 * X.509 v2/v3 unique identifier (not parsed)
504 */
505static int x509_get_uid( unsigned char **p,
506 unsigned char *end,
507 x509_buf *uid, int n )
508{
509 int ret;
510
511 if( *p == end )
512 return( 0 );
513
514 uid->tag = **p;
515
516 if( ( ret = asn1_get_tag( p, end, &uid->len,
517 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
518 {
Paul Bakker40e46942009-01-03 21:51:57 +0000519 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000520 return( 0 );
521
522 return( ret );
523 }
524
525 uid->p = *p;
526 *p += uid->len;
527
528 return( 0 );
529}
530
531/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000532 * X.509 Extensions (No parsing of extensions, pointer should
533 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000534 */
535static int x509_get_ext( unsigned char **p,
536 unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000537 x509_buf *ext )
Paul Bakker5121ce52009-01-03 21:22:43 +0000538{
539 int ret, len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000540
541 if( *p == end )
542 return( 0 );
543
544 ext->tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000545
Paul Bakker5121ce52009-01-03 21:22:43 +0000546 if( ( ret = asn1_get_tag( p, end, &ext->len,
547 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000548 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000549
550 ext->p = *p;
551 end = *p + ext->len;
552
553 /*
554 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
555 *
556 * Extension ::= SEQUENCE {
557 * extnID OBJECT IDENTIFIER,
558 * critical BOOLEAN DEFAULT FALSE,
559 * extnValue OCTET STRING }
560 */
561 if( ( ret = asn1_get_tag( p, end, &len,
562 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000563 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000564
565 if( end != *p + len )
Paul Bakker40e46942009-01-03 21:51:57 +0000566 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
567 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000568
Paul Bakkerd98030e2009-05-02 15:13:40 +0000569 return( 0 );
570}
571
572/*
573 * X.509 CRL v2 extensions (no extensions parsed yet.)
574 */
575static int x509_get_crl_ext( unsigned char **p,
576 unsigned char *end,
577 x509_buf *ext )
578{
579 int ret, len;
580
581 if( ( ret = x509_get_ext( p, end, ext ) ) != 0 )
582 {
583 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
584 return( 0 );
585
586 return( ret );
587 }
588
589 while( *p < end )
590 {
591 if( ( ret = asn1_get_tag( p, end, &len,
592 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
593 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
594
595 *p += len;
596 }
597
598 if( *p != end )
599 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
600 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
601
602 return( 0 );
603}
604
605/*
606 * X.509 v3 extensions (only BasicConstraints are parsed)
607 */
608static int x509_get_crt_ext( unsigned char **p,
609 unsigned char *end,
610 x509_buf *ext,
611 int *ca_istrue,
612 int *max_pathlen )
613{
614 int ret, len;
615 int is_critical = 1;
616 int is_cacert = 0;
617 unsigned char *end2;
618
619 if( ( ret = x509_get_ext( p, end, ext ) ) != 0 )
620 {
621 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
622 return( 0 );
623
624 return( ret );
625 }
626
Paul Bakker5121ce52009-01-03 21:22:43 +0000627 while( *p < end )
628 {
629 if( ( ret = asn1_get_tag( p, end, &len,
630 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000631 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000632
633 if( memcmp( *p, "\x06\x03\x55\x1D\x13", 5 ) != 0 )
634 {
635 *p += len;
636 continue;
637 }
638
639 *p += 5;
640
641 if( ( ret = asn1_get_bool( p, end, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000642 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
643 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000644
645 if( ( ret = asn1_get_tag( p, end, &len,
646 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000647 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000648
649 /*
650 * BasicConstraints ::= SEQUENCE {
651 * cA BOOLEAN DEFAULT FALSE,
652 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
653 */
654 end2 = *p + len;
655
656 if( ( ret = asn1_get_tag( p, end2, &len,
657 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000658 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000659
660 if( *p == end2 )
661 continue;
662
663 if( ( ret = asn1_get_bool( p, end2, &is_cacert ) ) != 0 )
664 {
Paul Bakker40e46942009-01-03 21:51:57 +0000665 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000666 ret = asn1_get_int( p, end2, &is_cacert );
667
668 if( ret != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000669 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000670
671 if( is_cacert != 0 )
672 is_cacert = 1;
673 }
674
675 if( *p == end2 )
676 continue;
677
678 if( ( ret = asn1_get_int( p, end2, max_pathlen ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000679 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000680
681 if( *p != end2 )
Paul Bakker40e46942009-01-03 21:51:57 +0000682 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
683 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000684
685 max_pathlen++;
686 }
687
688 if( *p != end )
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 *ca_istrue = is_critical & is_cacert;
693
694 return( 0 );
695}
696
697/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000698 * X.509 CRL Entries
699 */
700static int x509_get_entries( unsigned char **p,
701 unsigned char *end,
702 x509_crl_entry *entry )
703{
Paul Bakker9be19372009-07-27 20:21:53 +0000704 int ret, entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000705 x509_crl_entry *cur_entry = entry;
706
707 if( *p == end )
708 return( 0 );
709
Paul Bakker9be19372009-07-27 20:21:53 +0000710 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000711 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
712 {
713 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
714 return( 0 );
715
716 return( ret );
717 }
718
Paul Bakker9be19372009-07-27 20:21:53 +0000719 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000720
721 while( *p < end )
722 {
723 int len2;
724
725 if( ( ret = asn1_get_tag( p, end, &len2,
726 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
727 {
Paul Bakkerd98030e2009-05-02 15:13:40 +0000728 return( ret );
729 }
730
Paul Bakker9be19372009-07-27 20:21:53 +0000731 cur_entry->raw.tag = **p;
732 cur_entry->raw.p = *p;
733 cur_entry->raw.len = len2;
734
Paul Bakkerd98030e2009-05-02 15:13:40 +0000735 if( ( ret = x509_get_serial( p, end, &cur_entry->serial ) ) != 0 )
736 return( ret );
737
738 if( ( ret = x509_get_UTCTime( p, end, &cur_entry->revocation_date ) ) != 0 )
739 return( ret );
740
741 if( ( ret = x509_get_crl_ext( p, end, &cur_entry->entry_ext ) ) != 0 )
742 return( ret );
743
744 if ( *p < end ) {
745 cur_entry->next = malloc( sizeof( x509_crl_entry ) );
746 cur_entry = cur_entry->next;
747 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
748 }
749 }
750
751 return( 0 );
752}
753
754/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000755 * Parse one or more certificates and add them to the chained list
756 */
757int x509parse_crt( x509_cert *chain, unsigned char *buf, int buflen )
758{
759 int ret, len;
760 unsigned char *s1, *s2;
761 unsigned char *p, *end;
762 x509_cert *crt;
763
764 crt = chain;
765
Paul Bakker320a4b52009-03-28 18:52:39 +0000766 /*
767 * Check for valid input
768 */
769 if( crt == NULL || buf == NULL )
770 return( 1 );
771
Paul Bakkere9581d62009-03-28 20:29:25 +0000772 while( crt->version != 0 && crt->next != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +0000773 crt = crt->next;
774
775 /*
Paul Bakker320a4b52009-03-28 18:52:39 +0000776 * Add new certificate on the end of the chain if needed.
777 */
Paul Bakkere9581d62009-03-28 20:29:25 +0000778 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +0000779 {
780 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
781
Paul Bakker7d06ad22009-05-02 15:53:56 +0000782 if( crt->next == NULL )
783 {
Paul Bakker320a4b52009-03-28 18:52:39 +0000784 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +0000785 return( 1 );
786 }
Paul Bakker320a4b52009-03-28 18:52:39 +0000787
Paul Bakker7d06ad22009-05-02 15:53:56 +0000788 crt = crt->next;
789 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +0000790 }
791
792 /*
Paul Bakker5121ce52009-01-03 21:22:43 +0000793 * check if the certificate is encoded in base64
794 */
795 s1 = (unsigned char *) strstr( (char *) buf,
796 "-----BEGIN CERTIFICATE-----" );
797
798 if( s1 != NULL )
799 {
800 s2 = (unsigned char *) strstr( (char *) buf,
801 "-----END CERTIFICATE-----" );
802
803 if( s2 == NULL || s2 <= s1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000804 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +0000805
806 s1 += 27;
807 if( *s1 == '\r' ) s1++;
808 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +0000809 else return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +0000810
811 /*
812 * get the DER data length and decode the buffer
813 */
814 len = 0;
815 ret = base64_decode( NULL, &len, s1, s2 - s1 );
816
Paul Bakker40e46942009-01-03 21:51:57 +0000817 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
818 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000819
820 if( ( p = (unsigned char *) malloc( len ) ) == NULL )
821 return( 1 );
822
823 if( ( ret = base64_decode( p, &len, s1, s2 - s1 ) ) != 0 )
824 {
825 free( p );
Paul Bakker40e46942009-01-03 21:51:57 +0000826 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000827 }
828
829 /*
830 * update the buffer size and offset
831 */
832 s2 += 25;
833 if( *s2 == '\r' ) s2++;
834 if( *s2 == '\n' ) s2++;
835 else
836 {
837 free( p );
Paul Bakker40e46942009-01-03 21:51:57 +0000838 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +0000839 }
840
841 buflen -= s2 - buf;
842 buf = s2;
843 }
844 else
845 {
846 /*
847 * nope, copy the raw DER data
848 */
849 p = (unsigned char *) malloc( len = buflen );
850
851 if( p == NULL )
852 return( 1 );
853
854 memcpy( p, buf, buflen );
855
856 buflen = 0;
857 }
858
859 crt->raw.p = p;
860 crt->raw.len = len;
861 end = p + len;
862
863 /*
864 * Certificate ::= SEQUENCE {
865 * tbsCertificate TBSCertificate,
866 * signatureAlgorithm AlgorithmIdentifier,
867 * signatureValue BIT STRING }
868 */
869 if( ( ret = asn1_get_tag( &p, end, &len,
870 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
871 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000872 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000873 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +0000874 }
875
876 if( len != (int) ( end - p ) )
877 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000878 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000879 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
880 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000881 }
882
883 /*
884 * TBSCertificate ::= SEQUENCE {
885 */
886 crt->tbs.p = p;
887
888 if( ( ret = asn1_get_tag( &p, end, &len,
889 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
890 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000891 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000892 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000893 }
894
895 end = p + len;
896 crt->tbs.len = end - crt->tbs.p;
897
898 /*
899 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
900 *
901 * CertificateSerialNumber ::= INTEGER
902 *
903 * signature AlgorithmIdentifier
904 */
905 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
906 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
907 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
908 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000909 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +0000910 return( ret );
911 }
912
913 crt->version++;
914
915 if( crt->version > 3 )
916 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000917 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000918 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +0000919 }
920
921 if( crt->sig_oid1.len != 9 ||
922 memcmp( crt->sig_oid1.p, OID_PKCS1, 8 ) != 0 )
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_SIG_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000926 }
927
928 if( crt->sig_oid1.p[8] < 2 ||
Paul Bakker4593aea2009-02-09 22:32:35 +0000929 ( crt->sig_oid1.p[8] > 5 && crt->sig_oid1.p[8] < 11 ) ||
Paul Bakker7d06ad22009-05-02 15:53:56 +0000930 crt->sig_oid1.p[8] > 14 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000931 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000932 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000933 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000934 }
935
936 /*
937 * issuer Name
938 */
939 crt->issuer_raw.p = p;
940
941 if( ( ret = asn1_get_tag( &p, end, &len,
942 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
943 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000944 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000945 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000946 }
947
948 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
949 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000950 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +0000951 return( ret );
952 }
953
954 crt->issuer_raw.len = p - crt->issuer_raw.p;
955
956 /*
957 * Validity ::= SEQUENCE {
958 * notBefore Time,
959 * notAfter Time }
960 *
961 */
962 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
963 &crt->valid_to ) ) != 0 )
964 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000965 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +0000966 return( ret );
967 }
968
969 /*
970 * subject Name
971 */
972 crt->subject_raw.p = p;
973
974 if( ( ret = asn1_get_tag( &p, end, &len,
975 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
976 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000977 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000978 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000979 }
980
981 if( ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
982 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000983 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +0000984 return( ret );
985 }
986
987 crt->subject_raw.len = p - crt->subject_raw.p;
988
989 /*
990 * SubjectPublicKeyInfo ::= SEQUENCE
991 * algorithm AlgorithmIdentifier,
992 * subjectPublicKey BIT STRING }
993 */
994 if( ( ret = asn1_get_tag( &p, end, &len,
995 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
996 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000997 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000998 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000999 }
1000
1001 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1002 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1003 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001004 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001005 return( ret );
1006 }
1007
1008 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1009 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001010 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001011 return( ret );
1012 }
1013
1014 crt->rsa.len = mpi_size( &crt->rsa.N );
1015
1016 /*
1017 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1018 * -- If present, version shall be v2 or v3
1019 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1020 * -- If present, version shall be v2 or v3
1021 * extensions [3] EXPLICIT Extensions OPTIONAL
1022 * -- If present, version shall be v3
1023 */
1024 if( crt->version == 2 || crt->version == 3 )
1025 {
1026 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1027 if( ret != 0 )
1028 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001029 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001030 return( ret );
1031 }
1032 }
1033
1034 if( crt->version == 2 || crt->version == 3 )
1035 {
1036 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1037 if( ret != 0 )
1038 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001039 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001040 return( ret );
1041 }
1042 }
1043
1044 if( crt->version == 3 )
1045 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001046 ret = x509_get_crt_ext( &p, end, &crt->v3_ext,
Paul Bakker5121ce52009-01-03 21:22:43 +00001047 &crt->ca_istrue, &crt->max_pathlen );
1048 if( ret != 0 )
1049 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001050 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001051 return( ret );
1052 }
1053 }
1054
1055 if( p != end )
1056 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001057 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001058 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1059 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001060 }
1061
1062 end = crt->raw.p + crt->raw.len;
1063
1064 /*
1065 * signatureAlgorithm AlgorithmIdentifier,
1066 * signatureValue BIT STRING
1067 */
1068 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1069 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001070 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001071 return( ret );
1072 }
1073
Paul Bakker320a4b52009-03-28 18:52:39 +00001074 if( memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001075 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001076 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001077 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001078 }
1079
1080 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1081 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001082 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001083 return( ret );
1084 }
1085
1086 if( p != end )
1087 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001088 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001089 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1090 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001091 }
1092
Paul Bakker5121ce52009-01-03 21:22:43 +00001093 if( buflen > 0 )
Paul Bakker320a4b52009-03-28 18:52:39 +00001094 {
1095 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1096
Paul Bakker7d06ad22009-05-02 15:53:56 +00001097 if( crt->next == NULL )
1098 {
Paul Bakker320a4b52009-03-28 18:52:39 +00001099 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001100 return( 1 );
1101 }
Paul Bakker320a4b52009-03-28 18:52:39 +00001102
Paul Bakker7d06ad22009-05-02 15:53:56 +00001103 crt = crt->next;
1104 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001105
Paul Bakker5121ce52009-01-03 21:22:43 +00001106 return( x509parse_crt( crt, buf, buflen ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001107 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001108
1109 return( 0 );
1110}
1111
1112/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001113 * Parse one or more CRLs and add them to the chained list
1114 */
1115int x509parse_crl( x509_crl *chain, unsigned char *buf, int buflen )
1116{
1117 int ret, len;
1118 unsigned char *s1, *s2;
1119 unsigned char *p, *end;
1120 x509_crl *crl;
1121
1122 crl = chain;
1123
1124 /*
1125 * Check for valid input
1126 */
1127 if( crl == NULL || buf == NULL )
1128 return( 1 );
1129
1130 while( crl->version != 0 && crl->next != NULL )
1131 crl = crl->next;
1132
1133 /*
1134 * Add new CRL on the end of the chain if needed.
1135 */
1136 if ( crl->version != 0 && crl->next == NULL)
1137 {
1138 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1139
Paul Bakker7d06ad22009-05-02 15:53:56 +00001140 if( crl->next == NULL )
1141 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001142 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001143 return( 1 );
1144 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001145
Paul Bakker7d06ad22009-05-02 15:53:56 +00001146 crl = crl->next;
1147 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001148 }
1149
1150 /*
1151 * check if the CRL is encoded in base64
1152 */
1153 s1 = (unsigned char *) strstr( (char *) buf,
1154 "-----BEGIN X509 CRL-----" );
1155
1156 if( s1 != NULL )
1157 {
1158 s2 = (unsigned char *) strstr( (char *) buf,
1159 "-----END X509 CRL-----" );
1160
1161 if( s2 == NULL || s2 <= s1 )
1162 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1163
1164 s1 += 24;
1165 if( *s1 == '\r' ) s1++;
1166 if( *s1 == '\n' ) s1++;
1167 else return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1168
1169 /*
1170 * get the DER data length and decode the buffer
1171 */
1172 len = 0;
1173 ret = base64_decode( NULL, &len, s1, s2 - s1 );
1174
1175 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
1176 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
1177
1178 if( ( p = (unsigned char *) malloc( len ) ) == NULL )
1179 return( 1 );
1180
1181 if( ( ret = base64_decode( p, &len, s1, s2 - s1 ) ) != 0 )
1182 {
1183 free( p );
1184 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
1185 }
1186
1187 /*
1188 * update the buffer size and offset
1189 */
1190 s2 += 22;
1191 if( *s2 == '\r' ) s2++;
1192 if( *s2 == '\n' ) s2++;
1193 else
1194 {
1195 free( p );
1196 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1197 }
1198
1199 buflen -= s2 - buf;
1200 buf = s2;
1201 }
1202 else
1203 {
1204 /*
1205 * nope, copy the raw DER data
1206 */
1207 p = (unsigned char *) malloc( len = buflen );
1208
1209 if( p == NULL )
1210 return( 1 );
1211
1212 memcpy( p, buf, buflen );
1213
1214 buflen = 0;
1215 }
1216
1217 crl->raw.p = p;
1218 crl->raw.len = len;
1219 end = p + len;
1220
1221 /*
1222 * CertificateList ::= SEQUENCE {
1223 * tbsCertList TBSCertList,
1224 * signatureAlgorithm AlgorithmIdentifier,
1225 * signatureValue BIT STRING }
1226 */
1227 if( ( ret = asn1_get_tag( &p, end, &len,
1228 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1229 {
1230 x509_crl_free( crl );
1231 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1232 }
1233
1234 if( len != (int) ( end - p ) )
1235 {
1236 x509_crl_free( crl );
1237 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1238 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1239 }
1240
1241 /*
1242 * TBSCertList ::= SEQUENCE {
1243 */
1244 crl->tbs.p = p;
1245
1246 if( ( ret = asn1_get_tag( &p, end, &len,
1247 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1248 {
1249 x509_crl_free( crl );
1250 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
1251 }
1252
1253 end = p + len;
1254 crl->tbs.len = end - crl->tbs.p;
1255
1256 /*
1257 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1258 * -- if present, MUST be v2
1259 *
1260 * signature AlgorithmIdentifier
1261 */
1262 if( ( ret = x509_get_version( &p, end, &crl->version ) ) != 0 ||
1263 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1264 {
1265 x509_crl_free( crl );
1266 return( ret );
1267 }
1268
1269 crl->version++;
1270
1271 if( crl->version > 2 )
1272 {
1273 x509_crl_free( crl );
1274 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1275 }
1276
1277 if( crl->sig_oid1.len != 9 ||
1278 memcmp( crl->sig_oid1.p, OID_PKCS1, 8 ) != 0 )
1279 {
1280 x509_crl_free( crl );
1281 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1282 }
1283
1284 if( crl->sig_oid1.p[8] < 2 ||
1285 ( crl->sig_oid1.p[8] > 5 && crl->sig_oid1.p[8] < 11 ) ||
1286 crl->sig_oid1.p[8] > 14 )
1287 {
1288 x509_crl_free( crl );
1289 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1290 }
1291
1292 /*
1293 * issuer Name
1294 */
1295 crl->issuer_raw.p = p;
1296
1297 if( ( ret = asn1_get_tag( &p, end, &len,
1298 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1299 {
1300 x509_crl_free( crl );
1301 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
1302 }
1303
1304 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1305 {
1306 x509_crl_free( crl );
1307 return( ret );
1308 }
1309
1310 crl->issuer_raw.len = p - crl->issuer_raw.p;
1311
1312 /*
1313 * thisUpdate Time
1314 * nextUpdate Time OPTIONAL
1315 */
1316 if( ( ret = x509_get_UTCTime( &p, end, &crl->this_update ) ) != 0 )
1317 {
1318 x509_crl_free( crl );
1319 return( ret );
1320 }
1321
1322 if( ( ret = x509_get_UTCTime( &p, end, &crl->next_update ) ) != 0 )
1323 {
Paul Bakker635f4b42009-07-20 20:34:41 +00001324 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE |
Paul Bakker9be19372009-07-27 20:21:53 +00001325 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
1326 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE |
1327 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001328 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001329 x509_crl_free( crl );
1330 return( ret );
1331 }
1332 }
1333
1334 /*
1335 * revokedCertificates SEQUENCE OF SEQUENCE {
1336 * userCertificate CertificateSerialNumber,
1337 * revocationDate Time,
1338 * crlEntryExtensions Extensions OPTIONAL
1339 * -- if present, MUST be v2
1340 * } OPTIONAL
1341 */
1342 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1343 {
1344 x509_crl_free( crl );
1345 return( ret );
1346 }
1347
1348 /*
1349 * crlExtensions EXPLICIT Extensions OPTIONAL
1350 * -- if present, MUST be v2
1351 */
1352 if( crl->version == 2 )
1353 {
1354 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1355
1356 if( ret != 0 )
1357 {
1358 x509_crl_free( crl );
1359 return( ret );
1360 }
1361 }
1362
1363 if( p != end )
1364 {
1365 x509_crl_free( crl );
1366 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1367 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1368 }
1369
1370 end = crl->raw.p + crl->raw.len;
1371
1372 /*
1373 * signatureAlgorithm AlgorithmIdentifier,
1374 * signatureValue BIT STRING
1375 */
1376 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1377 {
1378 x509_crl_free( crl );
1379 return( ret );
1380 }
1381
1382 if( memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
1383 {
1384 x509_crl_free( crl );
1385 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1386 }
1387
1388 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1389 {
1390 x509_crl_free( crl );
1391 return( ret );
1392 }
1393
1394 if( p != end )
1395 {
1396 x509_crl_free( crl );
1397 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1398 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1399 }
1400
1401 if( buflen > 0 )
1402 {
1403 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1404
Paul Bakker7d06ad22009-05-02 15:53:56 +00001405 if( crl->next == NULL )
1406 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001407 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001408 return( 1 );
1409 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001410
Paul Bakker7d06ad22009-05-02 15:53:56 +00001411 crl = crl->next;
1412 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001413
1414 return( x509parse_crl( crl, buf, buflen ) );
1415 }
1416
1417 return( 0 );
1418}
1419
1420/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001421 * Load all data from a file into a given buffer.
1422 */
1423int load_file( char *path, unsigned char **buf, size_t *n )
1424{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001425 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001426
Paul Bakkerd98030e2009-05-02 15:13:40 +00001427 if( ( f = fopen( path, "rb" ) ) == NULL )
1428 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001429
Paul Bakkerd98030e2009-05-02 15:13:40 +00001430 fseek( f, 0, SEEK_END );
1431 *n = (size_t) ftell( f );
1432 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001433
Paul Bakkerd98030e2009-05-02 15:13:40 +00001434 if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
1435 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001436
Paul Bakkerd98030e2009-05-02 15:13:40 +00001437 if( fread( *buf, 1, *n, f ) != *n )
1438 {
1439 fclose( f );
1440 free( *buf );
1441 return( 1 );
1442 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001443
Paul Bakkerd98030e2009-05-02 15:13:40 +00001444 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001445
Paul Bakkerd98030e2009-05-02 15:13:40 +00001446 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001447
Paul Bakkerd98030e2009-05-02 15:13:40 +00001448 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001449}
1450
1451/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001452 * Load one or more certificates and add them to the chained list
1453 */
1454int x509parse_crtfile( x509_cert *chain, char *path )
1455{
1456 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001457 size_t n;
1458 unsigned char *buf;
1459
Paul Bakker2b245eb2009-04-19 18:44:26 +00001460 if ( load_file( path, &buf, &n ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001461 return( 1 );
1462
Paul Bakker5121ce52009-01-03 21:22:43 +00001463 ret = x509parse_crt( chain, buf, (int) n );
1464
1465 memset( buf, 0, n + 1 );
1466 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001467
1468 return( ret );
1469}
1470
Paul Bakkerd98030e2009-05-02 15:13:40 +00001471/*
1472 * Load one or more CRLs and add them to the chained list
1473 */
1474int x509parse_crlfile( x509_crl *chain, char *path )
1475{
1476 int ret;
1477 size_t n;
1478 unsigned char *buf;
1479
1480 if ( load_file( path, &buf, &n ) )
1481 return( 1 );
1482
1483 ret = x509parse_crl( chain, buf, (int) n );
1484
1485 memset( buf, 0, n + 1 );
1486 free( buf );
1487
1488 return( ret );
1489}
1490
Paul Bakker40e46942009-01-03 21:51:57 +00001491#if defined(POLARSSL_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001492/*
1493 * Read a 16-byte hex string and convert it to binary
1494 */
1495static int x509_get_iv( unsigned char *s, unsigned char iv[8] )
1496{
1497 int i, j, k;
1498
1499 memset( iv, 0, 8 );
1500
1501 for( i = 0; i < 16; i++, s++ )
1502 {
1503 if( *s >= '0' && *s <= '9' ) j = *s - '0'; else
1504 if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else
1505 if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else
Paul Bakker40e46942009-01-03 21:51:57 +00001506 return( POLARSSL_ERR_X509_KEY_INVALID_ENC_IV );
Paul Bakker5121ce52009-01-03 21:22:43 +00001507
1508 k = ( ( i & 1 ) != 0 ) ? j : j << 4;
1509
1510 iv[i >> 1] = (unsigned char)( iv[i >> 1] | k );
1511 }
1512
1513 return( 0 );
1514}
1515
1516/*
1517 * Decrypt with 3DES-CBC, using PBKDF1 for key derivation
1518 */
1519static void x509_des3_decrypt( unsigned char des3_iv[8],
1520 unsigned char *buf, int buflen,
1521 unsigned char *pwd, int pwdlen )
1522{
1523 md5_context md5_ctx;
1524 des3_context des3_ctx;
1525 unsigned char md5sum[16];
1526 unsigned char des3_key[24];
1527
1528 /*
1529 * 3DES key[ 0..15] = MD5(pwd || IV)
1530 * key[16..23] = MD5(pwd || IV || 3DES key[ 0..15])
1531 */
1532 md5_starts( &md5_ctx );
1533 md5_update( &md5_ctx, pwd, pwdlen );
1534 md5_update( &md5_ctx, des3_iv, 8 );
1535 md5_finish( &md5_ctx, md5sum );
1536 memcpy( des3_key, md5sum, 16 );
1537
1538 md5_starts( &md5_ctx );
1539 md5_update( &md5_ctx, md5sum, 16 );
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 + 16, md5sum, 8 );
1544
1545 des3_set3key_dec( &des3_ctx, des3_key );
1546 des3_crypt_cbc( &des3_ctx, DES_DECRYPT, buflen,
1547 des3_iv, buf, buf );
1548
1549 memset( &md5_ctx, 0, sizeof( md5_ctx ) );
1550 memset( &des3_ctx, 0, sizeof( des3_ctx ) );
1551 memset( md5sum, 0, 16 );
1552 memset( des3_key, 0, 24 );
1553}
1554#endif
1555
1556/*
1557 * Parse a private RSA key
1558 */
1559int x509parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
1560 unsigned char *pwd, int pwdlen )
1561{
1562 int ret, len, enc;
1563 unsigned char *s1, *s2;
1564 unsigned char *p, *end;
1565 unsigned char des3_iv[8];
1566
1567 s1 = (unsigned char *) strstr( (char *) buf,
1568 "-----BEGIN RSA PRIVATE KEY-----" );
1569
1570 if( s1 != NULL )
1571 {
1572 s2 = (unsigned char *) strstr( (char *) buf,
1573 "-----END RSA PRIVATE KEY-----" );
1574
1575 if( s2 == NULL || s2 <= s1 )
Paul Bakker40e46942009-01-03 21:51:57 +00001576 return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001577
1578 s1 += 31;
1579 if( *s1 == '\r' ) s1++;
1580 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001581 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001582
1583 enc = 0;
1584
1585 if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
1586 {
Paul Bakker40e46942009-01-03 21:51:57 +00001587#if defined(POLARSSL_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001588 enc++;
1589
1590 s1 += 22;
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 if( memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001596 return( POLARSSL_ERR_X509_KEY_UNKNOWN_ENC_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +00001597
1598 s1 += 23;
1599 if( x509_get_iv( s1, des3_iv ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001600 return( POLARSSL_ERR_X509_KEY_INVALID_ENC_IV );
Paul Bakker5121ce52009-01-03 21:22:43 +00001601
1602 s1 += 16;
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#else
Paul Bakker40e46942009-01-03 21:51:57 +00001607 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001608#endif
1609 }
1610
1611 len = 0;
1612 ret = base64_decode( NULL, &len, s1, s2 - s1 );
1613
Paul Bakker40e46942009-01-03 21:51:57 +00001614 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
1615 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001616
1617 if( ( buf = (unsigned char *) malloc( len ) ) == NULL )
1618 return( 1 );
1619
1620 if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
1621 {
1622 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001623 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001624 }
1625
1626 buflen = len;
1627
1628 if( enc != 0 )
1629 {
Paul Bakker40e46942009-01-03 21:51:57 +00001630#if defined(POLARSSL_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001631 if( pwd == NULL )
1632 {
1633 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001634 return( POLARSSL_ERR_X509_KEY_PASSWORD_REQUIRED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001635 }
1636
1637 x509_des3_decrypt( des3_iv, buf, buflen, pwd, pwdlen );
1638
1639 if( buf[0] != 0x30 || buf[1] != 0x82 ||
1640 buf[4] != 0x02 || buf[5] != 0x01 )
1641 {
1642 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001643 return( POLARSSL_ERR_X509_KEY_PASSWORD_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001644 }
1645#else
Paul Bakker40e46942009-01-03 21:51:57 +00001646 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001647#endif
1648 }
1649 }
1650
1651 memset( rsa, 0, sizeof( rsa_context ) );
1652
1653 p = buf;
1654 end = buf + buflen;
1655
1656 /*
1657 * RSAPrivateKey ::= SEQUENCE {
1658 * version Version,
1659 * modulus INTEGER, -- n
1660 * publicExponent INTEGER, -- e
1661 * privateExponent INTEGER, -- d
1662 * prime1 INTEGER, -- p
1663 * prime2 INTEGER, -- q
1664 * exponent1 INTEGER, -- d mod (p-1)
1665 * exponent2 INTEGER, -- d mod (q-1)
1666 * coefficient INTEGER, -- (inverse of q) mod p
1667 * otherPrimeInfos OtherPrimeInfos OPTIONAL
1668 * }
1669 */
1670 if( ( ret = asn1_get_tag( &p, end, &len,
1671 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1672 {
1673 if( s1 != NULL )
1674 free( buf );
1675
1676 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001677 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001678 }
1679
1680 end = p + len;
1681
1682 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
1683 {
1684 if( s1 != NULL )
1685 free( buf );
1686
1687 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001688 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001689 }
1690
1691 if( rsa->ver != 0 )
1692 {
1693 if( s1 != NULL )
1694 free( buf );
1695
1696 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001697 return( ret | POLARSSL_ERR_X509_KEY_INVALID_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001698 }
1699
1700 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
1701 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
1702 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
1703 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
1704 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
1705 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
1706 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
1707 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
1708 {
1709 if( s1 != NULL )
1710 free( buf );
1711
1712 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001713 return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001714 }
1715
1716 rsa->len = mpi_size( &rsa->N );
1717
1718 if( p != end )
1719 {
1720 if( s1 != NULL )
1721 free( buf );
1722
1723 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001724 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT |
1725 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001726 }
1727
1728 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
1729 {
1730 if( s1 != NULL )
1731 free( buf );
1732
1733 rsa_free( rsa );
1734 return( ret );
1735 }
1736
1737 if( s1 != NULL )
1738 free( buf );
1739
1740 return( 0 );
1741}
1742
1743/*
1744 * Load and parse a private RSA key
1745 */
1746int x509parse_keyfile( rsa_context *rsa, char *path, char *pwd )
1747{
1748 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001749 size_t n;
1750 unsigned char *buf;
1751
Paul Bakker2b245eb2009-04-19 18:44:26 +00001752 if ( load_file( path, &buf, &n ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001753 return( 1 );
1754
Paul Bakker5121ce52009-01-03 21:22:43 +00001755 if( pwd == NULL )
1756 ret = x509parse_key( rsa, buf, (int) n, NULL, 0 );
1757 else
1758 ret = x509parse_key( rsa, buf, (int) n,
1759 (unsigned char *) pwd, strlen( pwd ) );
1760
1761 memset( buf, 0, n + 1 );
1762 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001763
1764 return( ret );
1765}
1766
1767#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00001768#include <stdarg.h>
1769
1770#if !defined vsnprintf
1771#define vsnprintf _vsnprintf
1772#endif // vsnprintf
1773
1774/*
1775 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
1776 * Result value is not size of buffer needed, but -1 if no fit is possible.
1777 *
1778 * This fuction tries to 'fix' this by at least suggesting enlarging the
1779 * size by 20.
1780 */
1781int compat_snprintf(char *str, size_t size, const char *format, ...)
1782{
1783 va_list ap;
1784 int res = -1;
1785
1786 va_start( ap, format );
1787
1788 res = vsnprintf( str, size, format, ap );
1789
1790 va_end( ap );
1791
1792 // No quick fix possible
1793 if ( res < 0 )
1794 return( size + 20 );
1795
1796 return res;
1797}
1798
1799#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00001800#endif
1801
Paul Bakkerd98030e2009-05-02 15:13:40 +00001802#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
1803
1804#define SAFE_SNPRINTF() \
1805{ \
1806 if( ret == -1 ) \
1807 return( -1 ); \
1808 \
1809 if ( ret > n ) { \
1810 p[n - 1] = '\0'; \
1811 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
1812 } \
1813 \
1814 n -= ret; \
1815 p += ret; \
1816}
1817
Paul Bakker5121ce52009-01-03 21:22:43 +00001818/*
1819 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00001820 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00001821 */
Paul Bakkerd98030e2009-05-02 15:13:40 +00001822int x509parse_dn_gets( char *buf, size_t size, x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00001823{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001824 int i, ret, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00001825 unsigned char c;
1826 x509_name *name;
1827 char s[128], *p;
1828
1829 memset( s, 0, sizeof( s ) );
1830
1831 name = dn;
1832 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001833 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00001834
1835 while( name != NULL )
1836 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001837 if( name != dn ) {
1838 ret = snprintf( p, n, ", " );
1839 SAFE_SNPRINTF();
1840 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001841
1842 if( memcmp( name->oid.p, OID_X520, 2 ) == 0 )
1843 {
1844 switch( name->oid.p[2] )
1845 {
1846 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001847 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001848
1849 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001850 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001851
1852 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001853 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001854
1855 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001856 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001857
1858 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001859 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001860
1861 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001862 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001863
1864 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001865 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00001866 name->oid.p[2] );
1867 break;
1868 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001869 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001870 }
1871 else if( memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
1872 {
1873 switch( name->oid.p[8] )
1874 {
1875 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001876 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001877
1878 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001879 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00001880 name->oid.p[8] );
1881 break;
1882 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001883 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001884 }
1885 else
Paul Bakkerd98030e2009-05-02 15:13:40 +00001886 {
1887 ret = snprintf( p, n, "\?\?=" );
1888 SAFE_SNPRINTF();
1889 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001890
1891 for( i = 0; i < name->val.len; i++ )
1892 {
1893 if( i >= (int) sizeof( s ) - 1 )
1894 break;
1895
1896 c = name->val.p[i];
1897 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
1898 s[i] = '?';
1899 else s[i] = c;
1900 }
1901 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00001902 ret = snprintf( p, n, "%s", s );
1903 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001904 name = name->next;
1905 }
1906
Paul Bakkerd98030e2009-05-02 15:13:40 +00001907 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001908}
1909
1910/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001911 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00001912 */
Paul Bakkerd98030e2009-05-02 15:13:40 +00001913int x509parse_cert_info( char *buf, size_t size, char *prefix, x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00001914{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001915 int i, n, nr, ret;
1916 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00001917
1918 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001919 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00001920
Paul Bakkerd98030e2009-05-02 15:13:40 +00001921 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00001922 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001923 SAFE_SNPRINTF();
1924 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00001925 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001926 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001927
Paul Bakkerd98030e2009-05-02 15:13:40 +00001928 nr = ( crt->serial.len <= 32 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001929 ? crt->serial.len : 32;
1930
Paul Bakkerd98030e2009-05-02 15:13:40 +00001931 for( i = 0; i < nr; i++ )
1932 {
1933 ret = snprintf( p, n, "%02X%s",
1934 crt->serial.p[i], ( i < nr - 1 ) ? ":" : "" );
1935 SAFE_SNPRINTF();
1936 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001937
Paul Bakkerd98030e2009-05-02 15:13:40 +00001938 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
1939 SAFE_SNPRINTF();
1940 ret = x509parse_dn_gets( p, n, &crt->issuer );
1941 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001942
Paul Bakkerd98030e2009-05-02 15:13:40 +00001943 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
1944 SAFE_SNPRINTF();
1945 ret = x509parse_dn_gets( p, n, &crt->subject );
1946 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001947
Paul Bakkerd98030e2009-05-02 15:13:40 +00001948 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00001949 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1950 crt->valid_from.year, crt->valid_from.mon,
1951 crt->valid_from.day, crt->valid_from.hour,
1952 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001953 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001954
Paul Bakkerd98030e2009-05-02 15:13:40 +00001955 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00001956 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1957 crt->valid_to.year, crt->valid_to.mon,
1958 crt->valid_to.day, crt->valid_to.hour,
1959 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001960 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001961
Paul Bakkerd98030e2009-05-02 15:13:40 +00001962 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
1963 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001964
1965 switch( crt->sig_oid1.p[8] )
1966 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001967 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
1968 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
1969 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
1970 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
1971 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
1972 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
1973 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
1974 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
1975 default: ret = snprintf( p, n, "???" ); break;
1976 }
1977 SAFE_SNPRINTF();
1978
1979 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
1980 crt->rsa.N.n * (int) sizeof( unsigned long ) * 8 );
1981 SAFE_SNPRINTF();
1982
1983 return( size - n );
1984}
1985
1986/*
1987 * Return an informational string about the CRL.
1988 */
1989int x509parse_crl_info( char *buf, size_t size, char *prefix, x509_crl *crl )
1990{
1991 int i, n, nr, ret;
1992 char *p;
1993 x509_crl_entry *entry;
1994
1995 p = buf;
1996 n = size;
1997
1998 ret = snprintf( p, n, "%sCRL version : %d",
1999 prefix, crl->version );
2000 SAFE_SNPRINTF();
2001
2002 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2003 SAFE_SNPRINTF();
2004 ret = x509parse_dn_gets( p, n, &crl->issuer );
2005 SAFE_SNPRINTF();
2006
2007 ret = snprintf( p, n, "\n%sthis update : " \
2008 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2009 crl->this_update.year, crl->this_update.mon,
2010 crl->this_update.day, crl->this_update.hour,
2011 crl->this_update.min, crl->this_update.sec );
2012 SAFE_SNPRINTF();
2013
2014 ret = snprintf( p, n, "\n%snext update : " \
2015 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2016 crl->next_update.year, crl->next_update.mon,
2017 crl->next_update.day, crl->next_update.hour,
2018 crl->next_update.min, crl->next_update.sec );
2019 SAFE_SNPRINTF();
2020
2021 entry = &crl->entry;
2022
2023 ret = snprintf( p, n, "\n%sRevoked certificates:",
2024 prefix );
2025 SAFE_SNPRINTF();
2026
Paul Bakker9be19372009-07-27 20:21:53 +00002027 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002028 {
2029 ret = snprintf( p, n, "\n%sserial number: ",
2030 prefix );
2031 SAFE_SNPRINTF();
2032
2033 nr = ( entry->serial.len <= 32 )
2034 ? entry->serial.len : 32;
2035
2036 for( i = 0; i < nr; i++ ) {
2037 ret = snprintf( p, n, "%02X%s",
2038 entry->serial.p[i], ( i < nr - 1 ) ? ":" : "" );
2039 SAFE_SNPRINTF();
2040 }
2041
2042 ret = snprintf( p, n, " revocation date: " \
2043 "%04d-%02d-%02d %02d:%02d:%02d",
2044 entry->revocation_date.year, entry->revocation_date.mon,
2045 entry->revocation_date.day, entry->revocation_date.hour,
2046 entry->revocation_date.min, entry->revocation_date.sec );
2047 SAFE_SNPRINTF();
2048
2049 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002050 }
2051
Paul Bakkerd98030e2009-05-02 15:13:40 +00002052 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2053 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002054
Paul Bakkerd98030e2009-05-02 15:13:40 +00002055 switch( crl->sig_oid1.p[8] )
2056 {
2057 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2058 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2059 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2060 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2061 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2062 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2063 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2064 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2065 default: ret = snprintf( p, n, "???" ); break;
2066 }
2067 SAFE_SNPRINTF();
2068
Paul Bakker1e27bb22009-07-19 20:25:25 +00002069 ret = snprintf( p, n, "\n" );
2070 SAFE_SNPRINTF();
2071
Paul Bakkerd98030e2009-05-02 15:13:40 +00002072 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002073}
2074
2075/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00002076 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00002077 */
Paul Bakker40ea7de2009-05-03 10:18:48 +00002078int x509parse_time_expired( x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00002079{
2080 struct tm *lt;
2081 time_t tt;
2082
2083 tt = time( NULL );
2084 lt = localtime( &tt );
2085
Paul Bakker40ea7de2009-05-03 10:18:48 +00002086 if( lt->tm_year > to->year - 1900 )
2087 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002088
Paul Bakker40ea7de2009-05-03 10:18:48 +00002089 if( lt->tm_year == to->year - 1900 &&
2090 lt->tm_mon > to->mon - 1 )
2091 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002092
Paul Bakker40ea7de2009-05-03 10:18:48 +00002093 if( lt->tm_year == to->year - 1900 &&
2094 lt->tm_mon == to->mon - 1 &&
2095 lt->tm_mday > to->day )
2096 return( 1 );
2097
2098 return( 0 );
2099}
2100
2101/*
2102 * Return 1 if the certificate is revoked, or 0 otherwise.
2103 */
2104int x509parse_revoked( x509_cert *crt, x509_crl *crl )
2105{
2106 x509_crl_entry *cur = &crl->entry;
2107
2108 while( cur != NULL && cur->serial.len != 0 )
2109 {
2110 if( memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
2111 {
2112 if( x509parse_time_expired( &cur->revocation_date ) )
2113 return( 1 );
2114 }
2115
2116 cur = cur->next;
2117 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002118
2119 return( 0 );
2120}
2121
2122static void x509_hash( unsigned char *in, int len, int alg,
2123 unsigned char *out )
2124{
2125 switch( alg )
2126 {
Paul Bakker40e46942009-01-03 21:51:57 +00002127#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002128 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002129#endif
Paul Bakker40e46942009-01-03 21:51:57 +00002130#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002131 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002132#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00002133 case SIG_RSA_MD5 : md5( in, len, out ); break;
2134 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
2135#if defined(POLARSSL_SHA2_C)
2136 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
2137 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
2138#endif
2139#if defined(POLARSSL_SHA2_C)
2140 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
2141 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
2142#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002143 default:
2144 memset( out, '\xFF', len );
2145 break;
2146 }
2147}
2148
2149/*
2150 * Verify the certificate validity
2151 */
2152int x509parse_verify( x509_cert *crt,
2153 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00002154 x509_crl *ca_crl,
Paul Bakker5121ce52009-01-03 21:22:43 +00002155 char *cn, int *flags )
2156{
2157 int cn_len;
2158 int hash_id;
2159 int pathlen;
2160 x509_cert *cur;
2161 x509_name *name;
Paul Bakker4593aea2009-02-09 22:32:35 +00002162 unsigned char hash[64];
Paul Bakker5121ce52009-01-03 21:22:43 +00002163
Paul Bakker40ea7de2009-05-03 10:18:48 +00002164 *flags = 0;
2165
2166 if( x509parse_time_expired( &crt->valid_to ) )
2167 *flags = BADCERT_EXPIRED;
Paul Bakker5121ce52009-01-03 21:22:43 +00002168
2169 if( cn != NULL )
2170 {
2171 name = &crt->subject;
2172 cn_len = strlen( cn );
2173
2174 while( name != NULL )
2175 {
2176 if( memcmp( name->oid.p, OID_CN, 3 ) == 0 &&
2177 memcmp( name->val.p, cn, cn_len ) == 0 &&
2178 name->val.len == cn_len )
2179 break;
2180
2181 name = name->next;
2182 }
2183
2184 if( name == NULL )
2185 *flags |= BADCERT_CN_MISMATCH;
2186 }
2187
2188 *flags |= BADCERT_NOT_TRUSTED;
2189
2190 /*
2191 * Iterate upwards in the given cert chain,
2192 * ignoring any upper cert with CA != TRUE.
2193 */
2194 cur = crt->next;
2195
2196 pathlen = 1;
2197
Paul Bakker7c6d4a42009-03-28 20:35:47 +00002198 while( cur != NULL && cur->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002199 {
2200 if( cur->ca_istrue == 0 ||
2201 crt->issuer_raw.len != cur->subject_raw.len ||
2202 memcmp( crt->issuer_raw.p, cur->subject_raw.p,
2203 crt->issuer_raw.len ) != 0 )
2204 {
2205 cur = cur->next;
2206 continue;
2207 }
2208
2209 hash_id = crt->sig_oid1.p[8];
2210
2211 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2212
2213 if( rsa_pkcs1_verify( &cur->rsa, RSA_PUBLIC, hash_id,
2214 0, hash, crt->sig.p ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00002215 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002216
2217 pathlen++;
2218
2219 crt = cur;
2220 cur = crt->next;
2221 }
2222
2223 /*
2224 * Atempt to validate topmost cert with our CA chain.
2225 */
Paul Bakker7c6d4a42009-03-28 20:35:47 +00002226 while( trust_ca != NULL && trust_ca->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002227 {
2228 if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
2229 memcmp( crt->issuer_raw.p, trust_ca->subject_raw.p,
2230 crt->issuer_raw.len ) != 0 )
2231 {
2232 trust_ca = trust_ca->next;
2233 continue;
2234 }
2235
2236 if( trust_ca->max_pathlen > 0 &&
2237 trust_ca->max_pathlen < pathlen )
2238 break;
2239
2240 hash_id = crt->sig_oid1.p[8];
2241
2242 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2243
2244 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
2245 0, hash, crt->sig.p ) == 0 )
2246 {
2247 /*
2248 * cert. is signed by a trusted CA
2249 */
2250 *flags &= ~BADCERT_NOT_TRUSTED;
2251 break;
2252 }
2253
2254 trust_ca = trust_ca->next;
2255 }
2256
Paul Bakker40ea7de2009-05-03 10:18:48 +00002257 /*
2258 * TODO: What happens if no CRL is present?
2259 * Suggestion: Revocation state should be unknown if no CRL is present.
2260 * For backwards compatibility this is not yet implemented.
2261 */
2262
2263 /*
2264 * Check if the topmost certificate is revoked if the trusted CA is
2265 * determined.
2266 */
2267 while( trust_ca != NULL && ca_crl != NULL && ca_crl->version != 0 )
2268 {
2269 if( ca_crl->issuer_raw.len != trust_ca->subject_raw.len ||
2270 memcmp( ca_crl->issuer_raw.p, trust_ca->subject_raw.p,
2271 ca_crl->issuer_raw.len ) != 0 )
2272 {
2273 ca_crl = ca_crl->next;
2274 continue;
2275 }
2276
2277 /*
2278 * Check if CRL is correctry signed by the trusted CA
2279 */
2280 hash_id = ca_crl->sig_oid1.p[8];
2281
2282 x509_hash( ca_crl->tbs.p, ca_crl->tbs.len, hash_id, hash );
2283
2284 if( !rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
2285 0, hash, ca_crl->sig.p ) == 0 )
2286 {
2287 /*
2288 * CRL is not trusted
2289 */
2290 *flags |= BADCRL_NOT_TRUSTED;
2291 break;
2292 }
2293
2294 /*
2295 * Check for validity of CRL (Do not drop out)
2296 */
2297 if( x509parse_time_expired( &ca_crl->next_update ) )
2298 *flags |= BADCRL_EXPIRED;
2299
2300 /*
2301 * Check if certificate is revoked
2302 */
2303 if( x509parse_revoked(crt, ca_crl) )
2304 {
2305 *flags |= BADCERT_REVOKED;
2306 break;
2307 }
2308
2309 ca_crl = ca_crl->next;
2310 }
2311
Paul Bakker5121ce52009-01-03 21:22:43 +00002312 if( *flags != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00002313 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002314
2315 return( 0 );
2316}
2317
2318/*
2319 * Unallocate all certificate data
2320 */
2321void x509_free( x509_cert *crt )
2322{
2323 x509_cert *cert_cur = crt;
2324 x509_cert *cert_prv;
2325 x509_name *name_cur;
2326 x509_name *name_prv;
2327
2328 if( crt == NULL )
2329 return;
2330
2331 do
2332 {
2333 rsa_free( &cert_cur->rsa );
2334
2335 name_cur = cert_cur->issuer.next;
2336 while( name_cur != NULL )
2337 {
2338 name_prv = name_cur;
2339 name_cur = name_cur->next;
2340 memset( name_prv, 0, sizeof( x509_name ) );
2341 free( name_prv );
2342 }
2343
2344 name_cur = cert_cur->subject.next;
2345 while( name_cur != NULL )
2346 {
2347 name_prv = name_cur;
2348 name_cur = name_cur->next;
2349 memset( name_prv, 0, sizeof( x509_name ) );
2350 free( name_prv );
2351 }
2352
2353 if( cert_cur->raw.p != NULL )
2354 {
2355 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
2356 free( cert_cur->raw.p );
2357 }
2358
2359 cert_cur = cert_cur->next;
2360 }
2361 while( cert_cur != NULL );
2362
2363 cert_cur = crt;
2364 do
2365 {
2366 cert_prv = cert_cur;
2367 cert_cur = cert_cur->next;
2368
2369 memset( cert_prv, 0, sizeof( x509_cert ) );
2370 if( cert_prv != crt )
2371 free( cert_prv );
2372 }
2373 while( cert_cur != NULL );
2374}
2375
Paul Bakkerd98030e2009-05-02 15:13:40 +00002376/*
2377 * Unallocate all CRL data
2378 */
2379void x509_crl_free( x509_crl *crl )
2380{
2381 x509_crl *crl_cur = crl;
2382 x509_crl *crl_prv;
2383 x509_name *name_cur;
2384 x509_name *name_prv;
2385 x509_crl_entry *entry_cur;
2386 x509_crl_entry *entry_prv;
2387
2388 if( crl == NULL )
2389 return;
2390
2391 do
2392 {
2393 name_cur = crl_cur->issuer.next;
2394 while( name_cur != NULL )
2395 {
2396 name_prv = name_cur;
2397 name_cur = name_cur->next;
2398 memset( name_prv, 0, sizeof( x509_name ) );
2399 free( name_prv );
2400 }
2401
2402 entry_cur = crl_cur->entry.next;
2403 while( entry_cur != NULL )
2404 {
2405 entry_prv = entry_cur;
2406 entry_cur = entry_cur->next;
2407 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
2408 free( entry_prv );
2409 }
2410
2411 if( crl_cur->raw.p != NULL )
2412 {
2413 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
2414 free( crl_cur->raw.p );
2415 }
2416
2417 crl_cur = crl_cur->next;
2418 }
2419 while( crl_cur != NULL );
2420
2421 crl_cur = crl;
2422 do
2423 {
2424 crl_prv = crl_cur;
2425 crl_cur = crl_cur->next;
2426
2427 memset( crl_prv, 0, sizeof( x509_crl ) );
2428 if( crl_prv != crl )
2429 free( crl_prv );
2430 }
2431 while( crl_cur != NULL );
2432}
2433
Paul Bakker40e46942009-01-03 21:51:57 +00002434#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002435
Paul Bakker40e46942009-01-03 21:51:57 +00002436#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00002437
2438/*
2439 * Checkup routine
2440 */
2441int x509_self_test( int verbose )
2442{
2443 int ret, i, j;
2444 x509_cert cacert;
2445 x509_cert clicert;
2446 rsa_context rsa;
2447
2448 if( verbose != 0 )
2449 printf( " X.509 certificate load: " );
2450
2451 memset( &clicert, 0, sizeof( x509_cert ) );
2452
2453 ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
2454 strlen( test_cli_crt ) );
2455 if( ret != 0 )
2456 {
2457 if( verbose != 0 )
2458 printf( "failed\n" );
2459
2460 return( ret );
2461 }
2462
2463 memset( &cacert, 0, sizeof( x509_cert ) );
2464
2465 ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
2466 strlen( test_ca_crt ) );
2467 if( ret != 0 )
2468 {
2469 if( verbose != 0 )
2470 printf( "failed\n" );
2471
2472 return( ret );
2473 }
2474
2475 if( verbose != 0 )
2476 printf( "passed\n X.509 private key load: " );
2477
2478 i = strlen( test_ca_key );
2479 j = strlen( test_ca_pwd );
2480
2481 if( ( ret = x509parse_key( &rsa,
2482 (unsigned char *) test_ca_key, i,
2483 (unsigned char *) test_ca_pwd, j ) ) != 0 )
2484 {
2485 if( verbose != 0 )
2486 printf( "failed\n" );
2487
2488 return( ret );
2489 }
2490
2491 if( verbose != 0 )
2492 printf( "passed\n X.509 signature verify: ");
2493
Paul Bakker1973e4c2009-07-10 22:32:40 +00002494 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &i );
Paul Bakker5121ce52009-01-03 21:22:43 +00002495 if( ret != 0 )
2496 {
2497 if( verbose != 0 )
2498 printf( "failed\n" );
2499
2500 return( ret );
2501 }
2502
2503 if( verbose != 0 )
2504 printf( "passed\n\n" );
2505
2506 x509_free( &cacert );
2507 x509_free( &clicert );
2508 rsa_free( &rsa );
2509
2510 return( 0 );
2511}
2512
2513#endif
2514
2515#endif