blob: 38824b0da0a7b1b74d92cfc17bd6e83a03e21d65 [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{
704 int ret;
705 x509_crl_entry *cur_entry = entry;
706
707 if( *p == end )
708 return( 0 );
709
710 entry->raw.tag = **p;
711
712 if( ( ret = asn1_get_tag( p, end, &entry->raw.len,
713 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
714 {
715 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
716 return( 0 );
717
718 return( ret );
719 }
720
721 entry->raw.p = *p;
722 end = *p + entry->raw.len;
723
724 while( *p < end )
725 {
726 int len2;
727
728 if( ( ret = asn1_get_tag( p, end, &len2,
729 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
730 {
731 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
732 return( 0 );
733
734 return( ret );
735 }
736
737 if( ( ret = x509_get_serial( p, end, &cur_entry->serial ) ) != 0 )
738 return( ret );
739
740 if( ( ret = x509_get_UTCTime( p, end, &cur_entry->revocation_date ) ) != 0 )
741 return( ret );
742
743 if( ( ret = x509_get_crl_ext( p, end, &cur_entry->entry_ext ) ) != 0 )
744 return( ret );
745
746 if ( *p < end ) {
747 cur_entry->next = malloc( sizeof( x509_crl_entry ) );
748 cur_entry = cur_entry->next;
749 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
750 }
751 }
752
753 return( 0 );
754}
755
756/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000757 * Parse one or more certificates and add them to the chained list
758 */
759int x509parse_crt( x509_cert *chain, unsigned char *buf, int buflen )
760{
761 int ret, len;
762 unsigned char *s1, *s2;
763 unsigned char *p, *end;
764 x509_cert *crt;
765
766 crt = chain;
767
Paul Bakker320a4b52009-03-28 18:52:39 +0000768 /*
769 * Check for valid input
770 */
771 if( crt == NULL || buf == NULL )
772 return( 1 );
773
Paul Bakkere9581d62009-03-28 20:29:25 +0000774 while( crt->version != 0 && crt->next != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +0000775 crt = crt->next;
776
777 /*
Paul Bakker320a4b52009-03-28 18:52:39 +0000778 * Add new certificate on the end of the chain if needed.
779 */
Paul Bakkere9581d62009-03-28 20:29:25 +0000780 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +0000781 {
782 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
783
Paul Bakker7d06ad22009-05-02 15:53:56 +0000784 if( crt->next == NULL )
785 {
Paul Bakker320a4b52009-03-28 18:52:39 +0000786 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +0000787 return( 1 );
788 }
Paul Bakker320a4b52009-03-28 18:52:39 +0000789
Paul Bakker7d06ad22009-05-02 15:53:56 +0000790 crt = crt->next;
791 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +0000792 }
793
794 /*
Paul Bakker5121ce52009-01-03 21:22:43 +0000795 * check if the certificate is encoded in base64
796 */
797 s1 = (unsigned char *) strstr( (char *) buf,
798 "-----BEGIN CERTIFICATE-----" );
799
800 if( s1 != NULL )
801 {
802 s2 = (unsigned char *) strstr( (char *) buf,
803 "-----END CERTIFICATE-----" );
804
805 if( s2 == NULL || s2 <= s1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000806 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +0000807
808 s1 += 27;
809 if( *s1 == '\r' ) s1++;
810 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +0000811 else return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +0000812
813 /*
814 * get the DER data length and decode the buffer
815 */
816 len = 0;
817 ret = base64_decode( NULL, &len, s1, s2 - s1 );
818
Paul Bakker40e46942009-01-03 21:51:57 +0000819 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
820 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000821
822 if( ( p = (unsigned char *) malloc( len ) ) == NULL )
823 return( 1 );
824
825 if( ( ret = base64_decode( p, &len, s1, s2 - s1 ) ) != 0 )
826 {
827 free( p );
Paul Bakker40e46942009-01-03 21:51:57 +0000828 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000829 }
830
831 /*
832 * update the buffer size and offset
833 */
834 s2 += 25;
835 if( *s2 == '\r' ) s2++;
836 if( *s2 == '\n' ) s2++;
837 else
838 {
839 free( p );
Paul Bakker40e46942009-01-03 21:51:57 +0000840 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +0000841 }
842
843 buflen -= s2 - buf;
844 buf = s2;
845 }
846 else
847 {
848 /*
849 * nope, copy the raw DER data
850 */
851 p = (unsigned char *) malloc( len = buflen );
852
853 if( p == NULL )
854 return( 1 );
855
856 memcpy( p, buf, buflen );
857
858 buflen = 0;
859 }
860
861 crt->raw.p = p;
862 crt->raw.len = len;
863 end = p + len;
864
865 /*
866 * Certificate ::= SEQUENCE {
867 * tbsCertificate TBSCertificate,
868 * signatureAlgorithm AlgorithmIdentifier,
869 * signatureValue BIT STRING }
870 */
871 if( ( ret = asn1_get_tag( &p, end, &len,
872 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
873 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000874 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000875 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +0000876 }
877
878 if( len != (int) ( end - p ) )
879 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000880 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000881 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
882 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000883 }
884
885 /*
886 * TBSCertificate ::= SEQUENCE {
887 */
888 crt->tbs.p = p;
889
890 if( ( ret = asn1_get_tag( &p, end, &len,
891 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
892 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000893 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000894 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000895 }
896
897 end = p + len;
898 crt->tbs.len = end - crt->tbs.p;
899
900 /*
901 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
902 *
903 * CertificateSerialNumber ::= INTEGER
904 *
905 * signature AlgorithmIdentifier
906 */
907 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
908 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
909 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
910 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000911 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +0000912 return( ret );
913 }
914
915 crt->version++;
916
917 if( crt->version > 3 )
918 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000919 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000920 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +0000921 }
922
923 if( crt->sig_oid1.len != 9 ||
924 memcmp( crt->sig_oid1.p, OID_PKCS1, 8 ) != 0 )
925 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000926 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000927 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000928 }
929
930 if( crt->sig_oid1.p[8] < 2 ||
Paul Bakker4593aea2009-02-09 22:32:35 +0000931 ( crt->sig_oid1.p[8] > 5 && crt->sig_oid1.p[8] < 11 ) ||
Paul Bakker7d06ad22009-05-02 15:53:56 +0000932 crt->sig_oid1.p[8] > 14 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000933 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000934 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000935 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000936 }
937
938 /*
939 * issuer Name
940 */
941 crt->issuer_raw.p = p;
942
943 if( ( ret = asn1_get_tag( &p, end, &len,
944 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
945 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000946 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000947 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000948 }
949
950 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
951 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000952 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +0000953 return( ret );
954 }
955
956 crt->issuer_raw.len = p - crt->issuer_raw.p;
957
958 /*
959 * Validity ::= SEQUENCE {
960 * notBefore Time,
961 * notAfter Time }
962 *
963 */
964 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
965 &crt->valid_to ) ) != 0 )
966 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000967 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +0000968 return( ret );
969 }
970
971 /*
972 * subject Name
973 */
974 crt->subject_raw.p = p;
975
976 if( ( ret = asn1_get_tag( &p, end, &len,
977 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
978 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000979 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000980 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000981 }
982
983 if( ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
984 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000985 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +0000986 return( ret );
987 }
988
989 crt->subject_raw.len = p - crt->subject_raw.p;
990
991 /*
992 * SubjectPublicKeyInfo ::= SEQUENCE
993 * algorithm AlgorithmIdentifier,
994 * subjectPublicKey BIT STRING }
995 */
996 if( ( ret = asn1_get_tag( &p, end, &len,
997 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
998 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000999 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001000 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001001 }
1002
1003 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1004 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1005 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001006 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001007 return( ret );
1008 }
1009
1010 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1011 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001012 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001013 return( ret );
1014 }
1015
1016 crt->rsa.len = mpi_size( &crt->rsa.N );
1017
1018 /*
1019 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1020 * -- If present, version shall be v2 or v3
1021 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1022 * -- If present, version shall be v2 or v3
1023 * extensions [3] EXPLICIT Extensions OPTIONAL
1024 * -- If present, version shall be v3
1025 */
1026 if( crt->version == 2 || crt->version == 3 )
1027 {
1028 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1029 if( ret != 0 )
1030 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001031 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001032 return( ret );
1033 }
1034 }
1035
1036 if( crt->version == 2 || crt->version == 3 )
1037 {
1038 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1039 if( ret != 0 )
1040 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001041 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001042 return( ret );
1043 }
1044 }
1045
1046 if( crt->version == 3 )
1047 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001048 ret = x509_get_crt_ext( &p, end, &crt->v3_ext,
Paul Bakker5121ce52009-01-03 21:22:43 +00001049 &crt->ca_istrue, &crt->max_pathlen );
1050 if( ret != 0 )
1051 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001052 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001053 return( ret );
1054 }
1055 }
1056
1057 if( p != end )
1058 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001059 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001060 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1061 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001062 }
1063
1064 end = crt->raw.p + crt->raw.len;
1065
1066 /*
1067 * signatureAlgorithm AlgorithmIdentifier,
1068 * signatureValue BIT STRING
1069 */
1070 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1071 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001072 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001073 return( ret );
1074 }
1075
Paul Bakker320a4b52009-03-28 18:52:39 +00001076 if( memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001077 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001078 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001079 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001080 }
1081
1082 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1083 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001084 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001085 return( ret );
1086 }
1087
1088 if( p != end )
1089 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001090 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001091 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1092 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001093 }
1094
Paul Bakker5121ce52009-01-03 21:22:43 +00001095 if( buflen > 0 )
Paul Bakker320a4b52009-03-28 18:52:39 +00001096 {
1097 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1098
Paul Bakker7d06ad22009-05-02 15:53:56 +00001099 if( crt->next == NULL )
1100 {
Paul Bakker320a4b52009-03-28 18:52:39 +00001101 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001102 return( 1 );
1103 }
Paul Bakker320a4b52009-03-28 18:52:39 +00001104
Paul Bakker7d06ad22009-05-02 15:53:56 +00001105 crt = crt->next;
1106 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001107
Paul Bakker5121ce52009-01-03 21:22:43 +00001108 return( x509parse_crt( crt, buf, buflen ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001109 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001110
1111 return( 0 );
1112}
1113
1114/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001115 * Parse one or more CRLs and add them to the chained list
1116 */
1117int x509parse_crl( x509_crl *chain, unsigned char *buf, int buflen )
1118{
1119 int ret, len;
1120 unsigned char *s1, *s2;
1121 unsigned char *p, *end;
1122 x509_crl *crl;
1123
1124 crl = chain;
1125
1126 /*
1127 * Check for valid input
1128 */
1129 if( crl == NULL || buf == NULL )
1130 return( 1 );
1131
1132 while( crl->version != 0 && crl->next != NULL )
1133 crl = crl->next;
1134
1135 /*
1136 * Add new CRL on the end of the chain if needed.
1137 */
1138 if ( crl->version != 0 && crl->next == NULL)
1139 {
1140 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1141
Paul Bakker7d06ad22009-05-02 15:53:56 +00001142 if( crl->next == NULL )
1143 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001144 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001145 return( 1 );
1146 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001147
Paul Bakker7d06ad22009-05-02 15:53:56 +00001148 crl = crl->next;
1149 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001150 }
1151
1152 /*
1153 * check if the CRL is encoded in base64
1154 */
1155 s1 = (unsigned char *) strstr( (char *) buf,
1156 "-----BEGIN X509 CRL-----" );
1157
1158 if( s1 != NULL )
1159 {
1160 s2 = (unsigned char *) strstr( (char *) buf,
1161 "-----END X509 CRL-----" );
1162
1163 if( s2 == NULL || s2 <= s1 )
1164 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1165
1166 s1 += 24;
1167 if( *s1 == '\r' ) s1++;
1168 if( *s1 == '\n' ) s1++;
1169 else return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1170
1171 /*
1172 * get the DER data length and decode the buffer
1173 */
1174 len = 0;
1175 ret = base64_decode( NULL, &len, s1, s2 - s1 );
1176
1177 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
1178 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
1179
1180 if( ( p = (unsigned char *) malloc( len ) ) == NULL )
1181 return( 1 );
1182
1183 if( ( ret = base64_decode( p, &len, s1, s2 - s1 ) ) != 0 )
1184 {
1185 free( p );
1186 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
1187 }
1188
1189 /*
1190 * update the buffer size and offset
1191 */
1192 s2 += 22;
1193 if( *s2 == '\r' ) s2++;
1194 if( *s2 == '\n' ) s2++;
1195 else
1196 {
1197 free( p );
1198 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1199 }
1200
1201 buflen -= s2 - buf;
1202 buf = s2;
1203 }
1204 else
1205 {
1206 /*
1207 * nope, copy the raw DER data
1208 */
1209 p = (unsigned char *) malloc( len = buflen );
1210
1211 if( p == NULL )
1212 return( 1 );
1213
1214 memcpy( p, buf, buflen );
1215
1216 buflen = 0;
1217 }
1218
1219 crl->raw.p = p;
1220 crl->raw.len = len;
1221 end = p + len;
1222
1223 /*
1224 * CertificateList ::= SEQUENCE {
1225 * tbsCertList TBSCertList,
1226 * signatureAlgorithm AlgorithmIdentifier,
1227 * signatureValue BIT STRING }
1228 */
1229 if( ( ret = asn1_get_tag( &p, end, &len,
1230 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1231 {
1232 x509_crl_free( crl );
1233 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1234 }
1235
1236 if( len != (int) ( end - p ) )
1237 {
1238 x509_crl_free( crl );
1239 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1240 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1241 }
1242
1243 /*
1244 * TBSCertList ::= SEQUENCE {
1245 */
1246 crl->tbs.p = p;
1247
1248 if( ( ret = asn1_get_tag( &p, end, &len,
1249 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1250 {
1251 x509_crl_free( crl );
1252 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
1253 }
1254
1255 end = p + len;
1256 crl->tbs.len = end - crl->tbs.p;
1257
1258 /*
1259 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1260 * -- if present, MUST be v2
1261 *
1262 * signature AlgorithmIdentifier
1263 */
1264 if( ( ret = x509_get_version( &p, end, &crl->version ) ) != 0 ||
1265 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1266 {
1267 x509_crl_free( crl );
1268 return( ret );
1269 }
1270
1271 crl->version++;
1272
1273 if( crl->version > 2 )
1274 {
1275 x509_crl_free( crl );
1276 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1277 }
1278
1279 if( crl->sig_oid1.len != 9 ||
1280 memcmp( crl->sig_oid1.p, OID_PKCS1, 8 ) != 0 )
1281 {
1282 x509_crl_free( crl );
1283 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1284 }
1285
1286 if( crl->sig_oid1.p[8] < 2 ||
1287 ( crl->sig_oid1.p[8] > 5 && crl->sig_oid1.p[8] < 11 ) ||
1288 crl->sig_oid1.p[8] > 14 )
1289 {
1290 x509_crl_free( crl );
1291 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1292 }
1293
1294 /*
1295 * issuer Name
1296 */
1297 crl->issuer_raw.p = p;
1298
1299 if( ( ret = asn1_get_tag( &p, end, &len,
1300 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1301 {
1302 x509_crl_free( crl );
1303 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
1304 }
1305
1306 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1307 {
1308 x509_crl_free( crl );
1309 return( ret );
1310 }
1311
1312 crl->issuer_raw.len = p - crl->issuer_raw.p;
1313
1314 /*
1315 * thisUpdate Time
1316 * nextUpdate Time OPTIONAL
1317 */
1318 if( ( ret = x509_get_UTCTime( &p, end, &crl->this_update ) ) != 0 )
1319 {
1320 x509_crl_free( crl );
1321 return( ret );
1322 }
1323
1324 if( ( ret = x509_get_UTCTime( &p, end, &crl->next_update ) ) != 0 )
1325 {
1326 if ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) {
1327 x509_crl_free( crl );
1328 return( ret );
1329 }
1330 }
1331
1332 /*
1333 * revokedCertificates SEQUENCE OF SEQUENCE {
1334 * userCertificate CertificateSerialNumber,
1335 * revocationDate Time,
1336 * crlEntryExtensions Extensions OPTIONAL
1337 * -- if present, MUST be v2
1338 * } OPTIONAL
1339 */
1340 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1341 {
1342 x509_crl_free( crl );
1343 return( ret );
1344 }
1345
1346 /*
1347 * crlExtensions EXPLICIT Extensions OPTIONAL
1348 * -- if present, MUST be v2
1349 */
1350 if( crl->version == 2 )
1351 {
1352 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1353
1354 if( ret != 0 )
1355 {
1356 x509_crl_free( crl );
1357 return( ret );
1358 }
1359 }
1360
1361 if( p != end )
1362 {
1363 x509_crl_free( crl );
1364 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1365 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1366 }
1367
1368 end = crl->raw.p + crl->raw.len;
1369
1370 /*
1371 * signatureAlgorithm AlgorithmIdentifier,
1372 * signatureValue BIT STRING
1373 */
1374 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1375 {
1376 x509_crl_free( crl );
1377 return( ret );
1378 }
1379
1380 if( memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
1381 {
1382 x509_crl_free( crl );
1383 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1384 }
1385
1386 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1387 {
1388 x509_crl_free( crl );
1389 return( ret );
1390 }
1391
1392 if( p != end )
1393 {
1394 x509_crl_free( crl );
1395 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1396 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1397 }
1398
1399 if( buflen > 0 )
1400 {
1401 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1402
Paul Bakker7d06ad22009-05-02 15:53:56 +00001403 if( crl->next == NULL )
1404 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001405 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001406 return( 1 );
1407 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001408
Paul Bakker7d06ad22009-05-02 15:53:56 +00001409 crl = crl->next;
1410 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001411
1412 return( x509parse_crl( crl, buf, buflen ) );
1413 }
1414
1415 return( 0 );
1416}
1417
1418/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001419 * Load all data from a file into a given buffer.
1420 */
1421int load_file( char *path, unsigned char **buf, size_t *n )
1422{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001423 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001424
Paul Bakkerd98030e2009-05-02 15:13:40 +00001425 if( ( f = fopen( path, "rb" ) ) == NULL )
1426 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001427
Paul Bakkerd98030e2009-05-02 15:13:40 +00001428 fseek( f, 0, SEEK_END );
1429 *n = (size_t) ftell( f );
1430 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001431
Paul Bakkerd98030e2009-05-02 15:13:40 +00001432 if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
1433 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001434
Paul Bakkerd98030e2009-05-02 15:13:40 +00001435 if( fread( *buf, 1, *n, f ) != *n )
1436 {
1437 fclose( f );
1438 free( *buf );
1439 return( 1 );
1440 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001441
Paul Bakkerd98030e2009-05-02 15:13:40 +00001442 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001443
Paul Bakkerd98030e2009-05-02 15:13:40 +00001444 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001445
Paul Bakkerd98030e2009-05-02 15:13:40 +00001446 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001447}
1448
1449/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001450 * Load one or more certificates and add them to the chained list
1451 */
1452int x509parse_crtfile( x509_cert *chain, char *path )
1453{
1454 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001455 size_t n;
1456 unsigned char *buf;
1457
Paul Bakker2b245eb2009-04-19 18:44:26 +00001458 if ( load_file( path, &buf, &n ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001459 return( 1 );
1460
Paul Bakker5121ce52009-01-03 21:22:43 +00001461 ret = x509parse_crt( chain, buf, (int) n );
1462
1463 memset( buf, 0, n + 1 );
1464 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001465
1466 return( ret );
1467}
1468
Paul Bakkerd98030e2009-05-02 15:13:40 +00001469/*
1470 * Load one or more CRLs and add them to the chained list
1471 */
1472int x509parse_crlfile( x509_crl *chain, char *path )
1473{
1474 int ret;
1475 size_t n;
1476 unsigned char *buf;
1477
1478 if ( load_file( path, &buf, &n ) )
1479 return( 1 );
1480
1481 ret = x509parse_crl( chain, buf, (int) n );
1482
1483 memset( buf, 0, n + 1 );
1484 free( buf );
1485
1486 return( ret );
1487}
1488
Paul Bakker40e46942009-01-03 21:51:57 +00001489#if defined(POLARSSL_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001490/*
1491 * Read a 16-byte hex string and convert it to binary
1492 */
1493static int x509_get_iv( unsigned char *s, unsigned char iv[8] )
1494{
1495 int i, j, k;
1496
1497 memset( iv, 0, 8 );
1498
1499 for( i = 0; i < 16; i++, s++ )
1500 {
1501 if( *s >= '0' && *s <= '9' ) j = *s - '0'; else
1502 if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else
1503 if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else
Paul Bakker40e46942009-01-03 21:51:57 +00001504 return( POLARSSL_ERR_X509_KEY_INVALID_ENC_IV );
Paul Bakker5121ce52009-01-03 21:22:43 +00001505
1506 k = ( ( i & 1 ) != 0 ) ? j : j << 4;
1507
1508 iv[i >> 1] = (unsigned char)( iv[i >> 1] | k );
1509 }
1510
1511 return( 0 );
1512}
1513
1514/*
1515 * Decrypt with 3DES-CBC, using PBKDF1 for key derivation
1516 */
1517static void x509_des3_decrypt( unsigned char des3_iv[8],
1518 unsigned char *buf, int buflen,
1519 unsigned char *pwd, int pwdlen )
1520{
1521 md5_context md5_ctx;
1522 des3_context des3_ctx;
1523 unsigned char md5sum[16];
1524 unsigned char des3_key[24];
1525
1526 /*
1527 * 3DES key[ 0..15] = MD5(pwd || IV)
1528 * key[16..23] = MD5(pwd || IV || 3DES key[ 0..15])
1529 */
1530 md5_starts( &md5_ctx );
1531 md5_update( &md5_ctx, pwd, pwdlen );
1532 md5_update( &md5_ctx, des3_iv, 8 );
1533 md5_finish( &md5_ctx, md5sum );
1534 memcpy( des3_key, md5sum, 16 );
1535
1536 md5_starts( &md5_ctx );
1537 md5_update( &md5_ctx, md5sum, 16 );
1538 md5_update( &md5_ctx, pwd, pwdlen );
1539 md5_update( &md5_ctx, des3_iv, 8 );
1540 md5_finish( &md5_ctx, md5sum );
1541 memcpy( des3_key + 16, md5sum, 8 );
1542
1543 des3_set3key_dec( &des3_ctx, des3_key );
1544 des3_crypt_cbc( &des3_ctx, DES_DECRYPT, buflen,
1545 des3_iv, buf, buf );
1546
1547 memset( &md5_ctx, 0, sizeof( md5_ctx ) );
1548 memset( &des3_ctx, 0, sizeof( des3_ctx ) );
1549 memset( md5sum, 0, 16 );
1550 memset( des3_key, 0, 24 );
1551}
1552#endif
1553
1554/*
1555 * Parse a private RSA key
1556 */
1557int x509parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
1558 unsigned char *pwd, int pwdlen )
1559{
1560 int ret, len, enc;
1561 unsigned char *s1, *s2;
1562 unsigned char *p, *end;
1563 unsigned char des3_iv[8];
1564
1565 s1 = (unsigned char *) strstr( (char *) buf,
1566 "-----BEGIN RSA PRIVATE KEY-----" );
1567
1568 if( s1 != NULL )
1569 {
1570 s2 = (unsigned char *) strstr( (char *) buf,
1571 "-----END RSA PRIVATE KEY-----" );
1572
1573 if( s2 == NULL || s2 <= s1 )
Paul Bakker40e46942009-01-03 21:51:57 +00001574 return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001575
1576 s1 += 31;
1577 if( *s1 == '\r' ) s1++;
1578 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001579 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001580
1581 enc = 0;
1582
1583 if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
1584 {
Paul Bakker40e46942009-01-03 21:51:57 +00001585#if defined(POLARSSL_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001586 enc++;
1587
1588 s1 += 22;
1589 if( *s1 == '\r' ) s1++;
1590 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001591 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001592
1593 if( memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001594 return( POLARSSL_ERR_X509_KEY_UNKNOWN_ENC_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +00001595
1596 s1 += 23;
1597 if( x509_get_iv( s1, des3_iv ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001598 return( POLARSSL_ERR_X509_KEY_INVALID_ENC_IV );
Paul Bakker5121ce52009-01-03 21:22:43 +00001599
1600 s1 += 16;
1601 if( *s1 == '\r' ) s1++;
1602 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001603 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001604#else
Paul Bakker40e46942009-01-03 21:51:57 +00001605 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001606#endif
1607 }
1608
1609 len = 0;
1610 ret = base64_decode( NULL, &len, s1, s2 - s1 );
1611
Paul Bakker40e46942009-01-03 21:51:57 +00001612 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
1613 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001614
1615 if( ( buf = (unsigned char *) malloc( len ) ) == NULL )
1616 return( 1 );
1617
1618 if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
1619 {
1620 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001621 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001622 }
1623
1624 buflen = len;
1625
1626 if( enc != 0 )
1627 {
Paul Bakker40e46942009-01-03 21:51:57 +00001628#if defined(POLARSSL_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001629 if( pwd == NULL )
1630 {
1631 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001632 return( POLARSSL_ERR_X509_KEY_PASSWORD_REQUIRED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001633 }
1634
1635 x509_des3_decrypt( des3_iv, buf, buflen, pwd, pwdlen );
1636
1637 if( buf[0] != 0x30 || buf[1] != 0x82 ||
1638 buf[4] != 0x02 || buf[5] != 0x01 )
1639 {
1640 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001641 return( POLARSSL_ERR_X509_KEY_PASSWORD_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001642 }
1643#else
Paul Bakker40e46942009-01-03 21:51:57 +00001644 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001645#endif
1646 }
1647 }
1648
1649 memset( rsa, 0, sizeof( rsa_context ) );
1650
1651 p = buf;
1652 end = buf + buflen;
1653
1654 /*
1655 * RSAPrivateKey ::= SEQUENCE {
1656 * version Version,
1657 * modulus INTEGER, -- n
1658 * publicExponent INTEGER, -- e
1659 * privateExponent INTEGER, -- d
1660 * prime1 INTEGER, -- p
1661 * prime2 INTEGER, -- q
1662 * exponent1 INTEGER, -- d mod (p-1)
1663 * exponent2 INTEGER, -- d mod (q-1)
1664 * coefficient INTEGER, -- (inverse of q) mod p
1665 * otherPrimeInfos OtherPrimeInfos OPTIONAL
1666 * }
1667 */
1668 if( ( ret = asn1_get_tag( &p, end, &len,
1669 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1670 {
1671 if( s1 != NULL )
1672 free( buf );
1673
1674 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001675 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001676 }
1677
1678 end = p + len;
1679
1680 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
1681 {
1682 if( s1 != NULL )
1683 free( buf );
1684
1685 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001686 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001687 }
1688
1689 if( rsa->ver != 0 )
1690 {
1691 if( s1 != NULL )
1692 free( buf );
1693
1694 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001695 return( ret | POLARSSL_ERR_X509_KEY_INVALID_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001696 }
1697
1698 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
1699 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
1700 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
1701 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
1702 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
1703 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
1704 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
1705 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
1706 {
1707 if( s1 != NULL )
1708 free( buf );
1709
1710 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001711 return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001712 }
1713
1714 rsa->len = mpi_size( &rsa->N );
1715
1716 if( p != end )
1717 {
1718 if( s1 != NULL )
1719 free( buf );
1720
1721 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001722 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT |
1723 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001724 }
1725
1726 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
1727 {
1728 if( s1 != NULL )
1729 free( buf );
1730
1731 rsa_free( rsa );
1732 return( ret );
1733 }
1734
1735 if( s1 != NULL )
1736 free( buf );
1737
1738 return( 0 );
1739}
1740
1741/*
1742 * Load and parse a private RSA key
1743 */
1744int x509parse_keyfile( rsa_context *rsa, char *path, char *pwd )
1745{
1746 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001747 size_t n;
1748 unsigned char *buf;
1749
Paul Bakker2b245eb2009-04-19 18:44:26 +00001750 if ( load_file( path, &buf, &n ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001751 return( 1 );
1752
Paul Bakker5121ce52009-01-03 21:22:43 +00001753 if( pwd == NULL )
1754 ret = x509parse_key( rsa, buf, (int) n, NULL, 0 );
1755 else
1756 ret = x509parse_key( rsa, buf, (int) n,
1757 (unsigned char *) pwd, strlen( pwd ) );
1758
1759 memset( buf, 0, n + 1 );
1760 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001761
1762 return( ret );
1763}
1764
1765#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00001766#include <stdarg.h>
1767
1768#if !defined vsnprintf
1769#define vsnprintf _vsnprintf
1770#endif // vsnprintf
1771
1772/*
1773 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
1774 * Result value is not size of buffer needed, but -1 if no fit is possible.
1775 *
1776 * This fuction tries to 'fix' this by at least suggesting enlarging the
1777 * size by 20.
1778 */
1779int compat_snprintf(char *str, size_t size, const char *format, ...)
1780{
1781 va_list ap;
1782 int res = -1;
1783
1784 va_start( ap, format );
1785
1786 res = vsnprintf( str, size, format, ap );
1787
1788 va_end( ap );
1789
1790 // No quick fix possible
1791 if ( res < 0 )
1792 return( size + 20 );
1793
1794 return res;
1795}
1796
1797#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00001798#endif
1799
Paul Bakkerd98030e2009-05-02 15:13:40 +00001800#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
1801
1802#define SAFE_SNPRINTF() \
1803{ \
1804 if( ret == -1 ) \
1805 return( -1 ); \
1806 \
1807 if ( ret > n ) { \
1808 p[n - 1] = '\0'; \
1809 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
1810 } \
1811 \
1812 n -= ret; \
1813 p += ret; \
1814}
1815
Paul Bakker5121ce52009-01-03 21:22:43 +00001816/*
1817 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00001818 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00001819 */
Paul Bakkerd98030e2009-05-02 15:13:40 +00001820int x509parse_dn_gets( char *buf, size_t size, x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00001821{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001822 int i, ret, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00001823 unsigned char c;
1824 x509_name *name;
1825 char s[128], *p;
1826
1827 memset( s, 0, sizeof( s ) );
1828
1829 name = dn;
1830 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001831 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00001832
1833 while( name != NULL )
1834 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001835 if( name != dn ) {
1836 ret = snprintf( p, n, ", " );
1837 SAFE_SNPRINTF();
1838 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001839
1840 if( memcmp( name->oid.p, OID_X520, 2 ) == 0 )
1841 {
1842 switch( name->oid.p[2] )
1843 {
1844 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001845 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001846
1847 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001848 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001849
1850 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001851 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001852
1853 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001854 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001855
1856 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001857 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001858
1859 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001860 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001861
1862 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001863 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00001864 name->oid.p[2] );
1865 break;
1866 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001867 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001868 }
1869 else if( memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
1870 {
1871 switch( name->oid.p[8] )
1872 {
1873 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001874 ret = snprintf( p, n, "emailAddress=" ); 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[8] );
1879 break;
1880 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001881 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001882 }
1883 else
Paul Bakkerd98030e2009-05-02 15:13:40 +00001884 {
1885 ret = snprintf( p, n, "\?\?=" );
1886 SAFE_SNPRINTF();
1887 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001888
1889 for( i = 0; i < name->val.len; i++ )
1890 {
1891 if( i >= (int) sizeof( s ) - 1 )
1892 break;
1893
1894 c = name->val.p[i];
1895 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
1896 s[i] = '?';
1897 else s[i] = c;
1898 }
1899 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00001900 ret = snprintf( p, n, "%s", s );
1901 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001902 name = name->next;
1903 }
1904
Paul Bakkerd98030e2009-05-02 15:13:40 +00001905 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001906}
1907
1908/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001909 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00001910 */
Paul Bakkerd98030e2009-05-02 15:13:40 +00001911int x509parse_cert_info( char *buf, size_t size, char *prefix, x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00001912{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001913 int i, n, nr, ret;
1914 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00001915
1916 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001917 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00001918
Paul Bakkerd98030e2009-05-02 15:13:40 +00001919 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00001920 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001921 SAFE_SNPRINTF();
1922 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00001923 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001924 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001925
Paul Bakkerd98030e2009-05-02 15:13:40 +00001926 nr = ( crt->serial.len <= 32 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001927 ? crt->serial.len : 32;
1928
Paul Bakkerd98030e2009-05-02 15:13:40 +00001929 for( i = 0; i < nr; i++ )
1930 {
1931 ret = snprintf( p, n, "%02X%s",
1932 crt->serial.p[i], ( i < nr - 1 ) ? ":" : "" );
1933 SAFE_SNPRINTF();
1934 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001935
Paul Bakkerd98030e2009-05-02 15:13:40 +00001936 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
1937 SAFE_SNPRINTF();
1938 ret = x509parse_dn_gets( p, n, &crt->issuer );
1939 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001940
Paul Bakkerd98030e2009-05-02 15:13:40 +00001941 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
1942 SAFE_SNPRINTF();
1943 ret = x509parse_dn_gets( p, n, &crt->subject );
1944 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001945
Paul Bakkerd98030e2009-05-02 15:13:40 +00001946 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00001947 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1948 crt->valid_from.year, crt->valid_from.mon,
1949 crt->valid_from.day, crt->valid_from.hour,
1950 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001951 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001952
Paul Bakkerd98030e2009-05-02 15:13:40 +00001953 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00001954 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1955 crt->valid_to.year, crt->valid_to.mon,
1956 crt->valid_to.day, crt->valid_to.hour,
1957 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001958 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001959
Paul Bakkerd98030e2009-05-02 15:13:40 +00001960 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
1961 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001962
1963 switch( crt->sig_oid1.p[8] )
1964 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001965 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
1966 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
1967 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
1968 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
1969 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
1970 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
1971 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
1972 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
1973 default: ret = snprintf( p, n, "???" ); break;
1974 }
1975 SAFE_SNPRINTF();
1976
1977 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
1978 crt->rsa.N.n * (int) sizeof( unsigned long ) * 8 );
1979 SAFE_SNPRINTF();
1980
1981 return( size - n );
1982}
1983
1984/*
1985 * Return an informational string about the CRL.
1986 */
1987int x509parse_crl_info( char *buf, size_t size, char *prefix, x509_crl *crl )
1988{
1989 int i, n, nr, ret;
1990 char *p;
1991 x509_crl_entry *entry;
1992
1993 p = buf;
1994 n = size;
1995
1996 ret = snprintf( p, n, "%sCRL version : %d",
1997 prefix, crl->version );
1998 SAFE_SNPRINTF();
1999
2000 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2001 SAFE_SNPRINTF();
2002 ret = x509parse_dn_gets( p, n, &crl->issuer );
2003 SAFE_SNPRINTF();
2004
2005 ret = snprintf( p, n, "\n%sthis update : " \
2006 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2007 crl->this_update.year, crl->this_update.mon,
2008 crl->this_update.day, crl->this_update.hour,
2009 crl->this_update.min, crl->this_update.sec );
2010 SAFE_SNPRINTF();
2011
2012 ret = snprintf( p, n, "\n%snext update : " \
2013 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2014 crl->next_update.year, crl->next_update.mon,
2015 crl->next_update.day, crl->next_update.hour,
2016 crl->next_update.min, crl->next_update.sec );
2017 SAFE_SNPRINTF();
2018
2019 entry = &crl->entry;
2020
2021 ret = snprintf( p, n, "\n%sRevoked certificates:",
2022 prefix );
2023 SAFE_SNPRINTF();
2024
2025 while( entry != NULL )
2026 {
2027 ret = snprintf( p, n, "\n%sserial number: ",
2028 prefix );
2029 SAFE_SNPRINTF();
2030
2031 nr = ( entry->serial.len <= 32 )
2032 ? entry->serial.len : 32;
2033
2034 for( i = 0; i < nr; i++ ) {
2035 ret = snprintf( p, n, "%02X%s",
2036 entry->serial.p[i], ( i < nr - 1 ) ? ":" : "" );
2037 SAFE_SNPRINTF();
2038 }
2039
2040 ret = snprintf( p, n, " revocation date: " \
2041 "%04d-%02d-%02d %02d:%02d:%02d",
2042 entry->revocation_date.year, entry->revocation_date.mon,
2043 entry->revocation_date.day, entry->revocation_date.hour,
2044 entry->revocation_date.min, entry->revocation_date.sec );
2045 SAFE_SNPRINTF();
2046
2047 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002048 }
2049
Paul Bakkerd98030e2009-05-02 15:13:40 +00002050 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2051 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002052
Paul Bakkerd98030e2009-05-02 15:13:40 +00002053 switch( crl->sig_oid1.p[8] )
2054 {
2055 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2056 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2057 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2058 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2059 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2060 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2061 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2062 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2063 default: ret = snprintf( p, n, "???" ); break;
2064 }
2065 SAFE_SNPRINTF();
2066
Paul Bakker1e27bb22009-07-19 20:25:25 +00002067 ret = snprintf( p, n, "\n" );
2068 SAFE_SNPRINTF();
2069
Paul Bakkerd98030e2009-05-02 15:13:40 +00002070 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002071}
2072
2073/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00002074 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00002075 */
Paul Bakker40ea7de2009-05-03 10:18:48 +00002076int x509parse_time_expired( x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00002077{
2078 struct tm *lt;
2079 time_t tt;
2080
2081 tt = time( NULL );
2082 lt = localtime( &tt );
2083
Paul Bakker40ea7de2009-05-03 10:18:48 +00002084 if( lt->tm_year > to->year - 1900 )
2085 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002086
Paul Bakker40ea7de2009-05-03 10:18:48 +00002087 if( lt->tm_year == to->year - 1900 &&
2088 lt->tm_mon > to->mon - 1 )
2089 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002090
Paul Bakker40ea7de2009-05-03 10:18:48 +00002091 if( lt->tm_year == to->year - 1900 &&
2092 lt->tm_mon == to->mon - 1 &&
2093 lt->tm_mday > to->day )
2094 return( 1 );
2095
2096 return( 0 );
2097}
2098
2099/*
2100 * Return 1 if the certificate is revoked, or 0 otherwise.
2101 */
2102int x509parse_revoked( x509_cert *crt, x509_crl *crl )
2103{
2104 x509_crl_entry *cur = &crl->entry;
2105
2106 while( cur != NULL && cur->serial.len != 0 )
2107 {
2108 if( memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
2109 {
2110 if( x509parse_time_expired( &cur->revocation_date ) )
2111 return( 1 );
2112 }
2113
2114 cur = cur->next;
2115 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002116
2117 return( 0 );
2118}
2119
2120static void x509_hash( unsigned char *in, int len, int alg,
2121 unsigned char *out )
2122{
2123 switch( alg )
2124 {
Paul Bakker40e46942009-01-03 21:51:57 +00002125#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002126 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002127#endif
Paul Bakker40e46942009-01-03 21:51:57 +00002128#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002129 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002130#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00002131 case SIG_RSA_MD5 : md5( in, len, out ); break;
2132 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
2133#if defined(POLARSSL_SHA2_C)
2134 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
2135 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
2136#endif
2137#if defined(POLARSSL_SHA2_C)
2138 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
2139 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
2140#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002141 default:
2142 memset( out, '\xFF', len );
2143 break;
2144 }
2145}
2146
2147/*
2148 * Verify the certificate validity
2149 */
2150int x509parse_verify( x509_cert *crt,
2151 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00002152 x509_crl *ca_crl,
Paul Bakker5121ce52009-01-03 21:22:43 +00002153 char *cn, int *flags )
2154{
2155 int cn_len;
2156 int hash_id;
2157 int pathlen;
2158 x509_cert *cur;
2159 x509_name *name;
Paul Bakker4593aea2009-02-09 22:32:35 +00002160 unsigned char hash[64];
Paul Bakker5121ce52009-01-03 21:22:43 +00002161
Paul Bakker40ea7de2009-05-03 10:18:48 +00002162 *flags = 0;
2163
2164 if( x509parse_time_expired( &crt->valid_to ) )
2165 *flags = BADCERT_EXPIRED;
Paul Bakker5121ce52009-01-03 21:22:43 +00002166
2167 if( cn != NULL )
2168 {
2169 name = &crt->subject;
2170 cn_len = strlen( cn );
2171
2172 while( name != NULL )
2173 {
2174 if( memcmp( name->oid.p, OID_CN, 3 ) == 0 &&
2175 memcmp( name->val.p, cn, cn_len ) == 0 &&
2176 name->val.len == cn_len )
2177 break;
2178
2179 name = name->next;
2180 }
2181
2182 if( name == NULL )
2183 *flags |= BADCERT_CN_MISMATCH;
2184 }
2185
2186 *flags |= BADCERT_NOT_TRUSTED;
2187
2188 /*
2189 * Iterate upwards in the given cert chain,
2190 * ignoring any upper cert with CA != TRUE.
2191 */
2192 cur = crt->next;
2193
2194 pathlen = 1;
2195
Paul Bakker7c6d4a42009-03-28 20:35:47 +00002196 while( cur != NULL && cur->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002197 {
2198 if( cur->ca_istrue == 0 ||
2199 crt->issuer_raw.len != cur->subject_raw.len ||
2200 memcmp( crt->issuer_raw.p, cur->subject_raw.p,
2201 crt->issuer_raw.len ) != 0 )
2202 {
2203 cur = cur->next;
2204 continue;
2205 }
2206
2207 hash_id = crt->sig_oid1.p[8];
2208
2209 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2210
2211 if( rsa_pkcs1_verify( &cur->rsa, RSA_PUBLIC, hash_id,
2212 0, hash, crt->sig.p ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00002213 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002214
2215 pathlen++;
2216
2217 crt = cur;
2218 cur = crt->next;
2219 }
2220
2221 /*
2222 * Atempt to validate topmost cert with our CA chain.
2223 */
Paul Bakker7c6d4a42009-03-28 20:35:47 +00002224 while( trust_ca != NULL && trust_ca->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002225 {
2226 if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
2227 memcmp( crt->issuer_raw.p, trust_ca->subject_raw.p,
2228 crt->issuer_raw.len ) != 0 )
2229 {
2230 trust_ca = trust_ca->next;
2231 continue;
2232 }
2233
2234 if( trust_ca->max_pathlen > 0 &&
2235 trust_ca->max_pathlen < pathlen )
2236 break;
2237
2238 hash_id = crt->sig_oid1.p[8];
2239
2240 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2241
2242 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
2243 0, hash, crt->sig.p ) == 0 )
2244 {
2245 /*
2246 * cert. is signed by a trusted CA
2247 */
2248 *flags &= ~BADCERT_NOT_TRUSTED;
2249 break;
2250 }
2251
2252 trust_ca = trust_ca->next;
2253 }
2254
Paul Bakker40ea7de2009-05-03 10:18:48 +00002255 /*
2256 * TODO: What happens if no CRL is present?
2257 * Suggestion: Revocation state should be unknown if no CRL is present.
2258 * For backwards compatibility this is not yet implemented.
2259 */
2260
2261 /*
2262 * Check if the topmost certificate is revoked if the trusted CA is
2263 * determined.
2264 */
2265 while( trust_ca != NULL && ca_crl != NULL && ca_crl->version != 0 )
2266 {
2267 if( ca_crl->issuer_raw.len != trust_ca->subject_raw.len ||
2268 memcmp( ca_crl->issuer_raw.p, trust_ca->subject_raw.p,
2269 ca_crl->issuer_raw.len ) != 0 )
2270 {
2271 ca_crl = ca_crl->next;
2272 continue;
2273 }
2274
2275 /*
2276 * Check if CRL is correctry signed by the trusted CA
2277 */
2278 hash_id = ca_crl->sig_oid1.p[8];
2279
2280 x509_hash( ca_crl->tbs.p, ca_crl->tbs.len, hash_id, hash );
2281
2282 if( !rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
2283 0, hash, ca_crl->sig.p ) == 0 )
2284 {
2285 /*
2286 * CRL is not trusted
2287 */
2288 *flags |= BADCRL_NOT_TRUSTED;
2289 break;
2290 }
2291
2292 /*
2293 * Check for validity of CRL (Do not drop out)
2294 */
2295 if( x509parse_time_expired( &ca_crl->next_update ) )
2296 *flags |= BADCRL_EXPIRED;
2297
2298 /*
2299 * Check if certificate is revoked
2300 */
2301 if( x509parse_revoked(crt, ca_crl) )
2302 {
2303 *flags |= BADCERT_REVOKED;
2304 break;
2305 }
2306
2307 ca_crl = ca_crl->next;
2308 }
2309
Paul Bakker5121ce52009-01-03 21:22:43 +00002310 if( *flags != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00002311 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002312
2313 return( 0 );
2314}
2315
2316/*
2317 * Unallocate all certificate data
2318 */
2319void x509_free( x509_cert *crt )
2320{
2321 x509_cert *cert_cur = crt;
2322 x509_cert *cert_prv;
2323 x509_name *name_cur;
2324 x509_name *name_prv;
2325
2326 if( crt == NULL )
2327 return;
2328
2329 do
2330 {
2331 rsa_free( &cert_cur->rsa );
2332
2333 name_cur = cert_cur->issuer.next;
2334 while( name_cur != NULL )
2335 {
2336 name_prv = name_cur;
2337 name_cur = name_cur->next;
2338 memset( name_prv, 0, sizeof( x509_name ) );
2339 free( name_prv );
2340 }
2341
2342 name_cur = cert_cur->subject.next;
2343 while( name_cur != NULL )
2344 {
2345 name_prv = name_cur;
2346 name_cur = name_cur->next;
2347 memset( name_prv, 0, sizeof( x509_name ) );
2348 free( name_prv );
2349 }
2350
2351 if( cert_cur->raw.p != NULL )
2352 {
2353 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
2354 free( cert_cur->raw.p );
2355 }
2356
2357 cert_cur = cert_cur->next;
2358 }
2359 while( cert_cur != NULL );
2360
2361 cert_cur = crt;
2362 do
2363 {
2364 cert_prv = cert_cur;
2365 cert_cur = cert_cur->next;
2366
2367 memset( cert_prv, 0, sizeof( x509_cert ) );
2368 if( cert_prv != crt )
2369 free( cert_prv );
2370 }
2371 while( cert_cur != NULL );
2372}
2373
Paul Bakkerd98030e2009-05-02 15:13:40 +00002374/*
2375 * Unallocate all CRL data
2376 */
2377void x509_crl_free( x509_crl *crl )
2378{
2379 x509_crl *crl_cur = crl;
2380 x509_crl *crl_prv;
2381 x509_name *name_cur;
2382 x509_name *name_prv;
2383 x509_crl_entry *entry_cur;
2384 x509_crl_entry *entry_prv;
2385
2386 if( crl == NULL )
2387 return;
2388
2389 do
2390 {
2391 name_cur = crl_cur->issuer.next;
2392 while( name_cur != NULL )
2393 {
2394 name_prv = name_cur;
2395 name_cur = name_cur->next;
2396 memset( name_prv, 0, sizeof( x509_name ) );
2397 free( name_prv );
2398 }
2399
2400 entry_cur = crl_cur->entry.next;
2401 while( entry_cur != NULL )
2402 {
2403 entry_prv = entry_cur;
2404 entry_cur = entry_cur->next;
2405 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
2406 free( entry_prv );
2407 }
2408
2409 if( crl_cur->raw.p != NULL )
2410 {
2411 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
2412 free( crl_cur->raw.p );
2413 }
2414
2415 crl_cur = crl_cur->next;
2416 }
2417 while( crl_cur != NULL );
2418
2419 crl_cur = crl;
2420 do
2421 {
2422 crl_prv = crl_cur;
2423 crl_cur = crl_cur->next;
2424
2425 memset( crl_prv, 0, sizeof( x509_crl ) );
2426 if( crl_prv != crl )
2427 free( crl_prv );
2428 }
2429 while( crl_cur != NULL );
2430}
2431
Paul Bakker40e46942009-01-03 21:51:57 +00002432#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002433
Paul Bakker40e46942009-01-03 21:51:57 +00002434#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00002435
2436/*
2437 * Checkup routine
2438 */
2439int x509_self_test( int verbose )
2440{
2441 int ret, i, j;
2442 x509_cert cacert;
2443 x509_cert clicert;
2444 rsa_context rsa;
2445
2446 if( verbose != 0 )
2447 printf( " X.509 certificate load: " );
2448
2449 memset( &clicert, 0, sizeof( x509_cert ) );
2450
2451 ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
2452 strlen( test_cli_crt ) );
2453 if( ret != 0 )
2454 {
2455 if( verbose != 0 )
2456 printf( "failed\n" );
2457
2458 return( ret );
2459 }
2460
2461 memset( &cacert, 0, sizeof( x509_cert ) );
2462
2463 ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
2464 strlen( test_ca_crt ) );
2465 if( ret != 0 )
2466 {
2467 if( verbose != 0 )
2468 printf( "failed\n" );
2469
2470 return( ret );
2471 }
2472
2473 if( verbose != 0 )
2474 printf( "passed\n X.509 private key load: " );
2475
2476 i = strlen( test_ca_key );
2477 j = strlen( test_ca_pwd );
2478
2479 if( ( ret = x509parse_key( &rsa,
2480 (unsigned char *) test_ca_key, i,
2481 (unsigned char *) test_ca_pwd, j ) ) != 0 )
2482 {
2483 if( verbose != 0 )
2484 printf( "failed\n" );
2485
2486 return( ret );
2487 }
2488
2489 if( verbose != 0 )
2490 printf( "passed\n X.509 signature verify: ");
2491
Paul Bakker1973e4c2009-07-10 22:32:40 +00002492 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &i );
Paul Bakker5121ce52009-01-03 21:22:43 +00002493 if( ret != 0 )
2494 {
2495 if( verbose != 0 )
2496 printf( "failed\n" );
2497
2498 return( ret );
2499 }
2500
2501 if( verbose != 0 )
2502 printf( "passed\n\n" );
2503
2504 x509_free( &cacert );
2505 x509_free( &clicert );
2506 rsa_free( &rsa );
2507
2508 return( 0 );
2509}
2510
2511#endif
2512
2513#endif