blob: 47aae2a38fc15a45e50a3ae4a9bd19876c851e0f [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;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000617 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000618
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
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000633 end_ext_data = *p + len;
634
Paul Bakker5121ce52009-01-03 21:22:43 +0000635 if( memcmp( *p, "\x06\x03\x55\x1D\x13", 5 ) != 0 )
636 {
637 *p += len;
638 continue;
639 }
640
641 *p += 5;
642
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000643 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000644 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
645 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000646
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000647 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000648 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000649 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000650
651 /*
652 * BasicConstraints ::= SEQUENCE {
653 * cA BOOLEAN DEFAULT FALSE,
654 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
655 */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000656 end_ext_octet = *p + len;
657
658 if( end_ext_octet != end_ext_data )
659 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
660 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000661
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000662 if( ( ret = asn1_get_tag( p, end_ext_octet, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000663 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000664 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000665
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000666 if( *p == end_ext_octet )
Paul Bakker5121ce52009-01-03 21:22:43 +0000667 continue;
668
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000669 if( ( ret = asn1_get_bool( p, end_ext_octet, &is_cacert ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000670 {
Paul Bakker40e46942009-01-03 21:51:57 +0000671 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000672 ret = asn1_get_int( p, end_ext_octet, &is_cacert );
Paul Bakker5121ce52009-01-03 21:22:43 +0000673
674 if( ret != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000675 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000676
677 if( is_cacert != 0 )
678 is_cacert = 1;
679 }
680
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000681 if( *p == end_ext_octet )
Paul Bakker5121ce52009-01-03 21:22:43 +0000682 continue;
683
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000684 if( ( ret = asn1_get_int( p, end_ext_octet, max_pathlen ) ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000685 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000686
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000687 if( *p != end_ext_octet )
Paul Bakker40e46942009-01-03 21:51:57 +0000688 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
689 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000690
691 max_pathlen++;
692 }
693
694 if( *p != end )
Paul Bakker40e46942009-01-03 21:51:57 +0000695 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
696 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000697
698 *ca_istrue = is_critical & is_cacert;
699
700 return( 0 );
701}
702
703/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000704 * X.509 CRL Entries
705 */
706static int x509_get_entries( unsigned char **p,
707 unsigned char *end,
708 x509_crl_entry *entry )
709{
Paul Bakker9be19372009-07-27 20:21:53 +0000710 int ret, entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000711 x509_crl_entry *cur_entry = entry;
712
713 if( *p == end )
714 return( 0 );
715
Paul Bakker9be19372009-07-27 20:21:53 +0000716 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000717 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
718 {
719 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
720 return( 0 );
721
722 return( ret );
723 }
724
Paul Bakker9be19372009-07-27 20:21:53 +0000725 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000726
727 while( *p < end )
728 {
729 int len2;
730
731 if( ( ret = asn1_get_tag( p, end, &len2,
732 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
733 {
Paul Bakkerd98030e2009-05-02 15:13:40 +0000734 return( ret );
735 }
736
Paul Bakker9be19372009-07-27 20:21:53 +0000737 cur_entry->raw.tag = **p;
738 cur_entry->raw.p = *p;
739 cur_entry->raw.len = len2;
740
Paul Bakkerd98030e2009-05-02 15:13:40 +0000741 if( ( ret = x509_get_serial( p, end, &cur_entry->serial ) ) != 0 )
742 return( ret );
743
744 if( ( ret = x509_get_UTCTime( p, end, &cur_entry->revocation_date ) ) != 0 )
745 return( ret );
746
747 if( ( ret = x509_get_crl_ext( p, end, &cur_entry->entry_ext ) ) != 0 )
748 return( ret );
749
750 if ( *p < end ) {
751 cur_entry->next = malloc( sizeof( x509_crl_entry ) );
752 cur_entry = cur_entry->next;
753 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
754 }
755 }
756
757 return( 0 );
758}
759
760/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000761 * Parse one or more certificates and add them to the chained list
762 */
763int x509parse_crt( x509_cert *chain, unsigned char *buf, int buflen )
764{
765 int ret, len;
766 unsigned char *s1, *s2;
767 unsigned char *p, *end;
768 x509_cert *crt;
769
770 crt = chain;
771
Paul Bakker320a4b52009-03-28 18:52:39 +0000772 /*
773 * Check for valid input
774 */
775 if( crt == NULL || buf == NULL )
776 return( 1 );
777
Paul Bakkere9581d62009-03-28 20:29:25 +0000778 while( crt->version != 0 && crt->next != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +0000779 crt = crt->next;
780
781 /*
Paul Bakker320a4b52009-03-28 18:52:39 +0000782 * Add new certificate on the end of the chain if needed.
783 */
Paul Bakkere9581d62009-03-28 20:29:25 +0000784 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +0000785 {
786 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
787
Paul Bakker7d06ad22009-05-02 15:53:56 +0000788 if( crt->next == NULL )
789 {
Paul Bakker320a4b52009-03-28 18:52:39 +0000790 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +0000791 return( 1 );
792 }
Paul Bakker320a4b52009-03-28 18:52:39 +0000793
Paul Bakker7d06ad22009-05-02 15:53:56 +0000794 crt = crt->next;
795 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +0000796 }
797
798 /*
Paul Bakker5121ce52009-01-03 21:22:43 +0000799 * check if the certificate is encoded in base64
800 */
801 s1 = (unsigned char *) strstr( (char *) buf,
802 "-----BEGIN CERTIFICATE-----" );
803
804 if( s1 != NULL )
805 {
806 s2 = (unsigned char *) strstr( (char *) buf,
807 "-----END CERTIFICATE-----" );
808
809 if( s2 == NULL || s2 <= s1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000810 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +0000811
812 s1 += 27;
813 if( *s1 == '\r' ) s1++;
814 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +0000815 else return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +0000816
817 /*
818 * get the DER data length and decode the buffer
819 */
820 len = 0;
821 ret = base64_decode( NULL, &len, s1, s2 - s1 );
822
Paul Bakker40e46942009-01-03 21:51:57 +0000823 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
824 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000825
826 if( ( p = (unsigned char *) malloc( len ) ) == NULL )
827 return( 1 );
828
829 if( ( ret = base64_decode( p, &len, s1, s2 - s1 ) ) != 0 )
830 {
831 free( p );
Paul Bakker40e46942009-01-03 21:51:57 +0000832 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000833 }
834
835 /*
836 * update the buffer size and offset
837 */
838 s2 += 25;
839 if( *s2 == '\r' ) s2++;
840 if( *s2 == '\n' ) s2++;
841 else
842 {
843 free( p );
Paul Bakker40e46942009-01-03 21:51:57 +0000844 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +0000845 }
846
847 buflen -= s2 - buf;
848 buf = s2;
849 }
850 else
851 {
852 /*
853 * nope, copy the raw DER data
854 */
855 p = (unsigned char *) malloc( len = buflen );
856
857 if( p == NULL )
858 return( 1 );
859
860 memcpy( p, buf, buflen );
861
862 buflen = 0;
863 }
864
865 crt->raw.p = p;
866 crt->raw.len = len;
867 end = p + len;
868
869 /*
870 * Certificate ::= SEQUENCE {
871 * tbsCertificate TBSCertificate,
872 * signatureAlgorithm AlgorithmIdentifier,
873 * signatureValue BIT STRING }
874 */
875 if( ( ret = asn1_get_tag( &p, end, &len,
876 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
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 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000880 }
881
882 if( len != (int) ( end - p ) )
883 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000884 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000885 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
886 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000887 }
888
889 /*
890 * TBSCertificate ::= SEQUENCE {
891 */
892 crt->tbs.p = p;
893
894 if( ( ret = asn1_get_tag( &p, end, &len,
895 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
896 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000897 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000898 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000899 }
900
901 end = p + len;
902 crt->tbs.len = end - crt->tbs.p;
903
904 /*
905 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
906 *
907 * CertificateSerialNumber ::= INTEGER
908 *
909 * signature AlgorithmIdentifier
910 */
911 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
912 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
913 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
914 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000915 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +0000916 return( ret );
917 }
918
919 crt->version++;
920
921 if( crt->version > 3 )
922 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000923 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000924 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +0000925 }
926
927 if( crt->sig_oid1.len != 9 ||
928 memcmp( crt->sig_oid1.p, OID_PKCS1, 8 ) != 0 )
929 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000930 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000931 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000932 }
933
934 if( crt->sig_oid1.p[8] < 2 ||
Paul Bakker4593aea2009-02-09 22:32:35 +0000935 ( crt->sig_oid1.p[8] > 5 && crt->sig_oid1.p[8] < 11 ) ||
Paul Bakker7d06ad22009-05-02 15:53:56 +0000936 crt->sig_oid1.p[8] > 14 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000937 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000938 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000939 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000940 }
941
942 /*
943 * issuer Name
944 */
945 crt->issuer_raw.p = p;
946
947 if( ( ret = asn1_get_tag( &p, end, &len,
948 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
949 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000950 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000951 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000952 }
953
954 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
955 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000956 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +0000957 return( ret );
958 }
959
960 crt->issuer_raw.len = p - crt->issuer_raw.p;
961
962 /*
963 * Validity ::= SEQUENCE {
964 * notBefore Time,
965 * notAfter Time }
966 *
967 */
968 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
969 &crt->valid_to ) ) != 0 )
970 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000971 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +0000972 return( ret );
973 }
974
975 /*
976 * subject Name
977 */
978 crt->subject_raw.p = p;
979
980 if( ( ret = asn1_get_tag( &p, end, &len,
981 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
982 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000983 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +0000984 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000985 }
986
987 if( ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
988 {
Paul Bakker7d06ad22009-05-02 15:53:56 +0000989 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +0000990 return( ret );
991 }
992
993 crt->subject_raw.len = p - crt->subject_raw.p;
994
995 /*
996 * SubjectPublicKeyInfo ::= SEQUENCE
997 * algorithm AlgorithmIdentifier,
998 * subjectPublicKey BIT STRING }
999 */
1000 if( ( ret = asn1_get_tag( &p, end, &len,
1001 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1002 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001003 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001004 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001005 }
1006
1007 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1008 &crt->rsa.N, &crt->rsa.E ) ) != 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 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1015 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001016 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001017 return( ret );
1018 }
1019
1020 crt->rsa.len = mpi_size( &crt->rsa.N );
1021
1022 /*
1023 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1024 * -- If present, version shall be v2 or v3
1025 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1026 * -- If present, version shall be v2 or v3
1027 * extensions [3] EXPLICIT Extensions OPTIONAL
1028 * -- If present, version shall be v3
1029 */
1030 if( crt->version == 2 || crt->version == 3 )
1031 {
1032 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1033 if( ret != 0 )
1034 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001035 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001036 return( ret );
1037 }
1038 }
1039
1040 if( crt->version == 2 || crt->version == 3 )
1041 {
1042 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1043 if( ret != 0 )
1044 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001045 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001046 return( ret );
1047 }
1048 }
1049
1050 if( crt->version == 3 )
1051 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001052 ret = x509_get_crt_ext( &p, end, &crt->v3_ext,
Paul Bakker5121ce52009-01-03 21:22:43 +00001053 &crt->ca_istrue, &crt->max_pathlen );
1054 if( ret != 0 )
1055 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001056 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001057 return( ret );
1058 }
1059 }
1060
1061 if( p != end )
1062 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001063 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001064 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1065 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001066 }
1067
1068 end = crt->raw.p + crt->raw.len;
1069
1070 /*
1071 * signatureAlgorithm AlgorithmIdentifier,
1072 * signatureValue BIT STRING
1073 */
1074 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1075 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001076 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001077 return( ret );
1078 }
1079
Paul Bakker320a4b52009-03-28 18:52:39 +00001080 if( memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001081 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001082 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001083 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001084 }
1085
1086 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1087 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001088 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001089 return( ret );
1090 }
1091
1092 if( p != end )
1093 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001094 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001095 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1096 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001097 }
1098
Paul Bakker5121ce52009-01-03 21:22:43 +00001099 if( buflen > 0 )
Paul Bakker320a4b52009-03-28 18:52:39 +00001100 {
1101 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1102
Paul Bakker7d06ad22009-05-02 15:53:56 +00001103 if( crt->next == NULL )
1104 {
Paul Bakker320a4b52009-03-28 18:52:39 +00001105 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001106 return( 1 );
1107 }
Paul Bakker320a4b52009-03-28 18:52:39 +00001108
Paul Bakker7d06ad22009-05-02 15:53:56 +00001109 crt = crt->next;
1110 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001111
Paul Bakker5121ce52009-01-03 21:22:43 +00001112 return( x509parse_crt( crt, buf, buflen ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001113 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001114
1115 return( 0 );
1116}
1117
1118/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001119 * Parse one or more CRLs and add them to the chained list
1120 */
1121int x509parse_crl( x509_crl *chain, unsigned char *buf, int buflen )
1122{
1123 int ret, len;
1124 unsigned char *s1, *s2;
1125 unsigned char *p, *end;
1126 x509_crl *crl;
1127
1128 crl = chain;
1129
1130 /*
1131 * Check for valid input
1132 */
1133 if( crl == NULL || buf == NULL )
1134 return( 1 );
1135
1136 while( crl->version != 0 && crl->next != NULL )
1137 crl = crl->next;
1138
1139 /*
1140 * Add new CRL on the end of the chain if needed.
1141 */
1142 if ( crl->version != 0 && crl->next == NULL)
1143 {
1144 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1145
Paul Bakker7d06ad22009-05-02 15:53:56 +00001146 if( crl->next == NULL )
1147 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001148 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001149 return( 1 );
1150 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001151
Paul Bakker7d06ad22009-05-02 15:53:56 +00001152 crl = crl->next;
1153 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001154 }
1155
1156 /*
1157 * check if the CRL is encoded in base64
1158 */
1159 s1 = (unsigned char *) strstr( (char *) buf,
1160 "-----BEGIN X509 CRL-----" );
1161
1162 if( s1 != NULL )
1163 {
1164 s2 = (unsigned char *) strstr( (char *) buf,
1165 "-----END X509 CRL-----" );
1166
1167 if( s2 == NULL || s2 <= s1 )
1168 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1169
1170 s1 += 24;
1171 if( *s1 == '\r' ) s1++;
1172 if( *s1 == '\n' ) s1++;
1173 else return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1174
1175 /*
1176 * get the DER data length and decode the buffer
1177 */
1178 len = 0;
1179 ret = base64_decode( NULL, &len, s1, s2 - s1 );
1180
1181 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
1182 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
1183
1184 if( ( p = (unsigned char *) malloc( len ) ) == NULL )
1185 return( 1 );
1186
1187 if( ( ret = base64_decode( p, &len, s1, s2 - s1 ) ) != 0 )
1188 {
1189 free( p );
1190 return( POLARSSL_ERR_X509_CERT_INVALID_PEM | ret );
1191 }
1192
1193 /*
1194 * update the buffer size and offset
1195 */
1196 s2 += 22;
1197 if( *s2 == '\r' ) s2++;
1198 if( *s2 == '\n' ) s2++;
1199 else
1200 {
1201 free( p );
1202 return( POLARSSL_ERR_X509_CERT_INVALID_PEM );
1203 }
1204
1205 buflen -= s2 - buf;
1206 buf = s2;
1207 }
1208 else
1209 {
1210 /*
1211 * nope, copy the raw DER data
1212 */
1213 p = (unsigned char *) malloc( len = buflen );
1214
1215 if( p == NULL )
1216 return( 1 );
1217
1218 memcpy( p, buf, buflen );
1219
1220 buflen = 0;
1221 }
1222
1223 crl->raw.p = p;
1224 crl->raw.len = len;
1225 end = p + len;
1226
1227 /*
1228 * CertificateList ::= SEQUENCE {
1229 * tbsCertList TBSCertList,
1230 * signatureAlgorithm AlgorithmIdentifier,
1231 * signatureValue BIT STRING }
1232 */
1233 if( ( ret = asn1_get_tag( &p, end, &len,
1234 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1235 {
1236 x509_crl_free( crl );
1237 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1238 }
1239
1240 if( len != (int) ( end - p ) )
1241 {
1242 x509_crl_free( crl );
1243 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1244 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1245 }
1246
1247 /*
1248 * TBSCertList ::= SEQUENCE {
1249 */
1250 crl->tbs.p = p;
1251
1252 if( ( ret = asn1_get_tag( &p, end, &len,
1253 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1254 {
1255 x509_crl_free( crl );
1256 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
1257 }
1258
1259 end = p + len;
1260 crl->tbs.len = end - crl->tbs.p;
1261
1262 /*
1263 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1264 * -- if present, MUST be v2
1265 *
1266 * signature AlgorithmIdentifier
1267 */
1268 if( ( ret = x509_get_version( &p, end, &crl->version ) ) != 0 ||
1269 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1270 {
1271 x509_crl_free( crl );
1272 return( ret );
1273 }
1274
1275 crl->version++;
1276
1277 if( crl->version > 2 )
1278 {
1279 x509_crl_free( crl );
1280 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1281 }
1282
1283 if( crl->sig_oid1.len != 9 ||
1284 memcmp( crl->sig_oid1.p, OID_PKCS1, 8 ) != 0 )
1285 {
1286 x509_crl_free( crl );
1287 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1288 }
1289
1290 if( crl->sig_oid1.p[8] < 2 ||
1291 ( crl->sig_oid1.p[8] > 5 && crl->sig_oid1.p[8] < 11 ) ||
1292 crl->sig_oid1.p[8] > 14 )
1293 {
1294 x509_crl_free( crl );
1295 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1296 }
1297
1298 /*
1299 * issuer Name
1300 */
1301 crl->issuer_raw.p = p;
1302
1303 if( ( ret = asn1_get_tag( &p, end, &len,
1304 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1305 {
1306 x509_crl_free( crl );
1307 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
1308 }
1309
1310 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1311 {
1312 x509_crl_free( crl );
1313 return( ret );
1314 }
1315
1316 crl->issuer_raw.len = p - crl->issuer_raw.p;
1317
1318 /*
1319 * thisUpdate Time
1320 * nextUpdate Time OPTIONAL
1321 */
1322 if( ( ret = x509_get_UTCTime( &p, end, &crl->this_update ) ) != 0 )
1323 {
1324 x509_crl_free( crl );
1325 return( ret );
1326 }
1327
1328 if( ( ret = x509_get_UTCTime( &p, end, &crl->next_update ) ) != 0 )
1329 {
Paul Bakker635f4b42009-07-20 20:34:41 +00001330 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE |
Paul Bakker9be19372009-07-27 20:21:53 +00001331 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
1332 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE |
1333 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001334 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001335 x509_crl_free( crl );
1336 return( ret );
1337 }
1338 }
1339
1340 /*
1341 * revokedCertificates SEQUENCE OF SEQUENCE {
1342 * userCertificate CertificateSerialNumber,
1343 * revocationDate Time,
1344 * crlEntryExtensions Extensions OPTIONAL
1345 * -- if present, MUST be v2
1346 * } OPTIONAL
1347 */
1348 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1349 {
1350 x509_crl_free( crl );
1351 return( ret );
1352 }
1353
1354 /*
1355 * crlExtensions EXPLICIT Extensions OPTIONAL
1356 * -- if present, MUST be v2
1357 */
1358 if( crl->version == 2 )
1359 {
1360 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1361
1362 if( ret != 0 )
1363 {
1364 x509_crl_free( crl );
1365 return( ret );
1366 }
1367 }
1368
1369 if( p != end )
1370 {
1371 x509_crl_free( crl );
1372 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1373 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1374 }
1375
1376 end = crl->raw.p + crl->raw.len;
1377
1378 /*
1379 * signatureAlgorithm AlgorithmIdentifier,
1380 * signatureValue BIT STRING
1381 */
1382 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1383 {
1384 x509_crl_free( crl );
1385 return( ret );
1386 }
1387
1388 if( memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
1389 {
1390 x509_crl_free( crl );
1391 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1392 }
1393
1394 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1395 {
1396 x509_crl_free( crl );
1397 return( ret );
1398 }
1399
1400 if( p != end )
1401 {
1402 x509_crl_free( crl );
1403 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT |
1404 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1405 }
1406
1407 if( buflen > 0 )
1408 {
1409 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1410
Paul Bakker7d06ad22009-05-02 15:53:56 +00001411 if( crl->next == NULL )
1412 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001413 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001414 return( 1 );
1415 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001416
Paul Bakker7d06ad22009-05-02 15:53:56 +00001417 crl = crl->next;
1418 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001419
1420 return( x509parse_crl( crl, buf, buflen ) );
1421 }
1422
1423 return( 0 );
1424}
1425
1426/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001427 * Load all data from a file into a given buffer.
1428 */
1429int load_file( char *path, unsigned char **buf, size_t *n )
1430{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001431 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001432
Paul Bakkerd98030e2009-05-02 15:13:40 +00001433 if( ( f = fopen( path, "rb" ) ) == NULL )
1434 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001435
Paul Bakkerd98030e2009-05-02 15:13:40 +00001436 fseek( f, 0, SEEK_END );
1437 *n = (size_t) ftell( f );
1438 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001439
Paul Bakkerd98030e2009-05-02 15:13:40 +00001440 if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
1441 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001442
Paul Bakkerd98030e2009-05-02 15:13:40 +00001443 if( fread( *buf, 1, *n, f ) != *n )
1444 {
1445 fclose( f );
1446 free( *buf );
1447 return( 1 );
1448 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001449
Paul Bakkerd98030e2009-05-02 15:13:40 +00001450 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001451
Paul Bakkerd98030e2009-05-02 15:13:40 +00001452 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001453
Paul Bakkerd98030e2009-05-02 15:13:40 +00001454 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001455}
1456
1457/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001458 * Load one or more certificates and add them to the chained list
1459 */
1460int x509parse_crtfile( x509_cert *chain, char *path )
1461{
1462 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001463 size_t n;
1464 unsigned char *buf;
1465
Paul Bakker2b245eb2009-04-19 18:44:26 +00001466 if ( load_file( path, &buf, &n ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001467 return( 1 );
1468
Paul Bakker5121ce52009-01-03 21:22:43 +00001469 ret = x509parse_crt( chain, buf, (int) n );
1470
1471 memset( buf, 0, n + 1 );
1472 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001473
1474 return( ret );
1475}
1476
Paul Bakkerd98030e2009-05-02 15:13:40 +00001477/*
1478 * Load one or more CRLs and add them to the chained list
1479 */
1480int x509parse_crlfile( x509_crl *chain, char *path )
1481{
1482 int ret;
1483 size_t n;
1484 unsigned char *buf;
1485
1486 if ( load_file( path, &buf, &n ) )
1487 return( 1 );
1488
1489 ret = x509parse_crl( chain, buf, (int) n );
1490
1491 memset( buf, 0, n + 1 );
1492 free( buf );
1493
1494 return( ret );
1495}
1496
Paul Bakker40e46942009-01-03 21:51:57 +00001497#if defined(POLARSSL_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001498/*
1499 * Read a 16-byte hex string and convert it to binary
1500 */
1501static int x509_get_iv( unsigned char *s, unsigned char iv[8] )
1502{
1503 int i, j, k;
1504
1505 memset( iv, 0, 8 );
1506
1507 for( i = 0; i < 16; i++, s++ )
1508 {
1509 if( *s >= '0' && *s <= '9' ) j = *s - '0'; else
1510 if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else
1511 if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else
Paul Bakker40e46942009-01-03 21:51:57 +00001512 return( POLARSSL_ERR_X509_KEY_INVALID_ENC_IV );
Paul Bakker5121ce52009-01-03 21:22:43 +00001513
1514 k = ( ( i & 1 ) != 0 ) ? j : j << 4;
1515
1516 iv[i >> 1] = (unsigned char)( iv[i >> 1] | k );
1517 }
1518
1519 return( 0 );
1520}
1521
1522/*
1523 * Decrypt with 3DES-CBC, using PBKDF1 for key derivation
1524 */
1525static void x509_des3_decrypt( unsigned char des3_iv[8],
1526 unsigned char *buf, int buflen,
1527 unsigned char *pwd, int pwdlen )
1528{
1529 md5_context md5_ctx;
1530 des3_context des3_ctx;
1531 unsigned char md5sum[16];
1532 unsigned char des3_key[24];
1533
1534 /*
1535 * 3DES key[ 0..15] = MD5(pwd || IV)
1536 * key[16..23] = MD5(pwd || IV || 3DES key[ 0..15])
1537 */
1538 md5_starts( &md5_ctx );
1539 md5_update( &md5_ctx, pwd, pwdlen );
1540 md5_update( &md5_ctx, des3_iv, 8 );
1541 md5_finish( &md5_ctx, md5sum );
1542 memcpy( des3_key, md5sum, 16 );
1543
1544 md5_starts( &md5_ctx );
1545 md5_update( &md5_ctx, md5sum, 16 );
1546 md5_update( &md5_ctx, pwd, pwdlen );
1547 md5_update( &md5_ctx, des3_iv, 8 );
1548 md5_finish( &md5_ctx, md5sum );
1549 memcpy( des3_key + 16, md5sum, 8 );
1550
1551 des3_set3key_dec( &des3_ctx, des3_key );
1552 des3_crypt_cbc( &des3_ctx, DES_DECRYPT, buflen,
1553 des3_iv, buf, buf );
1554
1555 memset( &md5_ctx, 0, sizeof( md5_ctx ) );
1556 memset( &des3_ctx, 0, sizeof( des3_ctx ) );
1557 memset( md5sum, 0, 16 );
1558 memset( des3_key, 0, 24 );
1559}
1560#endif
1561
1562/*
1563 * Parse a private RSA key
1564 */
1565int x509parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
1566 unsigned char *pwd, int pwdlen )
1567{
1568 int ret, len, enc;
1569 unsigned char *s1, *s2;
1570 unsigned char *p, *end;
1571 unsigned char des3_iv[8];
1572
1573 s1 = (unsigned char *) strstr( (char *) buf,
1574 "-----BEGIN RSA PRIVATE KEY-----" );
1575
1576 if( s1 != NULL )
1577 {
1578 s2 = (unsigned char *) strstr( (char *) buf,
1579 "-----END RSA PRIVATE KEY-----" );
1580
1581 if( s2 == NULL || s2 <= s1 )
Paul Bakker40e46942009-01-03 21:51:57 +00001582 return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001583
1584 s1 += 31;
1585 if( *s1 == '\r' ) s1++;
1586 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001587 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001588
1589 enc = 0;
1590
1591 if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
1592 {
Paul Bakker40e46942009-01-03 21:51:57 +00001593#if defined(POLARSSL_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001594 enc++;
1595
1596 s1 += 22;
1597 if( *s1 == '\r' ) s1++;
1598 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001599 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001600
1601 if( memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001602 return( POLARSSL_ERR_X509_KEY_UNKNOWN_ENC_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +00001603
1604 s1 += 23;
1605 if( x509_get_iv( s1, des3_iv ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001606 return( POLARSSL_ERR_X509_KEY_INVALID_ENC_IV );
Paul Bakker5121ce52009-01-03 21:22:43 +00001607
1608 s1 += 16;
1609 if( *s1 == '\r' ) s1++;
1610 if( *s1 == '\n' ) s1++;
Paul Bakker40e46942009-01-03 21:51:57 +00001611 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001612#else
Paul Bakker40e46942009-01-03 21:51:57 +00001613 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001614#endif
1615 }
1616
1617 len = 0;
1618 ret = base64_decode( NULL, &len, s1, s2 - s1 );
1619
Paul Bakker40e46942009-01-03 21:51:57 +00001620 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
1621 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001622
1623 if( ( buf = (unsigned char *) malloc( len ) ) == NULL )
1624 return( 1 );
1625
1626 if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
1627 {
1628 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001629 return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
Paul Bakker5121ce52009-01-03 21:22:43 +00001630 }
1631
1632 buflen = len;
1633
1634 if( enc != 0 )
1635 {
Paul Bakker40e46942009-01-03 21:51:57 +00001636#if defined(POLARSSL_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001637 if( pwd == NULL )
1638 {
1639 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001640 return( POLARSSL_ERR_X509_KEY_PASSWORD_REQUIRED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001641 }
1642
1643 x509_des3_decrypt( des3_iv, buf, buflen, pwd, pwdlen );
1644
1645 if( buf[0] != 0x30 || buf[1] != 0x82 ||
1646 buf[4] != 0x02 || buf[5] != 0x01 )
1647 {
1648 free( buf );
Paul Bakker40e46942009-01-03 21:51:57 +00001649 return( POLARSSL_ERR_X509_KEY_PASSWORD_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001650 }
1651#else
Paul Bakker40e46942009-01-03 21:51:57 +00001652 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001653#endif
1654 }
1655 }
1656
1657 memset( rsa, 0, sizeof( rsa_context ) );
1658
1659 p = buf;
1660 end = buf + buflen;
1661
1662 /*
1663 * RSAPrivateKey ::= SEQUENCE {
1664 * version Version,
1665 * modulus INTEGER, -- n
1666 * publicExponent INTEGER, -- e
1667 * privateExponent INTEGER, -- d
1668 * prime1 INTEGER, -- p
1669 * prime2 INTEGER, -- q
1670 * exponent1 INTEGER, -- d mod (p-1)
1671 * exponent2 INTEGER, -- d mod (q-1)
1672 * coefficient INTEGER, -- (inverse of q) mod p
1673 * otherPrimeInfos OtherPrimeInfos OPTIONAL
1674 * }
1675 */
1676 if( ( ret = asn1_get_tag( &p, end, &len,
1677 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1678 {
1679 if( s1 != NULL )
1680 free( buf );
1681
1682 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001683 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001684 }
1685
1686 end = p + len;
1687
1688 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
1689 {
1690 if( s1 != NULL )
1691 free( buf );
1692
1693 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001694 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001695 }
1696
1697 if( rsa->ver != 0 )
1698 {
1699 if( s1 != NULL )
1700 free( buf );
1701
1702 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001703 return( ret | POLARSSL_ERR_X509_KEY_INVALID_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001704 }
1705
1706 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
1707 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
1708 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
1709 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
1710 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
1711 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
1712 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
1713 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
1714 {
1715 if( s1 != NULL )
1716 free( buf );
1717
1718 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001719 return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001720 }
1721
1722 rsa->len = mpi_size( &rsa->N );
1723
1724 if( p != end )
1725 {
1726 if( s1 != NULL )
1727 free( buf );
1728
1729 rsa_free( rsa );
Paul Bakker40e46942009-01-03 21:51:57 +00001730 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT |
1731 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001732 }
1733
1734 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
1735 {
1736 if( s1 != NULL )
1737 free( buf );
1738
1739 rsa_free( rsa );
1740 return( ret );
1741 }
1742
1743 if( s1 != NULL )
1744 free( buf );
1745
1746 return( 0 );
1747}
1748
1749/*
1750 * Load and parse a private RSA key
1751 */
1752int x509parse_keyfile( rsa_context *rsa, char *path, char *pwd )
1753{
1754 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001755 size_t n;
1756 unsigned char *buf;
1757
Paul Bakker2b245eb2009-04-19 18:44:26 +00001758 if ( load_file( path, &buf, &n ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001759 return( 1 );
1760
Paul Bakker5121ce52009-01-03 21:22:43 +00001761 if( pwd == NULL )
1762 ret = x509parse_key( rsa, buf, (int) n, NULL, 0 );
1763 else
1764 ret = x509parse_key( rsa, buf, (int) n,
1765 (unsigned char *) pwd, strlen( pwd ) );
1766
1767 memset( buf, 0, n + 1 );
1768 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001769
1770 return( ret );
1771}
1772
1773#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00001774#include <stdarg.h>
1775
1776#if !defined vsnprintf
1777#define vsnprintf _vsnprintf
1778#endif // vsnprintf
1779
1780/*
1781 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
1782 * Result value is not size of buffer needed, but -1 if no fit is possible.
1783 *
1784 * This fuction tries to 'fix' this by at least suggesting enlarging the
1785 * size by 20.
1786 */
1787int compat_snprintf(char *str, size_t size, const char *format, ...)
1788{
1789 va_list ap;
1790 int res = -1;
1791
1792 va_start( ap, format );
1793
1794 res = vsnprintf( str, size, format, ap );
1795
1796 va_end( ap );
1797
1798 // No quick fix possible
1799 if ( res < 0 )
1800 return( size + 20 );
1801
1802 return res;
1803}
1804
1805#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00001806#endif
1807
Paul Bakkerd98030e2009-05-02 15:13:40 +00001808#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
1809
1810#define SAFE_SNPRINTF() \
1811{ \
1812 if( ret == -1 ) \
1813 return( -1 ); \
1814 \
1815 if ( ret > n ) { \
1816 p[n - 1] = '\0'; \
1817 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
1818 } \
1819 \
1820 n -= ret; \
1821 p += ret; \
1822}
1823
Paul Bakker5121ce52009-01-03 21:22:43 +00001824/*
1825 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00001826 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00001827 */
Paul Bakkerd98030e2009-05-02 15:13:40 +00001828int x509parse_dn_gets( char *buf, size_t size, x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00001829{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001830 int i, ret, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00001831 unsigned char c;
1832 x509_name *name;
1833 char s[128], *p;
1834
1835 memset( s, 0, sizeof( s ) );
1836
1837 name = dn;
1838 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001839 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00001840
1841 while( name != NULL )
1842 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001843 if( name != dn ) {
1844 ret = snprintf( p, n, ", " );
1845 SAFE_SNPRINTF();
1846 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001847
1848 if( memcmp( name->oid.p, OID_X520, 2 ) == 0 )
1849 {
1850 switch( name->oid.p[2] )
1851 {
1852 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001853 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001854
1855 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001856 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001857
1858 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001859 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001860
1861 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001862 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001863
1864 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001865 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001866
1867 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001868 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001869
1870 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001871 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00001872 name->oid.p[2] );
1873 break;
1874 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001875 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001876 }
1877 else if( memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
1878 {
1879 switch( name->oid.p[8] )
1880 {
1881 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001882 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00001883
1884 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00001885 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00001886 name->oid.p[8] );
1887 break;
1888 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001889 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001890 }
1891 else
Paul Bakkerd98030e2009-05-02 15:13:40 +00001892 {
1893 ret = snprintf( p, n, "\?\?=" );
1894 SAFE_SNPRINTF();
1895 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001896
1897 for( i = 0; i < name->val.len; i++ )
1898 {
1899 if( i >= (int) sizeof( s ) - 1 )
1900 break;
1901
1902 c = name->val.p[i];
1903 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
1904 s[i] = '?';
1905 else s[i] = c;
1906 }
1907 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00001908 ret = snprintf( p, n, "%s", s );
1909 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001910 name = name->next;
1911 }
1912
Paul Bakkerd98030e2009-05-02 15:13:40 +00001913 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001914}
1915
1916/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001917 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00001918 */
Paul Bakkerd98030e2009-05-02 15:13:40 +00001919int x509parse_cert_info( char *buf, size_t size, char *prefix, x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00001920{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001921 int i, n, nr, ret;
1922 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00001923
1924 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001925 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00001926
Paul Bakkerd98030e2009-05-02 15:13:40 +00001927 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00001928 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001929 SAFE_SNPRINTF();
1930 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00001931 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001932 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001933
Paul Bakkerd98030e2009-05-02 15:13:40 +00001934 nr = ( crt->serial.len <= 32 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001935 ? crt->serial.len : 32;
1936
Paul Bakkerd98030e2009-05-02 15:13:40 +00001937 for( i = 0; i < nr; i++ )
1938 {
1939 ret = snprintf( p, n, "%02X%s",
1940 crt->serial.p[i], ( i < nr - 1 ) ? ":" : "" );
1941 SAFE_SNPRINTF();
1942 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001943
Paul Bakkerd98030e2009-05-02 15:13:40 +00001944 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
1945 SAFE_SNPRINTF();
1946 ret = x509parse_dn_gets( p, n, &crt->issuer );
1947 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001948
Paul Bakkerd98030e2009-05-02 15:13:40 +00001949 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
1950 SAFE_SNPRINTF();
1951 ret = x509parse_dn_gets( p, n, &crt->subject );
1952 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001953
Paul Bakkerd98030e2009-05-02 15:13:40 +00001954 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00001955 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1956 crt->valid_from.year, crt->valid_from.mon,
1957 crt->valid_from.day, crt->valid_from.hour,
1958 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001959 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001960
Paul Bakkerd98030e2009-05-02 15:13:40 +00001961 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00001962 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1963 crt->valid_to.year, crt->valid_to.mon,
1964 crt->valid_to.day, crt->valid_to.hour,
1965 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001966 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001967
Paul Bakkerd98030e2009-05-02 15:13:40 +00001968 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
1969 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00001970
1971 switch( crt->sig_oid1.p[8] )
1972 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001973 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
1974 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
1975 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
1976 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
1977 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
1978 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
1979 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
1980 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
1981 default: ret = snprintf( p, n, "???" ); break;
1982 }
1983 SAFE_SNPRINTF();
1984
1985 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
1986 crt->rsa.N.n * (int) sizeof( unsigned long ) * 8 );
1987 SAFE_SNPRINTF();
1988
1989 return( size - n );
1990}
1991
1992/*
1993 * Return an informational string about the CRL.
1994 */
1995int x509parse_crl_info( char *buf, size_t size, char *prefix, x509_crl *crl )
1996{
1997 int i, n, nr, ret;
1998 char *p;
1999 x509_crl_entry *entry;
2000
2001 p = buf;
2002 n = size;
2003
2004 ret = snprintf( p, n, "%sCRL version : %d",
2005 prefix, crl->version );
2006 SAFE_SNPRINTF();
2007
2008 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2009 SAFE_SNPRINTF();
2010 ret = x509parse_dn_gets( p, n, &crl->issuer );
2011 SAFE_SNPRINTF();
2012
2013 ret = snprintf( p, n, "\n%sthis update : " \
2014 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2015 crl->this_update.year, crl->this_update.mon,
2016 crl->this_update.day, crl->this_update.hour,
2017 crl->this_update.min, crl->this_update.sec );
2018 SAFE_SNPRINTF();
2019
2020 ret = snprintf( p, n, "\n%snext update : " \
2021 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2022 crl->next_update.year, crl->next_update.mon,
2023 crl->next_update.day, crl->next_update.hour,
2024 crl->next_update.min, crl->next_update.sec );
2025 SAFE_SNPRINTF();
2026
2027 entry = &crl->entry;
2028
2029 ret = snprintf( p, n, "\n%sRevoked certificates:",
2030 prefix );
2031 SAFE_SNPRINTF();
2032
Paul Bakker9be19372009-07-27 20:21:53 +00002033 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002034 {
2035 ret = snprintf( p, n, "\n%sserial number: ",
2036 prefix );
2037 SAFE_SNPRINTF();
2038
2039 nr = ( entry->serial.len <= 32 )
2040 ? entry->serial.len : 32;
2041
2042 for( i = 0; i < nr; i++ ) {
2043 ret = snprintf( p, n, "%02X%s",
2044 entry->serial.p[i], ( i < nr - 1 ) ? ":" : "" );
2045 SAFE_SNPRINTF();
2046 }
2047
2048 ret = snprintf( p, n, " revocation date: " \
2049 "%04d-%02d-%02d %02d:%02d:%02d",
2050 entry->revocation_date.year, entry->revocation_date.mon,
2051 entry->revocation_date.day, entry->revocation_date.hour,
2052 entry->revocation_date.min, entry->revocation_date.sec );
2053 SAFE_SNPRINTF();
2054
2055 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002056 }
2057
Paul Bakkerd98030e2009-05-02 15:13:40 +00002058 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2059 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002060
Paul Bakkerd98030e2009-05-02 15:13:40 +00002061 switch( crl->sig_oid1.p[8] )
2062 {
2063 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2064 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2065 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2066 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2067 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2068 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2069 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2070 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2071 default: ret = snprintf( p, n, "???" ); break;
2072 }
2073 SAFE_SNPRINTF();
2074
Paul Bakker1e27bb22009-07-19 20:25:25 +00002075 ret = snprintf( p, n, "\n" );
2076 SAFE_SNPRINTF();
2077
Paul Bakkerd98030e2009-05-02 15:13:40 +00002078 return( size - n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002079}
2080
2081/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00002082 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00002083 */
Paul Bakker40ea7de2009-05-03 10:18:48 +00002084int x509parse_time_expired( x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00002085{
2086 struct tm *lt;
2087 time_t tt;
2088
2089 tt = time( NULL );
2090 lt = localtime( &tt );
2091
Paul Bakker40ea7de2009-05-03 10:18:48 +00002092 if( lt->tm_year > to->year - 1900 )
2093 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002094
Paul Bakker40ea7de2009-05-03 10:18:48 +00002095 if( lt->tm_year == to->year - 1900 &&
2096 lt->tm_mon > to->mon - 1 )
2097 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002098
Paul Bakker40ea7de2009-05-03 10:18:48 +00002099 if( lt->tm_year == to->year - 1900 &&
2100 lt->tm_mon == to->mon - 1 &&
2101 lt->tm_mday > to->day )
2102 return( 1 );
2103
2104 return( 0 );
2105}
2106
2107/*
2108 * Return 1 if the certificate is revoked, or 0 otherwise.
2109 */
2110int x509parse_revoked( x509_cert *crt, x509_crl *crl )
2111{
2112 x509_crl_entry *cur = &crl->entry;
2113
2114 while( cur != NULL && cur->serial.len != 0 )
2115 {
2116 if( memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
2117 {
2118 if( x509parse_time_expired( &cur->revocation_date ) )
2119 return( 1 );
2120 }
2121
2122 cur = cur->next;
2123 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002124
2125 return( 0 );
2126}
2127
2128static void x509_hash( unsigned char *in, int len, int alg,
2129 unsigned char *out )
2130{
2131 switch( alg )
2132 {
Paul Bakker40e46942009-01-03 21:51:57 +00002133#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002134 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002135#endif
Paul Bakker40e46942009-01-03 21:51:57 +00002136#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002137 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002138#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00002139 case SIG_RSA_MD5 : md5( in, len, out ); break;
2140 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
2141#if defined(POLARSSL_SHA2_C)
2142 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
2143 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
2144#endif
2145#if defined(POLARSSL_SHA2_C)
2146 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
2147 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
2148#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002149 default:
2150 memset( out, '\xFF', len );
2151 break;
2152 }
2153}
2154
2155/*
2156 * Verify the certificate validity
2157 */
2158int x509parse_verify( x509_cert *crt,
2159 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00002160 x509_crl *ca_crl,
Paul Bakker5121ce52009-01-03 21:22:43 +00002161 char *cn, int *flags )
2162{
2163 int cn_len;
2164 int hash_id;
2165 int pathlen;
2166 x509_cert *cur;
2167 x509_name *name;
Paul Bakker4593aea2009-02-09 22:32:35 +00002168 unsigned char hash[64];
Paul Bakker5121ce52009-01-03 21:22:43 +00002169
Paul Bakker40ea7de2009-05-03 10:18:48 +00002170 *flags = 0;
2171
2172 if( x509parse_time_expired( &crt->valid_to ) )
2173 *flags = BADCERT_EXPIRED;
Paul Bakker5121ce52009-01-03 21:22:43 +00002174
2175 if( cn != NULL )
2176 {
2177 name = &crt->subject;
2178 cn_len = strlen( cn );
2179
2180 while( name != NULL )
2181 {
2182 if( memcmp( name->oid.p, OID_CN, 3 ) == 0 &&
2183 memcmp( name->val.p, cn, cn_len ) == 0 &&
2184 name->val.len == cn_len )
2185 break;
2186
2187 name = name->next;
2188 }
2189
2190 if( name == NULL )
2191 *flags |= BADCERT_CN_MISMATCH;
2192 }
2193
2194 *flags |= BADCERT_NOT_TRUSTED;
2195
2196 /*
2197 * Iterate upwards in the given cert chain,
2198 * ignoring any upper cert with CA != TRUE.
2199 */
2200 cur = crt->next;
2201
2202 pathlen = 1;
2203
Paul Bakker7c6d4a42009-03-28 20:35:47 +00002204 while( cur != NULL && cur->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002205 {
2206 if( cur->ca_istrue == 0 ||
2207 crt->issuer_raw.len != cur->subject_raw.len ||
2208 memcmp( crt->issuer_raw.p, cur->subject_raw.p,
2209 crt->issuer_raw.len ) != 0 )
2210 {
2211 cur = cur->next;
2212 continue;
2213 }
2214
2215 hash_id = crt->sig_oid1.p[8];
2216
2217 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2218
2219 if( rsa_pkcs1_verify( &cur->rsa, RSA_PUBLIC, hash_id,
2220 0, hash, crt->sig.p ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00002221 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002222
2223 pathlen++;
2224
2225 crt = cur;
2226 cur = crt->next;
2227 }
2228
2229 /*
2230 * Atempt to validate topmost cert with our CA chain.
2231 */
Paul Bakker7c6d4a42009-03-28 20:35:47 +00002232 while( trust_ca != NULL && trust_ca->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002233 {
2234 if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
2235 memcmp( crt->issuer_raw.p, trust_ca->subject_raw.p,
2236 crt->issuer_raw.len ) != 0 )
2237 {
2238 trust_ca = trust_ca->next;
2239 continue;
2240 }
2241
2242 if( trust_ca->max_pathlen > 0 &&
2243 trust_ca->max_pathlen < pathlen )
2244 break;
2245
2246 hash_id = crt->sig_oid1.p[8];
2247
2248 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2249
2250 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
2251 0, hash, crt->sig.p ) == 0 )
2252 {
2253 /*
2254 * cert. is signed by a trusted CA
2255 */
2256 *flags &= ~BADCERT_NOT_TRUSTED;
2257 break;
2258 }
2259
2260 trust_ca = trust_ca->next;
2261 }
2262
Paul Bakker40ea7de2009-05-03 10:18:48 +00002263 /*
2264 * TODO: What happens if no CRL is present?
2265 * Suggestion: Revocation state should be unknown if no CRL is present.
2266 * For backwards compatibility this is not yet implemented.
2267 */
2268
2269 /*
2270 * Check if the topmost certificate is revoked if the trusted CA is
2271 * determined.
2272 */
2273 while( trust_ca != NULL && ca_crl != NULL && ca_crl->version != 0 )
2274 {
2275 if( ca_crl->issuer_raw.len != trust_ca->subject_raw.len ||
2276 memcmp( ca_crl->issuer_raw.p, trust_ca->subject_raw.p,
2277 ca_crl->issuer_raw.len ) != 0 )
2278 {
2279 ca_crl = ca_crl->next;
2280 continue;
2281 }
2282
2283 /*
2284 * Check if CRL is correctry signed by the trusted CA
2285 */
2286 hash_id = ca_crl->sig_oid1.p[8];
2287
2288 x509_hash( ca_crl->tbs.p, ca_crl->tbs.len, hash_id, hash );
2289
2290 if( !rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
2291 0, hash, ca_crl->sig.p ) == 0 )
2292 {
2293 /*
2294 * CRL is not trusted
2295 */
2296 *flags |= BADCRL_NOT_TRUSTED;
2297 break;
2298 }
2299
2300 /*
2301 * Check for validity of CRL (Do not drop out)
2302 */
2303 if( x509parse_time_expired( &ca_crl->next_update ) )
2304 *flags |= BADCRL_EXPIRED;
2305
2306 /*
2307 * Check if certificate is revoked
2308 */
2309 if( x509parse_revoked(crt, ca_crl) )
2310 {
2311 *flags |= BADCERT_REVOKED;
2312 break;
2313 }
2314
2315 ca_crl = ca_crl->next;
2316 }
2317
Paul Bakker5121ce52009-01-03 21:22:43 +00002318 if( *flags != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00002319 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002320
2321 return( 0 );
2322}
2323
2324/*
2325 * Unallocate all certificate data
2326 */
2327void x509_free( x509_cert *crt )
2328{
2329 x509_cert *cert_cur = crt;
2330 x509_cert *cert_prv;
2331 x509_name *name_cur;
2332 x509_name *name_prv;
2333
2334 if( crt == NULL )
2335 return;
2336
2337 do
2338 {
2339 rsa_free( &cert_cur->rsa );
2340
2341 name_cur = cert_cur->issuer.next;
2342 while( name_cur != NULL )
2343 {
2344 name_prv = name_cur;
2345 name_cur = name_cur->next;
2346 memset( name_prv, 0, sizeof( x509_name ) );
2347 free( name_prv );
2348 }
2349
2350 name_cur = cert_cur->subject.next;
2351 while( name_cur != NULL )
2352 {
2353 name_prv = name_cur;
2354 name_cur = name_cur->next;
2355 memset( name_prv, 0, sizeof( x509_name ) );
2356 free( name_prv );
2357 }
2358
2359 if( cert_cur->raw.p != NULL )
2360 {
2361 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
2362 free( cert_cur->raw.p );
2363 }
2364
2365 cert_cur = cert_cur->next;
2366 }
2367 while( cert_cur != NULL );
2368
2369 cert_cur = crt;
2370 do
2371 {
2372 cert_prv = cert_cur;
2373 cert_cur = cert_cur->next;
2374
2375 memset( cert_prv, 0, sizeof( x509_cert ) );
2376 if( cert_prv != crt )
2377 free( cert_prv );
2378 }
2379 while( cert_cur != NULL );
2380}
2381
Paul Bakkerd98030e2009-05-02 15:13:40 +00002382/*
2383 * Unallocate all CRL data
2384 */
2385void x509_crl_free( x509_crl *crl )
2386{
2387 x509_crl *crl_cur = crl;
2388 x509_crl *crl_prv;
2389 x509_name *name_cur;
2390 x509_name *name_prv;
2391 x509_crl_entry *entry_cur;
2392 x509_crl_entry *entry_prv;
2393
2394 if( crl == NULL )
2395 return;
2396
2397 do
2398 {
2399 name_cur = crl_cur->issuer.next;
2400 while( name_cur != NULL )
2401 {
2402 name_prv = name_cur;
2403 name_cur = name_cur->next;
2404 memset( name_prv, 0, sizeof( x509_name ) );
2405 free( name_prv );
2406 }
2407
2408 entry_cur = crl_cur->entry.next;
2409 while( entry_cur != NULL )
2410 {
2411 entry_prv = entry_cur;
2412 entry_cur = entry_cur->next;
2413 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
2414 free( entry_prv );
2415 }
2416
2417 if( crl_cur->raw.p != NULL )
2418 {
2419 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
2420 free( crl_cur->raw.p );
2421 }
2422
2423 crl_cur = crl_cur->next;
2424 }
2425 while( crl_cur != NULL );
2426
2427 crl_cur = crl;
2428 do
2429 {
2430 crl_prv = crl_cur;
2431 crl_cur = crl_cur->next;
2432
2433 memset( crl_prv, 0, sizeof( x509_crl ) );
2434 if( crl_prv != crl )
2435 free( crl_prv );
2436 }
2437 while( crl_cur != NULL );
2438}
2439
Paul Bakker40e46942009-01-03 21:51:57 +00002440#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002441
Paul Bakker40e46942009-01-03 21:51:57 +00002442#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00002443
2444/*
2445 * Checkup routine
2446 */
2447int x509_self_test( int verbose )
2448{
2449 int ret, i, j;
2450 x509_cert cacert;
2451 x509_cert clicert;
2452 rsa_context rsa;
2453
2454 if( verbose != 0 )
2455 printf( " X.509 certificate load: " );
2456
2457 memset( &clicert, 0, sizeof( x509_cert ) );
2458
2459 ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
2460 strlen( test_cli_crt ) );
2461 if( ret != 0 )
2462 {
2463 if( verbose != 0 )
2464 printf( "failed\n" );
2465
2466 return( ret );
2467 }
2468
2469 memset( &cacert, 0, sizeof( x509_cert ) );
2470
2471 ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
2472 strlen( test_ca_crt ) );
2473 if( ret != 0 )
2474 {
2475 if( verbose != 0 )
2476 printf( "failed\n" );
2477
2478 return( ret );
2479 }
2480
2481 if( verbose != 0 )
2482 printf( "passed\n X.509 private key load: " );
2483
2484 i = strlen( test_ca_key );
2485 j = strlen( test_ca_pwd );
2486
2487 if( ( ret = x509parse_key( &rsa,
2488 (unsigned char *) test_ca_key, i,
2489 (unsigned char *) test_ca_pwd, j ) ) != 0 )
2490 {
2491 if( verbose != 0 )
2492 printf( "failed\n" );
2493
2494 return( ret );
2495 }
2496
2497 if( verbose != 0 )
2498 printf( "passed\n X.509 signature verify: ");
2499
Paul Bakker1973e4c2009-07-10 22:32:40 +00002500 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &i );
Paul Bakker5121ce52009-01-03 21:22:43 +00002501 if( ret != 0 )
2502 {
2503 if( verbose != 0 )
2504 printf( "failed\n" );
2505
2506 return( ret );
2507 }
2508
2509 if( verbose != 0 )
2510 printf( "passed\n\n" );
2511
2512 x509_free( &cacert );
2513 x509_free( &clicert );
2514 rsa_free( &rsa );
2515
2516 return( 0 );
2517}
2518
2519#endif
2520
2521#endif