blob: bdafb22ea894697d3b8375c31b91cd8957766a7c [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * X.509 certificate and private key decoding
3 *
Paul Bakker84f12b72010-07-18 10:13:04 +00004 * Copyright (C) 2006-2010, Brainspark B.V.
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
Paul Bakker84f12b72010-07-18 10:13:04 +00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakkerb96f1542010-07-18 20:36:00 +00008 *
Paul Bakker77b385e2009-07-28 17:23:11 +00009 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +000010 *
Paul Bakker5121ce52009-01-03 21:22:43 +000011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25/*
26 * The ITU-T X.509 standard defines a certificat format for PKI.
27 *
28 * http://www.ietf.org/rfc/rfc2459.txt
29 * http://www.ietf.org/rfc/rfc3279.txt
30 *
31 * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
32 *
33 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
34 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
35 */
36
Paul Bakker40e46942009-01-03 21:51:57 +000037#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000038
Paul Bakker40e46942009-01-03 21:51:57 +000039#if defined(POLARSSL_X509_PARSE_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000040
Paul Bakker40e46942009-01-03 21:51:57 +000041#include "polarssl/x509.h"
Paul Bakker96743fc2011-02-12 14:30:57 +000042#include "polarssl/pem.h"
Paul Bakker40e46942009-01-03 21:51:57 +000043#include "polarssl/des.h"
44#include "polarssl/md2.h"
45#include "polarssl/md4.h"
46#include "polarssl/md5.h"
47#include "polarssl/sha1.h"
Paul Bakker026c03b2009-03-28 17:53:03 +000048#include "polarssl/sha2.h"
49#include "polarssl/sha4.h"
Paul Bakker1b57b062011-01-06 15:48:19 +000050#include "polarssl/dhm.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000051
52#include <string.h>
53#include <stdlib.h>
Paul Bakker5121ce52009-01-03 21:22:43 +000054#include <time.h>
55
Paul Bakker335db3f2011-04-25 15:28:35 +000056#if defined(POLARSSL_FS_IO)
57#include <stdio.h>
58#endif
59
Paul Bakker5121ce52009-01-03 21:22:43 +000060/*
61 * ASN.1 DER decoding routines
62 */
63static int asn1_get_len( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +000064 const unsigned char *end,
Paul Bakker23986e52011-04-24 08:57:21 +000065 size_t *len )
Paul Bakker5121ce52009-01-03 21:22:43 +000066{
67 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +000068 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000069
70 if( ( **p & 0x80 ) == 0 )
71 *len = *(*p)++;
72 else
73 {
74 switch( **p & 0x7F )
75 {
76 case 1:
77 if( ( end - *p ) < 2 )
Paul Bakker40e46942009-01-03 21:51:57 +000078 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000079
80 *len = (*p)[1];
81 (*p) += 2;
82 break;
83
84 case 2:
85 if( ( end - *p ) < 3 )
Paul Bakker40e46942009-01-03 21:51:57 +000086 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000087
88 *len = ( (*p)[1] << 8 ) | (*p)[2];
89 (*p) += 3;
90 break;
91
Paul Bakkerc4909d92011-10-12 09:52:22 +000092 case 3:
93 if( ( end - *p ) < 4 )
94 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
95
96 *len = ( (*p)[1] << 16 ) | ( (*p)[2] << 8 ) | (*p)[3];
97 (*p) += 4;
98 break;
99
100 case 4:
101 if( ( end - *p ) < 5 )
102 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
103
104 *len = ( (*p)[1] << 24 ) | ( (*p)[2] << 16 ) | ( (*p)[3] << 8 ) | (*p)[4];
105 (*p) += 5;
106 break;
107
Paul Bakker5121ce52009-01-03 21:22:43 +0000108 default:
Paul Bakker40e46942009-01-03 21:51:57 +0000109 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000110 }
111 }
112
Paul Bakker23986e52011-04-24 08:57:21 +0000113 if( *len > (size_t) ( end - *p ) )
Paul Bakker40e46942009-01-03 21:51:57 +0000114 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000115
116 return( 0 );
117}
118
119static int asn1_get_tag( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000120 const unsigned char *end,
Paul Bakker23986e52011-04-24 08:57:21 +0000121 size_t *len, int tag )
Paul Bakker5121ce52009-01-03 21:22:43 +0000122{
123 if( ( end - *p ) < 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000124 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000125
126 if( **p != tag )
Paul Bakker40e46942009-01-03 21:51:57 +0000127 return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000128
129 (*p)++;
130
131 return( asn1_get_len( p, end, len ) );
132}
133
134static int asn1_get_bool( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000135 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000136 int *val )
137{
Paul Bakker23986e52011-04-24 08:57:21 +0000138 int ret;
139 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000140
141 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 )
142 return( ret );
143
144 if( len != 1 )
Paul Bakker40e46942009-01-03 21:51:57 +0000145 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000146
147 *val = ( **p != 0 ) ? 1 : 0;
148 (*p)++;
149
150 return( 0 );
151}
152
153static int asn1_get_int( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000154 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000155 int *val )
156{
Paul Bakker23986e52011-04-24 08:57:21 +0000157 int ret;
158 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000159
160 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
161 return( ret );
162
Paul Bakker27fdf462011-06-09 13:55:13 +0000163 if( len > sizeof( int ) || ( **p & 0x80 ) != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000164 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000165
166 *val = 0;
167
168 while( len-- > 0 )
169 {
170 *val = ( *val << 8 ) | **p;
171 (*p)++;
172 }
173
174 return( 0 );
175}
176
177static int asn1_get_mpi( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000178 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000179 mpi *X )
180{
Paul Bakker23986e52011-04-24 08:57:21 +0000181 int ret;
182 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000183
184 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
185 return( ret );
186
187 ret = mpi_read_binary( X, *p, len );
188
189 *p += len;
190
191 return( ret );
192}
193
Paul Bakker74111d32011-01-15 16:57:55 +0000194static int asn1_get_bitstring( unsigned char **p, const unsigned char *end,
195 x509_bitstring *bs)
196{
197 int ret;
198
199 /* Certificate type is a single byte bitstring */
200 if( ( ret = asn1_get_tag( p, end, &bs->len, ASN1_BIT_STRING ) ) != 0 )
201 return( ret );
202
203 /* Check length, subtract one for actual bit string length */
204 if ( bs->len < 1 )
205 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
206 bs->len -= 1;
207
208 /* Get number of unused bits, ensure unused bits <= 7 */
209 bs->unused_bits = **p;
210 if( bs->unused_bits > 7 )
211 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
212 (*p)++;
213
214 /* Get actual bitstring */
215 bs->p = *p;
216 *p += bs->len;
217
218 if( *p != end )
219 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
220
221 return 0;
222}
223
224
225/*
226 * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
227 */
228static int asn1_get_sequence_of( unsigned char **p,
229 const unsigned char *end,
230 x509_sequence *cur,
231 int tag)
232{
Paul Bakker23986e52011-04-24 08:57:21 +0000233 int ret;
234 size_t len;
Paul Bakker74111d32011-01-15 16:57:55 +0000235 x509_buf *buf;
236
237 /* Get main sequence tag */
238 if( ( ret = asn1_get_tag( p, end, &len,
239 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
240 return( ret );
241
242 if( *p + len != end )
243 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
244
245 while( *p < end )
246 {
247 buf = &(cur->buf);
248 buf->tag = **p;
249
250 if( ( ret = asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
251 return( ret );
252
253 buf->p = *p;
254 *p += buf->len;
255
256 /* Allocate and assign next pointer */
257 if (*p < end)
258 {
259 cur->next = (x509_sequence *) malloc(
260 sizeof( x509_sequence ) );
261
262 if( cur->next == NULL )
263 return( 1 );
264
265 cur = cur->next;
266 }
267 }
268
269 /* Set final sequence entry's next pointer to NULL */
270 cur->next = NULL;
271
272 if( *p != end )
273 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
274
275 return( 0 );
276}
277
Paul Bakker5121ce52009-01-03 21:22:43 +0000278/*
279 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
280 */
281static int x509_get_version( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000282 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000283 int *ver )
284{
Paul Bakker23986e52011-04-24 08:57:21 +0000285 int ret;
286 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000287
288 if( ( ret = asn1_get_tag( p, end, &len,
289 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
290 {
Paul Bakker40e46942009-01-03 21:51:57 +0000291 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000292 return( *ver = 0 );
293
294 return( ret );
295 }
296
297 end = *p + len;
298
299 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000300 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000301
302 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000303 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION +
Paul Bakker40e46942009-01-03 21:51:57 +0000304 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000305
306 return( 0 );
307}
308
309/*
Paul Bakker3329d1f2011-10-12 09:55:01 +0000310 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
311 */
312static int x509_crl_get_version( unsigned char **p,
313 const unsigned char *end,
314 int *ver )
315{
316 int ret;
317
318 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
319 {
320 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
321 return( *ver = 0 );
322
323 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
324 }
325
326 return( 0 );
327}
328
329/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000330 * CertificateSerialNumber ::= INTEGER
331 */
332static int x509_get_serial( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000333 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000334 x509_buf *serial )
335{
336 int ret;
337
338 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000339 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000340 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000341
342 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
343 **p != ASN1_INTEGER )
Paul Bakker9d781402011-05-09 16:17:09 +0000344 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000345 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000346
347 serial->tag = *(*p)++;
348
349 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000350 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000351
352 serial->p = *p;
353 *p += serial->len;
354
355 return( 0 );
356}
357
358/*
359 * AlgorithmIdentifier ::= SEQUENCE {
360 * algorithm OBJECT IDENTIFIER,
361 * parameters ANY DEFINED BY algorithm OPTIONAL }
362 */
363static int x509_get_alg( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000364 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000365 x509_buf *alg )
366{
Paul Bakker23986e52011-04-24 08:57:21 +0000367 int ret;
368 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000369
370 if( ( ret = asn1_get_tag( p, end, &len,
371 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000372 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000373
374 end = *p + len;
375 alg->tag = **p;
376
377 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000378 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000379
380 alg->p = *p;
381 *p += alg->len;
382
383 if( *p == end )
384 return( 0 );
385
386 /*
387 * assume the algorithm parameters must be NULL
388 */
389 if( ( ret = asn1_get_tag( p, end, &len, ASN1_NULL ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000390 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000391
392 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000393 return( POLARSSL_ERR_X509_CERT_INVALID_ALG +
Paul Bakker40e46942009-01-03 21:51:57 +0000394 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000395
396 return( 0 );
397}
398
399/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000400 * AttributeTypeAndValue ::= SEQUENCE {
401 * type AttributeType,
402 * value AttributeValue }
403 *
404 * AttributeType ::= OBJECT IDENTIFIER
405 *
406 * AttributeValue ::= ANY DEFINED BY AttributeType
407 */
Paul Bakker400ff6f2011-02-20 10:40:16 +0000408static int x509_get_attr_type_value( unsigned char **p,
409 const unsigned char *end,
410 x509_name *cur )
Paul Bakker5121ce52009-01-03 21:22:43 +0000411{
Paul Bakker23986e52011-04-24 08:57:21 +0000412 int ret;
413 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000414 x509_buf *oid;
415 x509_buf *val;
416
417 if( ( ret = asn1_get_tag( p, end, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000418 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000419 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000420
Paul Bakker5121ce52009-01-03 21:22:43 +0000421 oid = &cur->oid;
422 oid->tag = **p;
423
424 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000425 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000426
427 oid->p = *p;
428 *p += oid->len;
429
430 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000431 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000432 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000433
434 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
435 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
436 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker9d781402011-05-09 16:17:09 +0000437 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000438 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000439
440 val = &cur->val;
441 val->tag = *(*p)++;
442
443 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000444 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000445
446 val->p = *p;
447 *p += val->len;
448
449 cur->next = NULL;
450
Paul Bakker400ff6f2011-02-20 10:40:16 +0000451 return( 0 );
452}
453
454/*
455 * RelativeDistinguishedName ::=
456 * SET OF AttributeTypeAndValue
457 *
458 * AttributeTypeAndValue ::= SEQUENCE {
459 * type AttributeType,
460 * value AttributeValue }
461 *
462 * AttributeType ::= OBJECT IDENTIFIER
463 *
464 * AttributeValue ::= ANY DEFINED BY AttributeType
465 */
466static int x509_get_name( unsigned char **p,
467 const unsigned char *end,
468 x509_name *cur )
469{
Paul Bakker23986e52011-04-24 08:57:21 +0000470 int ret;
471 size_t len;
Paul Bakker400ff6f2011-02-20 10:40:16 +0000472 const unsigned char *end2;
473 x509_name *use;
474
475 if( ( ret = asn1_get_tag( p, end, &len,
476 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000477 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000478
479 end2 = end;
480 end = *p + len;
481 use = cur;
482
483 do
484 {
485 if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
486 return( ret );
487
488 if( *p != end )
489 {
490 use->next = (x509_name *) malloc(
491 sizeof( x509_name ) );
492
493 if( use->next == NULL )
494 return( 1 );
495
496 memset( use->next, 0, sizeof( x509_name ) );
497
498 use = use->next;
499 }
500 }
501 while( *p != end );
Paul Bakker5121ce52009-01-03 21:22:43 +0000502
503 /*
504 * recurse until end of SEQUENCE is reached
505 */
506 if( *p == end2 )
507 return( 0 );
508
509 cur->next = (x509_name *) malloc(
510 sizeof( x509_name ) );
511
512 if( cur->next == NULL )
513 return( 1 );
514
515 return( x509_get_name( p, end2, cur->next ) );
516}
517
518/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000519 * Time ::= CHOICE {
520 * utcTime UTCTime,
521 * generalTime GeneralizedTime }
522 */
Paul Bakker91200182010-02-18 21:26:15 +0000523static int x509_get_time( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000524 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000525 x509_time *time )
526{
Paul Bakker23986e52011-04-24 08:57:21 +0000527 int ret;
528 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000529 char date[64];
Paul Bakker91200182010-02-18 21:26:15 +0000530 unsigned char tag;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000531
Paul Bakker91200182010-02-18 21:26:15 +0000532 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000533 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
534 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000535
Paul Bakker91200182010-02-18 21:26:15 +0000536 tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000537
Paul Bakker91200182010-02-18 21:26:15 +0000538 if ( tag == ASN1_UTC_TIME )
539 {
540 (*p)++;
541 ret = asn1_get_len( p, end, &len );
542
543 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000544 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000545
Paul Bakker91200182010-02-18 21:26:15 +0000546 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000547 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
548 len : sizeof( date ) - 1 );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000549
Paul Bakker91200182010-02-18 21:26:15 +0000550 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
551 &time->year, &time->mon, &time->day,
552 &time->hour, &time->min, &time->sec ) < 5 )
553 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000554
Paul Bakker400ff6f2011-02-20 10:40:16 +0000555 time->year += 100 * ( time->year < 50 );
Paul Bakker91200182010-02-18 21:26:15 +0000556 time->year += 1900;
557
558 *p += len;
559
560 return( 0 );
561 }
562 else if ( tag == ASN1_GENERALIZED_TIME )
563 {
564 (*p)++;
565 ret = asn1_get_len( p, end, &len );
566
567 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000568 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker91200182010-02-18 21:26:15 +0000569
570 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000571 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
572 len : sizeof( date ) - 1 );
Paul Bakker91200182010-02-18 21:26:15 +0000573
574 if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
575 &time->year, &time->mon, &time->day,
576 &time->hour, &time->min, &time->sec ) < 5 )
577 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
578
579 *p += len;
580
581 return( 0 );
582 }
583 else
Paul Bakker9d781402011-05-09 16:17:09 +0000584 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000585}
586
587
588/*
589 * Validity ::= SEQUENCE {
590 * notBefore Time,
591 * notAfter Time }
592 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000593static int x509_get_dates( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000594 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000595 x509_time *from,
596 x509_time *to )
597{
Paul Bakker23986e52011-04-24 08:57:21 +0000598 int ret;
599 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000600
601 if( ( ret = asn1_get_tag( p, end, &len,
602 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000603 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000604
605 end = *p + len;
606
Paul Bakker91200182010-02-18 21:26:15 +0000607 if( ( ret = x509_get_time( p, end, from ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000608 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000609
Paul Bakker91200182010-02-18 21:26:15 +0000610 if( ( ret = x509_get_time( p, end, to ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000611 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000612
613 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000614 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker40e46942009-01-03 21:51:57 +0000615 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000616
617 return( 0 );
618}
619
620/*
621 * SubjectPublicKeyInfo ::= SEQUENCE {
622 * algorithm AlgorithmIdentifier,
623 * subjectPublicKey BIT STRING }
624 */
625static int x509_get_pubkey( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000626 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000627 x509_buf *pk_alg_oid,
628 mpi *N, mpi *E )
629{
Paul Bakker23986e52011-04-24 08:57:21 +0000630 int ret, can_handle;
631 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000632 unsigned char *end2;
633
634 if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 )
635 return( ret );
636
637 /*
638 * only RSA public keys handled at this time
639 */
Paul Bakker400ff6f2011-02-20 10:40:16 +0000640 can_handle = 0;
641
642 if( pk_alg_oid->len == 9 &&
643 memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) == 0 )
644 can_handle = 1;
645
646 if( pk_alg_oid->len == 9 &&
647 memcmp( pk_alg_oid->p, OID_PKCS1, 8 ) == 0 )
648 {
649 if( pk_alg_oid->p[8] >= 2 && pk_alg_oid->p[8] <= 5 )
650 can_handle = 1;
651
652 if ( pk_alg_oid->p[8] >= 11 && pk_alg_oid->p[8] <= 14 )
653 can_handle = 1;
654 }
655
656 if( pk_alg_oid->len == 5 &&
657 memcmp( pk_alg_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
658 can_handle = 1;
659
660 if( can_handle == 0 )
Paul Bakkered56b222011-07-13 11:26:43 +0000661 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000662
663 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000664 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000665
666 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000667 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000668 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000669
670 end2 = *p + len;
671
672 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000673 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000674
675 /*
676 * RSAPublicKey ::= SEQUENCE {
677 * modulus INTEGER, -- n
678 * publicExponent INTEGER -- e
679 * }
680 */
681 if( ( ret = asn1_get_tag( p, end2, &len,
682 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000683 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000684
685 if( *p + len != end2 )
Paul Bakker9d781402011-05-09 16:17:09 +0000686 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000687 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000688
689 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
690 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000691 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000692
693 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000694 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000695 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000696
697 return( 0 );
698}
699
700static int x509_get_sig( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000701 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000702 x509_buf *sig )
703{
Paul Bakker23986e52011-04-24 08:57:21 +0000704 int ret;
705 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000706
707 sig->tag = **p;
708
709 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000710 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000711
Paul Bakker74111d32011-01-15 16:57:55 +0000712
Paul Bakker5121ce52009-01-03 21:22:43 +0000713 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000714 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000715
716 sig->len = len;
717 sig->p = *p;
718
719 *p += len;
720
721 return( 0 );
722}
723
724/*
725 * X.509 v2/v3 unique identifier (not parsed)
726 */
727static int x509_get_uid( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000728 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000729 x509_buf *uid, int n )
730{
731 int ret;
732
733 if( *p == end )
734 return( 0 );
735
736 uid->tag = **p;
737
738 if( ( ret = asn1_get_tag( p, end, &uid->len,
739 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
740 {
Paul Bakker40e46942009-01-03 21:51:57 +0000741 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000742 return( 0 );
743
744 return( ret );
745 }
746
747 uid->p = *p;
748 *p += uid->len;
749
750 return( 0 );
751}
752
753/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000754 * X.509 Extensions (No parsing of extensions, pointer should
755 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000756 */
757static int x509_get_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000758 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000759 x509_buf *ext )
Paul Bakker5121ce52009-01-03 21:22:43 +0000760{
Paul Bakker23986e52011-04-24 08:57:21 +0000761 int ret;
762 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000763
764 if( *p == end )
765 return( 0 );
766
767 ext->tag = **p;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000768
Paul Bakker5121ce52009-01-03 21:22:43 +0000769 if( ( ret = asn1_get_tag( p, end, &ext->len,
770 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000771 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000772
773 ext->p = *p;
774 end = *p + ext->len;
775
776 /*
777 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
778 *
779 * Extension ::= SEQUENCE {
780 * extnID OBJECT IDENTIFIER,
781 * critical BOOLEAN DEFAULT FALSE,
782 * extnValue OCTET STRING }
783 */
784 if( ( ret = asn1_get_tag( p, end, &len,
785 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000786 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000787
788 if( end != *p + len )
Paul Bakker9d781402011-05-09 16:17:09 +0000789 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +0000790 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000791
Paul Bakkerd98030e2009-05-02 15:13:40 +0000792 return( 0 );
793}
794
795/*
796 * X.509 CRL v2 extensions (no extensions parsed yet.)
797 */
798static int x509_get_crl_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000799 const unsigned char *end,
800 x509_buf *ext )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000801{
Paul Bakker23986e52011-04-24 08:57:21 +0000802 int ret;
803 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000804
805 if( ( ret = x509_get_ext( p, end, ext ) ) != 0 )
806 {
807 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
808 return( 0 );
809
810 return( ret );
811 }
812
813 while( *p < end )
814 {
815 if( ( ret = asn1_get_tag( p, end, &len,
816 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000817 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000818
819 *p += len;
820 }
821
822 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000823 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerd98030e2009-05-02 15:13:40 +0000824 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
825
826 return( 0 );
827}
828
Paul Bakker74111d32011-01-15 16:57:55 +0000829static int x509_get_basic_constraints( unsigned char **p,
830 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000831 int *ca_istrue,
832 int *max_pathlen )
833{
Paul Bakker23986e52011-04-24 08:57:21 +0000834 int ret;
835 size_t len;
Paul Bakker74111d32011-01-15 16:57:55 +0000836
837 /*
838 * BasicConstraints ::= SEQUENCE {
839 * cA BOOLEAN DEFAULT FALSE,
840 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
841 */
Paul Bakker3cccddb2011-01-16 21:46:31 +0000842 *ca_istrue = 0; /* DEFAULT FALSE */
Paul Bakker74111d32011-01-15 16:57:55 +0000843 *max_pathlen = 0; /* endless */
844
845 if( ( ret = asn1_get_tag( p, end, &len,
846 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000847 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000848
849 if( *p == end )
850 return 0;
851
Paul Bakker3cccddb2011-01-16 21:46:31 +0000852 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000853 {
854 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker3cccddb2011-01-16 21:46:31 +0000855 ret = asn1_get_int( p, end, ca_istrue );
Paul Bakker74111d32011-01-15 16:57:55 +0000856
857 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000858 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000859
Paul Bakker3cccddb2011-01-16 21:46:31 +0000860 if( *ca_istrue != 0 )
861 *ca_istrue = 1;
Paul Bakker74111d32011-01-15 16:57:55 +0000862 }
863
864 if( *p == end )
865 return 0;
866
867 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000868 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000869
870 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000871 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000872 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
873
874 (*max_pathlen)++;
875
Paul Bakker74111d32011-01-15 16:57:55 +0000876 return 0;
877}
878
879static int x509_get_ns_cert_type( unsigned char **p,
880 const unsigned char *end,
881 unsigned char *ns_cert_type)
882{
883 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000884 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000885
886 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000887 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000888
889 if( bs.len != 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000890 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000891 POLARSSL_ERR_ASN1_INVALID_LENGTH );
892
893 /* Get actual bitstring */
894 *ns_cert_type = *bs.p;
895 return 0;
896}
897
898static int x509_get_key_usage( unsigned char **p,
899 const unsigned char *end,
900 unsigned char *key_usage)
901{
902 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000903 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000904
905 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000906 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000907
908 if( bs.len != 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000909 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000910 POLARSSL_ERR_ASN1_INVALID_LENGTH );
911
912 /* Get actual bitstring */
913 *key_usage = *bs.p;
914 return 0;
915}
916
Paul Bakkerd98030e2009-05-02 15:13:40 +0000917/*
Paul Bakker74111d32011-01-15 16:57:55 +0000918 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
919 *
920 * KeyPurposeId ::= OBJECT IDENTIFIER
921 */
922static int x509_get_ext_key_usage( unsigned char **p,
923 const unsigned char *end,
924 x509_sequence *ext_key_usage)
925{
926 int ret;
927
928 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000929 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000930
931 /* Sequence length must be >= 1 */
932 if( ext_key_usage->buf.p == NULL )
Paul Bakker9d781402011-05-09 16:17:09 +0000933 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000934 POLARSSL_ERR_ASN1_INVALID_LENGTH );
935
936 return 0;
937}
938
939/*
940 * X.509 v3 extensions
941 *
942 * TODO: Perform all of the basic constraints tests required by the RFC
943 * TODO: Set values for undetected extensions to a sane default?
944 *
Paul Bakkerd98030e2009-05-02 15:13:40 +0000945 */
946static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000947 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000948 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000949{
Paul Bakker23986e52011-04-24 08:57:21 +0000950 int ret;
951 size_t len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000952 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000953
Paul Bakker74111d32011-01-15 16:57:55 +0000954 if( ( ret = x509_get_ext( p, end, &crt->v3_ext ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000955 {
956 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
957 return( 0 );
958
959 return( ret );
960 }
961
Paul Bakker5121ce52009-01-03 21:22:43 +0000962 while( *p < end )
963 {
Paul Bakker74111d32011-01-15 16:57:55 +0000964 /*
965 * Extension ::= SEQUENCE {
966 * extnID OBJECT IDENTIFIER,
967 * critical BOOLEAN DEFAULT FALSE,
968 * extnValue OCTET STRING }
969 */
970 x509_buf extn_oid = {0, 0, NULL};
971 int is_critical = 0; /* DEFAULT FALSE */
972
Paul Bakker5121ce52009-01-03 21:22:43 +0000973 if( ( ret = asn1_get_tag( p, end, &len,
974 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000975 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000976
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000977 end_ext_data = *p + len;
978
Paul Bakker74111d32011-01-15 16:57:55 +0000979 /* Get extension ID */
980 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000981
Paul Bakker74111d32011-01-15 16:57:55 +0000982 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000983 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000984
Paul Bakker74111d32011-01-15 16:57:55 +0000985 extn_oid.p = *p;
986 *p += extn_oid.len;
987
988 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000989 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000990 POLARSSL_ERR_ASN1_OUT_OF_DATA );
991
992 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000993 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000994 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
Paul Bakker9d781402011-05-09 16:17:09 +0000995 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000996
Paul Bakker74111d32011-01-15 16:57:55 +0000997 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000998 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000999 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +00001000 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001001
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001002 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +00001003
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001004 if( end_ext_octet != end_ext_data )
Paul Bakker9d781402011-05-09 16:17:09 +00001005 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001006 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001007
Paul Bakker74111d32011-01-15 16:57:55 +00001008 /*
1009 * Detect supported extensions
1010 */
1011 if( ( OID_SIZE( OID_BASIC_CONSTRAINTS ) == extn_oid.len ) &&
1012 memcmp( extn_oid.p, OID_BASIC_CONSTRAINTS, extn_oid.len ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001013 {
Paul Bakker74111d32011-01-15 16:57:55 +00001014 /* Parse basic constraints */
1015 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
Paul Bakker3cccddb2011-01-16 21:46:31 +00001016 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +00001017 return ( ret );
1018 crt->ext_types |= EXT_BASIC_CONSTRAINTS;
Paul Bakker5121ce52009-01-03 21:22:43 +00001019 }
Paul Bakker74111d32011-01-15 16:57:55 +00001020 else if( ( OID_SIZE( OID_NS_CERT_TYPE ) == extn_oid.len ) &&
1021 memcmp( extn_oid.p, OID_NS_CERT_TYPE, extn_oid.len ) == 0 )
1022 {
1023 /* Parse netscape certificate type */
1024 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
1025 &crt->ns_cert_type ) ) != 0 )
1026 return ( ret );
1027 crt->ext_types |= EXT_NS_CERT_TYPE;
1028 }
1029 else if( ( OID_SIZE( OID_KEY_USAGE ) == extn_oid.len ) &&
1030 memcmp( extn_oid.p, OID_KEY_USAGE, extn_oid.len ) == 0 )
1031 {
1032 /* Parse key usage */
1033 if( ( ret = x509_get_key_usage( p, end_ext_octet,
1034 &crt->key_usage ) ) != 0 )
1035 return ( ret );
1036 crt->ext_types |= EXT_KEY_USAGE;
1037 }
1038 else if( ( OID_SIZE( OID_EXTENDED_KEY_USAGE ) == extn_oid.len ) &&
1039 memcmp( extn_oid.p, OID_EXTENDED_KEY_USAGE, extn_oid.len ) == 0 )
1040 {
1041 /* Parse extended key usage */
1042 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
1043 &crt->ext_key_usage ) ) != 0 )
1044 return ( ret );
1045 crt->ext_types |= EXT_EXTENDED_KEY_USAGE;
1046 }
1047 else
1048 {
1049 /* No parser found, skip extension */
1050 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +00001051
Paul Bakker5c721f92011-07-27 16:51:09 +00001052#if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
Paul Bakker74111d32011-01-15 16:57:55 +00001053 if( is_critical )
1054 {
1055 /* Data is marked as critical: fail */
Paul Bakker9d781402011-05-09 16:17:09 +00001056 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +00001057 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
1058 }
Paul Bakker5c721f92011-07-27 16:51:09 +00001059#endif
Paul Bakker74111d32011-01-15 16:57:55 +00001060 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001061 }
1062
1063 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +00001064 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +00001065 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001066
Paul Bakker5121ce52009-01-03 21:22:43 +00001067 return( 0 );
1068}
1069
1070/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001071 * X.509 CRL Entries
1072 */
1073static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001074 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001075 x509_crl_entry *entry )
1076{
Paul Bakker23986e52011-04-24 08:57:21 +00001077 int ret;
1078 size_t entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001079 x509_crl_entry *cur_entry = entry;
1080
1081 if( *p == end )
1082 return( 0 );
1083
Paul Bakker9be19372009-07-27 20:21:53 +00001084 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001085 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1086 {
1087 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
1088 return( 0 );
1089
1090 return( ret );
1091 }
1092
Paul Bakker9be19372009-07-27 20:21:53 +00001093 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001094
1095 while( *p < end )
1096 {
Paul Bakker23986e52011-04-24 08:57:21 +00001097 size_t len2;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001098
1099 if( ( ret = asn1_get_tag( p, end, &len2,
1100 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1101 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001102 return( ret );
1103 }
1104
Paul Bakker9be19372009-07-27 20:21:53 +00001105 cur_entry->raw.tag = **p;
1106 cur_entry->raw.p = *p;
1107 cur_entry->raw.len = len2;
1108
Paul Bakkerd98030e2009-05-02 15:13:40 +00001109 if( ( ret = x509_get_serial( p, end, &cur_entry->serial ) ) != 0 )
1110 return( ret );
1111
Paul Bakker91200182010-02-18 21:26:15 +00001112 if( ( ret = x509_get_time( p, end, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001113 return( ret );
1114
1115 if( ( ret = x509_get_crl_ext( p, end, &cur_entry->entry_ext ) ) != 0 )
1116 return( ret );
1117
Paul Bakker74111d32011-01-15 16:57:55 +00001118 if ( *p < end )
1119 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001120 cur_entry->next = malloc( sizeof( x509_crl_entry ) );
1121 cur_entry = cur_entry->next;
1122 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
1123 }
1124 }
1125
1126 return( 0 );
1127}
1128
Paul Bakker27d66162010-03-17 06:56:01 +00001129static int x509_get_sig_alg( const x509_buf *sig_oid, int *sig_alg )
1130{
1131 if( sig_oid->len == 9 &&
1132 memcmp( sig_oid->p, OID_PKCS1, 8 ) == 0 )
1133 {
1134 if( sig_oid->p[8] >= 2 && sig_oid->p[8] <= 5 )
1135 {
1136 *sig_alg = sig_oid->p[8];
1137 return( 0 );
1138 }
1139
1140 if ( sig_oid->p[8] >= 11 && sig_oid->p[8] <= 14 )
1141 {
1142 *sig_alg = sig_oid->p[8];
1143 return( 0 );
1144 }
1145
1146 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1147 }
Paul Bakker400ff6f2011-02-20 10:40:16 +00001148 if( sig_oid->len == 5 &&
1149 memcmp( sig_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
1150 {
1151 *sig_alg = SIG_RSA_SHA1;
1152 return( 0 );
1153 }
Paul Bakker27d66162010-03-17 06:56:01 +00001154
1155 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1156}
1157
Paul Bakkerd98030e2009-05-02 15:13:40 +00001158/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001159 * Parse one or more certificates and add them to the chained list
1160 */
Paul Bakker23986e52011-04-24 08:57:21 +00001161int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001162{
Paul Bakker23986e52011-04-24 08:57:21 +00001163 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001164 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00001165 unsigned char *p, *end;
1166 x509_cert *crt;
Paul Bakker96743fc2011-02-12 14:30:57 +00001167#if defined(POLARSSL_PEM_C)
1168 pem_context pem;
Paul Bakker5690efc2011-05-26 13:16:06 +00001169 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001170#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001171
1172 crt = chain;
1173
Paul Bakker320a4b52009-03-28 18:52:39 +00001174 /*
1175 * Check for valid input
1176 */
1177 if( crt == NULL || buf == NULL )
1178 return( 1 );
1179
Paul Bakkere9581d62009-03-28 20:29:25 +00001180 while( crt->version != 0 && crt->next != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00001181 crt = crt->next;
1182
1183 /*
Paul Bakker320a4b52009-03-28 18:52:39 +00001184 * Add new certificate on the end of the chain if needed.
1185 */
Paul Bakkere9581d62009-03-28 20:29:25 +00001186 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001187 {
1188 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1189
Paul Bakker7d06ad22009-05-02 15:53:56 +00001190 if( crt->next == NULL )
1191 {
Paul Bakker320a4b52009-03-28 18:52:39 +00001192 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001193 return( 1 );
1194 }
Paul Bakker320a4b52009-03-28 18:52:39 +00001195
Paul Bakker7d06ad22009-05-02 15:53:56 +00001196 crt = crt->next;
1197 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001198 }
1199
Paul Bakker96743fc2011-02-12 14:30:57 +00001200#if defined(POLARSSL_PEM_C)
1201 pem_init( &pem );
1202 ret = pem_read_buffer( &pem,
1203 "-----BEGIN CERTIFICATE-----",
1204 "-----END CERTIFICATE-----",
1205 buf, NULL, 0, &use_len );
Paul Bakker5121ce52009-01-03 21:22:43 +00001206
Paul Bakker96743fc2011-02-12 14:30:57 +00001207 if( ret == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001208 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001209 /*
1210 * Was PEM encoded
1211 */
1212 buflen -= use_len;
1213 buf += use_len;
Paul Bakker5121ce52009-01-03 21:22:43 +00001214
1215 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001216 * Steal PEM buffer
Paul Bakker5121ce52009-01-03 21:22:43 +00001217 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001218 p = pem.buf;
1219 pem.buf = NULL;
1220 len = pem.buflen;
1221 pem_free( &pem );
1222 }
1223 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
1224 {
1225 pem_free( &pem );
1226 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001227 }
1228 else
1229 {
1230 /*
1231 * nope, copy the raw DER data
1232 */
1233 p = (unsigned char *) malloc( len = buflen );
1234
1235 if( p == NULL )
1236 return( 1 );
1237
1238 memcpy( p, buf, buflen );
1239
1240 buflen = 0;
1241 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001242#else
1243 p = (unsigned char *) malloc( len = buflen );
1244
1245 if( p == NULL )
1246 return( 1 );
1247
1248 memcpy( p, buf, buflen );
1249
1250 buflen = 0;
1251#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001252
1253 crt->raw.p = p;
1254 crt->raw.len = len;
1255 end = p + len;
1256
1257 /*
1258 * Certificate ::= SEQUENCE {
1259 * tbsCertificate TBSCertificate,
1260 * signatureAlgorithm AlgorithmIdentifier,
1261 * signatureValue BIT STRING }
1262 */
1263 if( ( ret = asn1_get_tag( &p, end, &len,
1264 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1265 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001266 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001267 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001268 }
1269
Paul Bakker23986e52011-04-24 08:57:21 +00001270 if( len != (size_t) ( end - p ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001271 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001272 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001273 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001274 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001275 }
1276
1277 /*
1278 * TBSCertificate ::= SEQUENCE {
1279 */
1280 crt->tbs.p = p;
1281
1282 if( ( ret = asn1_get_tag( &p, end, &len,
1283 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1284 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001285 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001286 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001287 }
1288
1289 end = p + len;
1290 crt->tbs.len = end - crt->tbs.p;
1291
1292 /*
1293 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1294 *
1295 * CertificateSerialNumber ::= INTEGER
1296 *
1297 * signature AlgorithmIdentifier
1298 */
1299 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1300 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1301 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
1302 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001303 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001304 return( ret );
1305 }
1306
1307 crt->version++;
1308
1309 if( crt->version > 3 )
1310 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001311 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001312 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001313 }
1314
Paul Bakker27d66162010-03-17 06:56:01 +00001315 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_alg ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001316 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001317 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001318 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001319 }
1320
1321 /*
1322 * issuer Name
1323 */
1324 crt->issuer_raw.p = p;
1325
1326 if( ( ret = asn1_get_tag( &p, end, &len,
1327 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1328 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001329 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001330 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001331 }
1332
1333 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1334 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001335 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001336 return( ret );
1337 }
1338
1339 crt->issuer_raw.len = p - crt->issuer_raw.p;
1340
1341 /*
1342 * Validity ::= SEQUENCE {
1343 * notBefore Time,
1344 * notAfter Time }
1345 *
1346 */
1347 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1348 &crt->valid_to ) ) != 0 )
1349 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001350 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001351 return( ret );
1352 }
1353
1354 /*
1355 * subject Name
1356 */
1357 crt->subject_raw.p = p;
1358
1359 if( ( ret = asn1_get_tag( &p, end, &len,
1360 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1361 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001362 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001363 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001364 }
1365
1366 if( ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
1367 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001368 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001369 return( ret );
1370 }
1371
1372 crt->subject_raw.len = p - crt->subject_raw.p;
1373
1374 /*
1375 * SubjectPublicKeyInfo ::= SEQUENCE
1376 * algorithm AlgorithmIdentifier,
1377 * subjectPublicKey BIT STRING }
1378 */
1379 if( ( ret = asn1_get_tag( &p, end, &len,
1380 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1381 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001382 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001383 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001384 }
1385
1386 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1387 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1388 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001389 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001390 return( ret );
1391 }
1392
1393 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1394 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001395 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001396 return( ret );
1397 }
1398
1399 crt->rsa.len = mpi_size( &crt->rsa.N );
1400
1401 /*
1402 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1403 * -- If present, version shall be v2 or v3
1404 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1405 * -- If present, version shall be v2 or v3
1406 * extensions [3] EXPLICIT Extensions OPTIONAL
1407 * -- If present, version shall be v3
1408 */
1409 if( crt->version == 2 || crt->version == 3 )
1410 {
1411 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1412 if( ret != 0 )
1413 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001414 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001415 return( ret );
1416 }
1417 }
1418
1419 if( crt->version == 2 || crt->version == 3 )
1420 {
1421 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1422 if( ret != 0 )
1423 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001424 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001425 return( ret );
1426 }
1427 }
1428
1429 if( crt->version == 3 )
1430 {
Paul Bakker74111d32011-01-15 16:57:55 +00001431 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001432 if( ret != 0 )
1433 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001434 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001435 return( ret );
1436 }
1437 }
1438
1439 if( p != end )
1440 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001441 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001442 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001443 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001444 }
1445
1446 end = crt->raw.p + crt->raw.len;
1447
1448 /*
1449 * signatureAlgorithm AlgorithmIdentifier,
1450 * signatureValue BIT STRING
1451 */
1452 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1453 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001454 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001455 return( ret );
1456 }
1457
Paul Bakker320a4b52009-03-28 18:52:39 +00001458 if( memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001459 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001460 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001461 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001462 }
1463
1464 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1465 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001466 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001467 return( ret );
1468 }
1469
1470 if( p != end )
1471 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001472 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001473 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001474 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001475 }
1476
Paul Bakker5121ce52009-01-03 21:22:43 +00001477 if( buflen > 0 )
Paul Bakker320a4b52009-03-28 18:52:39 +00001478 {
1479 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1480
Paul Bakker7d06ad22009-05-02 15:53:56 +00001481 if( crt->next == NULL )
1482 {
Paul Bakker320a4b52009-03-28 18:52:39 +00001483 x509_free( crt );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001484 return( 1 );
1485 }
Paul Bakker320a4b52009-03-28 18:52:39 +00001486
Paul Bakker7d06ad22009-05-02 15:53:56 +00001487 crt = crt->next;
1488 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001489
Paul Bakker5121ce52009-01-03 21:22:43 +00001490 return( x509parse_crt( crt, buf, buflen ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001491 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001492
1493 return( 0 );
1494}
1495
1496/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001497 * Parse one or more CRLs and add them to the chained list
1498 */
Paul Bakker23986e52011-04-24 08:57:21 +00001499int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001500{
Paul Bakker23986e52011-04-24 08:57:21 +00001501 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001502 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001503 unsigned char *p, *end;
1504 x509_crl *crl;
Paul Bakker96743fc2011-02-12 14:30:57 +00001505#if defined(POLARSSL_PEM_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00001506 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001507 pem_context pem;
1508#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001509
1510 crl = chain;
1511
1512 /*
1513 * Check for valid input
1514 */
1515 if( crl == NULL || buf == NULL )
1516 return( 1 );
1517
1518 while( crl->version != 0 && crl->next != NULL )
1519 crl = crl->next;
1520
1521 /*
1522 * Add new CRL on the end of the chain if needed.
1523 */
1524 if ( crl->version != 0 && crl->next == NULL)
1525 {
1526 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1527
Paul Bakker7d06ad22009-05-02 15:53:56 +00001528 if( crl->next == NULL )
1529 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001530 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001531 return( 1 );
1532 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001533
Paul Bakker7d06ad22009-05-02 15:53:56 +00001534 crl = crl->next;
1535 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001536 }
1537
Paul Bakker96743fc2011-02-12 14:30:57 +00001538#if defined(POLARSSL_PEM_C)
1539 pem_init( &pem );
1540 ret = pem_read_buffer( &pem,
1541 "-----BEGIN X509 CRL-----",
1542 "-----END X509 CRL-----",
1543 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001544
Paul Bakker96743fc2011-02-12 14:30:57 +00001545 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001546 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001547 /*
1548 * Was PEM encoded
1549 */
1550 buflen -= use_len;
1551 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001552
1553 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001554 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001555 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001556 p = pem.buf;
1557 pem.buf = NULL;
1558 len = pem.buflen;
1559 pem_free( &pem );
1560 }
1561 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
1562 {
1563 pem_free( &pem );
1564 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001565 }
1566 else
1567 {
1568 /*
1569 * nope, copy the raw DER data
1570 */
1571 p = (unsigned char *) malloc( len = buflen );
1572
1573 if( p == NULL )
1574 return( 1 );
1575
1576 memcpy( p, buf, buflen );
1577
1578 buflen = 0;
1579 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001580#else
1581 p = (unsigned char *) malloc( len = buflen );
1582
1583 if( p == NULL )
1584 return( 1 );
1585
1586 memcpy( p, buf, buflen );
1587
1588 buflen = 0;
1589#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001590
1591 crl->raw.p = p;
1592 crl->raw.len = len;
1593 end = p + len;
1594
1595 /*
1596 * CertificateList ::= SEQUENCE {
1597 * tbsCertList TBSCertList,
1598 * signatureAlgorithm AlgorithmIdentifier,
1599 * signatureValue BIT STRING }
1600 */
1601 if( ( ret = asn1_get_tag( &p, end, &len,
1602 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1603 {
1604 x509_crl_free( crl );
1605 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1606 }
1607
Paul Bakker23986e52011-04-24 08:57:21 +00001608 if( len != (size_t) ( end - p ) )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001609 {
1610 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001611 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001612 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1613 }
1614
1615 /*
1616 * TBSCertList ::= SEQUENCE {
1617 */
1618 crl->tbs.p = p;
1619
1620 if( ( ret = asn1_get_tag( &p, end, &len,
1621 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1622 {
1623 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001624 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001625 }
1626
1627 end = p + len;
1628 crl->tbs.len = end - crl->tbs.p;
1629
1630 /*
1631 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1632 * -- if present, MUST be v2
1633 *
1634 * signature AlgorithmIdentifier
1635 */
Paul Bakker3329d1f2011-10-12 09:55:01 +00001636 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
Paul Bakkerd98030e2009-05-02 15:13:40 +00001637 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1638 {
1639 x509_crl_free( crl );
1640 return( ret );
1641 }
1642
1643 crl->version++;
1644
1645 if( crl->version > 2 )
1646 {
1647 x509_crl_free( crl );
1648 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1649 }
1650
Paul Bakker27d66162010-03-17 06:56:01 +00001651 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_alg ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001652 {
1653 x509_crl_free( crl );
1654 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1655 }
1656
1657 /*
1658 * issuer Name
1659 */
1660 crl->issuer_raw.p = p;
1661
1662 if( ( ret = asn1_get_tag( &p, end, &len,
1663 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1664 {
1665 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001666 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001667 }
1668
1669 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1670 {
1671 x509_crl_free( crl );
1672 return( ret );
1673 }
1674
1675 crl->issuer_raw.len = p - crl->issuer_raw.p;
1676
1677 /*
1678 * thisUpdate Time
1679 * nextUpdate Time OPTIONAL
1680 */
Paul Bakker91200182010-02-18 21:26:15 +00001681 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001682 {
1683 x509_crl_free( crl );
1684 return( ret );
1685 }
1686
Paul Bakker91200182010-02-18 21:26:15 +00001687 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001688 {
Paul Bakker9d781402011-05-09 16:17:09 +00001689 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001690 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker9d781402011-05-09 16:17:09 +00001691 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001692 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001693 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001694 x509_crl_free( crl );
1695 return( ret );
1696 }
1697 }
1698
1699 /*
1700 * revokedCertificates SEQUENCE OF SEQUENCE {
1701 * userCertificate CertificateSerialNumber,
1702 * revocationDate Time,
1703 * crlEntryExtensions Extensions OPTIONAL
1704 * -- if present, MUST be v2
1705 * } OPTIONAL
1706 */
1707 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1708 {
1709 x509_crl_free( crl );
1710 return( ret );
1711 }
1712
1713 /*
1714 * crlExtensions EXPLICIT Extensions OPTIONAL
1715 * -- if present, MUST be v2
1716 */
1717 if( crl->version == 2 )
1718 {
1719 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1720
1721 if( ret != 0 )
1722 {
1723 x509_crl_free( crl );
1724 return( ret );
1725 }
1726 }
1727
1728 if( p != end )
1729 {
1730 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001731 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001732 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1733 }
1734
1735 end = crl->raw.p + crl->raw.len;
1736
1737 /*
1738 * signatureAlgorithm AlgorithmIdentifier,
1739 * signatureValue BIT STRING
1740 */
1741 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1742 {
1743 x509_crl_free( crl );
1744 return( ret );
1745 }
1746
1747 if( memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
1748 {
1749 x509_crl_free( crl );
1750 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1751 }
1752
1753 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1754 {
1755 x509_crl_free( crl );
1756 return( ret );
1757 }
1758
1759 if( p != end )
1760 {
1761 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001762 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001763 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1764 }
1765
1766 if( buflen > 0 )
1767 {
1768 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1769
Paul Bakker7d06ad22009-05-02 15:53:56 +00001770 if( crl->next == NULL )
1771 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001772 x509_crl_free( crl );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001773 return( 1 );
1774 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001775
Paul Bakker7d06ad22009-05-02 15:53:56 +00001776 crl = crl->next;
1777 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001778
1779 return( x509parse_crl( crl, buf, buflen ) );
1780 }
1781
1782 return( 0 );
1783}
1784
Paul Bakker335db3f2011-04-25 15:28:35 +00001785#if defined(POLARSSL_FS_IO)
Paul Bakkerd98030e2009-05-02 15:13:40 +00001786/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001787 * Load all data from a file into a given buffer.
1788 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001789int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001790{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001791 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001792
Paul Bakkerd98030e2009-05-02 15:13:40 +00001793 if( ( f = fopen( path, "rb" ) ) == NULL )
1794 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001795
Paul Bakkerd98030e2009-05-02 15:13:40 +00001796 fseek( f, 0, SEEK_END );
1797 *n = (size_t) ftell( f );
1798 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001799
Paul Bakkerd98030e2009-05-02 15:13:40 +00001800 if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
1801 return( 1 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001802
Paul Bakkerd98030e2009-05-02 15:13:40 +00001803 if( fread( *buf, 1, *n, f ) != *n )
1804 {
1805 fclose( f );
1806 free( *buf );
1807 return( 1 );
1808 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001809
Paul Bakkerd98030e2009-05-02 15:13:40 +00001810 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001811
Paul Bakkerd98030e2009-05-02 15:13:40 +00001812 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001813
Paul Bakkerd98030e2009-05-02 15:13:40 +00001814 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001815}
1816
1817/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001818 * Load one or more certificates and add them to the chained list
1819 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001820int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001821{
1822 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001823 size_t n;
1824 unsigned char *buf;
1825
Paul Bakker2b245eb2009-04-19 18:44:26 +00001826 if ( load_file( path, &buf, &n ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001827 return( 1 );
1828
Paul Bakker27fdf462011-06-09 13:55:13 +00001829 ret = x509parse_crt( chain, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001830
1831 memset( buf, 0, n + 1 );
1832 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001833
1834 return( ret );
1835}
1836
Paul Bakkerd98030e2009-05-02 15:13:40 +00001837/*
1838 * Load one or more CRLs and add them to the chained list
1839 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001840int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001841{
1842 int ret;
1843 size_t n;
1844 unsigned char *buf;
1845
1846 if ( load_file( path, &buf, &n ) )
1847 return( 1 );
1848
Paul Bakker27fdf462011-06-09 13:55:13 +00001849 ret = x509parse_crl( chain, buf, n );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001850
1851 memset( buf, 0, n + 1 );
1852 free( buf );
1853
1854 return( ret );
1855}
1856
Paul Bakker5121ce52009-01-03 21:22:43 +00001857/*
Paul Bakker335db3f2011-04-25 15:28:35 +00001858 * Load and parse a private RSA key
1859 */
1860int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
1861{
1862 int ret;
1863 size_t n;
1864 unsigned char *buf;
1865
1866 if ( load_file( path, &buf, &n ) )
1867 return( 1 );
1868
1869 if( pwd == NULL )
Paul Bakker27fdf462011-06-09 13:55:13 +00001870 ret = x509parse_key( rsa, buf, n, NULL, 0 );
Paul Bakker335db3f2011-04-25 15:28:35 +00001871 else
Paul Bakker27fdf462011-06-09 13:55:13 +00001872 ret = x509parse_key( rsa, buf, n,
Paul Bakker335db3f2011-04-25 15:28:35 +00001873 (unsigned char *) pwd, strlen( pwd ) );
1874
1875 memset( buf, 0, n + 1 );
1876 free( buf );
1877
1878 return( ret );
1879}
1880
1881/*
1882 * Load and parse a public RSA key
1883 */
1884int x509parse_public_keyfile( rsa_context *rsa, const char *path )
1885{
1886 int ret;
1887 size_t n;
1888 unsigned char *buf;
1889
1890 if ( load_file( path, &buf, &n ) )
1891 return( 1 );
1892
Paul Bakker27fdf462011-06-09 13:55:13 +00001893 ret = x509parse_public_key( rsa, buf, n );
Paul Bakker335db3f2011-04-25 15:28:35 +00001894
1895 memset( buf, 0, n + 1 );
1896 free( buf );
1897
1898 return( ret );
1899}
1900#endif /* POLARSSL_FS_IO */
1901
1902/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001903 * Parse a private RSA key
1904 */
Paul Bakker23986e52011-04-24 08:57:21 +00001905int x509parse_key( rsa_context *rsa, const unsigned char *key, size_t keylen,
1906 const unsigned char *pwd, size_t pwdlen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001907{
Paul Bakker23986e52011-04-24 08:57:21 +00001908 int ret;
1909 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00001910 unsigned char *p, *end;
Paul Bakkered56b222011-07-13 11:26:43 +00001911 unsigned char *p_alt;
1912 x509_buf pk_alg_oid;
1913
Paul Bakker96743fc2011-02-12 14:30:57 +00001914#if defined(POLARSSL_PEM_C)
1915 pem_context pem;
Paul Bakker5121ce52009-01-03 21:22:43 +00001916
Paul Bakker96743fc2011-02-12 14:30:57 +00001917 pem_init( &pem );
1918 ret = pem_read_buffer( &pem,
1919 "-----BEGIN RSA PRIVATE KEY-----",
1920 "-----END RSA PRIVATE KEY-----",
1921 key, pwd, pwdlen, &len );
Paul Bakker5121ce52009-01-03 21:22:43 +00001922
Paul Bakkered56b222011-07-13 11:26:43 +00001923 if( ret == POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
1924 {
1925 ret = pem_read_buffer( &pem,
1926 "-----BEGIN PRIVATE KEY-----",
1927 "-----END PRIVATE KEY-----",
1928 key, pwd, pwdlen, &len );
1929 }
1930
Paul Bakker96743fc2011-02-12 14:30:57 +00001931 if( ret == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001932 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001933 /*
1934 * Was PEM encoded
1935 */
1936 keylen = pem.buflen;
Paul Bakker5121ce52009-01-03 21:22:43 +00001937 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001938 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
Paul Bakkerff60ee62010-03-16 21:09:09 +00001939 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001940 pem_free( &pem );
1941 return( ret );
Paul Bakkerff60ee62010-03-16 21:09:09 +00001942 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001943
Paul Bakker96743fc2011-02-12 14:30:57 +00001944 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
1945#else
Paul Bakker5690efc2011-05-26 13:16:06 +00001946 ((void) pwd);
1947 ((void) pwdlen);
Paul Bakker96743fc2011-02-12 14:30:57 +00001948 p = (unsigned char *) key;
1949#endif
1950 end = p + keylen;
1951
Paul Bakker5121ce52009-01-03 21:22:43 +00001952 /*
Paul Bakkered56b222011-07-13 11:26:43 +00001953 * Note: Depending on the type of private key file one can expect either a
1954 * PrivatKeyInfo object (PKCS#8) or a RSAPrivateKey (PKCS#1) directly.
1955 *
1956 * PrivateKeyInfo ::= SEQUENCE {
Paul Bakker5c721f92011-07-27 16:51:09 +00001957 * version Version,
Paul Bakkered56b222011-07-13 11:26:43 +00001958 * algorithm AlgorithmIdentifier,
1959 * PrivateKey BIT STRING
1960 * }
1961 *
1962 * AlgorithmIdentifier ::= SEQUENCE {
1963 * algorithm OBJECT IDENTIFIER,
1964 * parameters ANY DEFINED BY algorithm OPTIONAL
1965 * }
1966 *
Paul Bakker5121ce52009-01-03 21:22:43 +00001967 * RSAPrivateKey ::= SEQUENCE {
1968 * version Version,
1969 * modulus INTEGER, -- n
1970 * publicExponent INTEGER, -- e
1971 * privateExponent INTEGER, -- d
1972 * prime1 INTEGER, -- p
1973 * prime2 INTEGER, -- q
1974 * exponent1 INTEGER, -- d mod (p-1)
1975 * exponent2 INTEGER, -- d mod (q-1)
1976 * coefficient INTEGER, -- (inverse of q) mod p
1977 * otherPrimeInfos OtherPrimeInfos OPTIONAL
1978 * }
1979 */
1980 if( ( ret = asn1_get_tag( &p, end, &len,
1981 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1982 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001983#if defined(POLARSSL_PEM_C)
1984 pem_free( &pem );
1985#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001986 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00001987 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001988 }
1989
1990 end = p + len;
1991
1992 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
1993 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001994#if defined(POLARSSL_PEM_C)
1995 pem_free( &pem );
1996#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001997 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00001998 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001999 }
2000
2001 if( rsa->ver != 0 )
2002 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002003#if defined(POLARSSL_PEM_C)
2004 pem_free( &pem );
2005#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002006 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002007 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002008 }
2009
Paul Bakkered56b222011-07-13 11:26:43 +00002010 p_alt = p;
2011
2012 if( ( ret = x509_get_alg( &p_alt, end, &pk_alg_oid ) ) != 0 )
2013 {
2014 // Assume that we have the PKCS#1 format if wrong
2015 // tag was encountered
2016 //
2017 if( ret != POLARSSL_ERR_X509_CERT_INVALID_ALG +
2018 POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
2019 {
2020#if defined(POLARSSL_PEM_C)
2021 pem_free( &pem );
2022#endif
2023 rsa_free( rsa );
2024 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
2025 }
2026 }
2027 else
2028 {
2029 int can_handle;
2030
2031 /*
2032 * only RSA keys handled at this time
2033 */
2034 can_handle = 0;
2035
2036 if( pk_alg_oid.len == 9 &&
2037 memcmp( pk_alg_oid.p, OID_PKCS1_RSA, 9 ) == 0 )
2038 can_handle = 1;
2039
2040 if( pk_alg_oid.len == 9 &&
2041 memcmp( pk_alg_oid.p, OID_PKCS1, 8 ) == 0 )
2042 {
2043 if( pk_alg_oid.p[8] >= 2 && pk_alg_oid.p[8] <= 5 )
2044 can_handle = 1;
2045
2046 if ( pk_alg_oid.p[8] >= 11 && pk_alg_oid.p[8] <= 14 )
2047 can_handle = 1;
2048 }
2049
2050 if( pk_alg_oid.len == 5 &&
2051 memcmp( pk_alg_oid.p, OID_RSA_SHA_OBS, 5 ) == 0 )
2052 can_handle = 1;
2053
2054 if( can_handle == 0 )
2055 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
2056
2057 /*
2058 * Parse the PKCS#8 format
2059 */
2060
2061 p = p_alt;
2062 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2063 {
2064#if defined(POLARSSL_PEM_C)
2065 pem_free( &pem );
2066#endif
2067 rsa_free( rsa );
2068 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2069 }
2070
2071 if( ( end - p ) < 1 )
2072 {
2073#if defined(POLARSSL_PEM_C)
2074 pem_free( &pem );
2075#endif
2076 rsa_free( rsa );
2077 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
2078 POLARSSL_ERR_ASN1_OUT_OF_DATA );
2079 }
2080
2081 end = p + len;
2082
2083 if( ( ret = asn1_get_tag( &p, end, &len,
2084 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2085 {
2086#if defined(POLARSSL_PEM_C)
2087 pem_free( &pem );
2088#endif
2089 rsa_free( rsa );
2090 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2091 }
2092
2093 end = p + len;
2094
2095 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2096 {
2097#if defined(POLARSSL_PEM_C)
2098 pem_free( &pem );
2099#endif
2100 rsa_free( rsa );
2101 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2102 }
2103
2104 if( rsa->ver != 0 )
2105 {
2106#if defined(POLARSSL_PEM_C)
2107 pem_free( &pem );
2108#endif
2109 rsa_free( rsa );
2110 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2111 }
2112 }
2113
Paul Bakker5121ce52009-01-03 21:22:43 +00002114 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
2115 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
2116 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
2117 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
2118 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
2119 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
2120 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
2121 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
2122 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002123#if defined(POLARSSL_PEM_C)
2124 pem_free( &pem );
2125#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002126 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002127 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002128 }
2129
2130 rsa->len = mpi_size( &rsa->N );
2131
2132 if( p != end )
2133 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002134#if defined(POLARSSL_PEM_C)
2135 pem_free( &pem );
2136#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002137 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002138 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00002139 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002140 }
2141
2142 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2143 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002144#if defined(POLARSSL_PEM_C)
2145 pem_free( &pem );
2146#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002147 rsa_free( rsa );
2148 return( ret );
2149 }
2150
Paul Bakker96743fc2011-02-12 14:30:57 +00002151#if defined(POLARSSL_PEM_C)
2152 pem_free( &pem );
2153#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002154
2155 return( 0 );
2156}
2157
2158/*
Paul Bakker53019ae2011-03-25 13:58:48 +00002159 * Parse a public RSA key
2160 */
Paul Bakker23986e52011-04-24 08:57:21 +00002161int x509parse_public_key( rsa_context *rsa, const unsigned char *key, size_t keylen )
Paul Bakker53019ae2011-03-25 13:58:48 +00002162{
Paul Bakker23986e52011-04-24 08:57:21 +00002163 int ret;
2164 size_t len;
Paul Bakker53019ae2011-03-25 13:58:48 +00002165 unsigned char *p, *end;
2166 x509_buf alg_oid;
2167#if defined(POLARSSL_PEM_C)
2168 pem_context pem;
2169
2170 pem_init( &pem );
2171 ret = pem_read_buffer( &pem,
2172 "-----BEGIN PUBLIC KEY-----",
2173 "-----END PUBLIC KEY-----",
2174 key, NULL, 0, &len );
2175
2176 if( ret == 0 )
2177 {
2178 /*
2179 * Was PEM encoded
2180 */
2181 keylen = pem.buflen;
2182 }
2183 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
2184 {
2185 pem_free( &pem );
2186 return( ret );
2187 }
2188
2189 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2190#else
2191 p = (unsigned char *) key;
2192#endif
2193 end = p + keylen;
2194
2195 /*
2196 * PublicKeyInfo ::= SEQUENCE {
2197 * algorithm AlgorithmIdentifier,
2198 * PublicKey BIT STRING
2199 * }
2200 *
2201 * AlgorithmIdentifier ::= SEQUENCE {
2202 * algorithm OBJECT IDENTIFIER,
2203 * parameters ANY DEFINED BY algorithm OPTIONAL
2204 * }
2205 *
2206 * RSAPublicKey ::= SEQUENCE {
2207 * modulus INTEGER, -- n
2208 * publicExponent INTEGER -- e
2209 * }
2210 */
2211
2212 if( ( ret = asn1_get_tag( &p, end, &len,
2213 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2214 {
2215#if defined(POLARSSL_PEM_C)
2216 pem_free( &pem );
2217#endif
2218 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002219 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002220 }
2221
2222 if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
2223 {
2224#if defined(POLARSSL_PEM_C)
2225 pem_free( &pem );
2226#endif
2227 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002228 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002229 }
2230
2231 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
2232 {
2233#if defined(POLARSSL_PEM_C)
2234 pem_free( &pem );
2235#endif
2236 rsa_free( rsa );
2237 return( ret );
2238 }
2239
2240 rsa->len = mpi_size( &rsa->N );
2241
2242#if defined(POLARSSL_PEM_C)
2243 pem_free( &pem );
2244#endif
2245
2246 return( 0 );
2247}
2248
Paul Bakkereaa89f82011-04-04 21:36:15 +00002249#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00002250/*
Paul Bakker1b57b062011-01-06 15:48:19 +00002251 * Parse DHM parameters
2252 */
Paul Bakker23986e52011-04-24 08:57:21 +00002253int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
Paul Bakker1b57b062011-01-06 15:48:19 +00002254{
Paul Bakker23986e52011-04-24 08:57:21 +00002255 int ret;
2256 size_t len;
Paul Bakker1b57b062011-01-06 15:48:19 +00002257 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00002258#if defined(POLARSSL_PEM_C)
2259 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00002260
Paul Bakker96743fc2011-02-12 14:30:57 +00002261 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00002262
Paul Bakker96743fc2011-02-12 14:30:57 +00002263 ret = pem_read_buffer( &pem,
2264 "-----BEGIN DH PARAMETERS-----",
2265 "-----END DH PARAMETERS-----",
2266 dhmin, NULL, 0, &dhminlen );
2267
2268 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00002269 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002270 /*
2271 * Was PEM encoded
2272 */
2273 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00002274 }
Paul Bakker96743fc2011-02-12 14:30:57 +00002275 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00002276 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002277 pem_free( &pem );
2278 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002279 }
2280
Paul Bakker96743fc2011-02-12 14:30:57 +00002281 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
2282#else
2283 p = (unsigned char *) dhmin;
2284#endif
2285 end = p + dhminlen;
2286
Paul Bakker1b57b062011-01-06 15:48:19 +00002287 memset( dhm, 0, sizeof( dhm_context ) );
2288
Paul Bakker1b57b062011-01-06 15:48:19 +00002289 /*
2290 * DHParams ::= SEQUENCE {
2291 * prime INTEGER, -- P
2292 * generator INTEGER, -- g
2293 * }
2294 */
2295 if( ( ret = asn1_get_tag( &p, end, &len,
2296 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2297 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002298#if defined(POLARSSL_PEM_C)
2299 pem_free( &pem );
2300#endif
Paul Bakker9d781402011-05-09 16:17:09 +00002301 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002302 }
2303
2304 end = p + len;
2305
2306 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
2307 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
2308 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002309#if defined(POLARSSL_PEM_C)
2310 pem_free( &pem );
2311#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002312 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002313 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002314 }
2315
2316 if( p != end )
2317 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002318#if defined(POLARSSL_PEM_C)
2319 pem_free( &pem );
2320#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002321 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002322 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker1b57b062011-01-06 15:48:19 +00002323 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
2324 }
2325
Paul Bakker96743fc2011-02-12 14:30:57 +00002326#if defined(POLARSSL_PEM_C)
2327 pem_free( &pem );
2328#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002329
2330 return( 0 );
2331}
2332
Paul Bakker335db3f2011-04-25 15:28:35 +00002333#if defined(POLARSSL_FS_IO)
Paul Bakker1b57b062011-01-06 15:48:19 +00002334/*
2335 * Load and parse a private RSA key
2336 */
2337int x509parse_dhmfile( dhm_context *dhm, const char *path )
2338{
2339 int ret;
2340 size_t n;
2341 unsigned char *buf;
2342
2343 if ( load_file( path, &buf, &n ) )
2344 return( 1 );
2345
Paul Bakker27fdf462011-06-09 13:55:13 +00002346 ret = x509parse_dhm( dhm, buf, n );
Paul Bakker1b57b062011-01-06 15:48:19 +00002347
2348 memset( buf, 0, n + 1 );
2349 free( buf );
2350
2351 return( ret );
2352}
Paul Bakker335db3f2011-04-25 15:28:35 +00002353#endif /* POLARSSL_FS_IO */
Paul Bakkereaa89f82011-04-04 21:36:15 +00002354#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00002355
Paul Bakker5121ce52009-01-03 21:22:43 +00002356#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002357#include <stdarg.h>
2358
2359#if !defined vsnprintf
2360#define vsnprintf _vsnprintf
2361#endif // vsnprintf
2362
2363/*
2364 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2365 * Result value is not size of buffer needed, but -1 if no fit is possible.
2366 *
2367 * This fuction tries to 'fix' this by at least suggesting enlarging the
2368 * size by 20.
2369 */
2370int compat_snprintf(char *str, size_t size, const char *format, ...)
2371{
2372 va_list ap;
2373 int res = -1;
2374
2375 va_start( ap, format );
2376
2377 res = vsnprintf( str, size, format, ap );
2378
2379 va_end( ap );
2380
2381 // No quick fix possible
2382 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00002383 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002384
2385 return res;
2386}
2387
2388#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002389#endif
2390
Paul Bakkerd98030e2009-05-02 15:13:40 +00002391#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2392
2393#define SAFE_SNPRINTF() \
2394{ \
2395 if( ret == -1 ) \
2396 return( -1 ); \
2397 \
Paul Bakker23986e52011-04-24 08:57:21 +00002398 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002399 p[n - 1] = '\0'; \
2400 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2401 } \
2402 \
Paul Bakker23986e52011-04-24 08:57:21 +00002403 n -= (unsigned int) ret; \
2404 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002405}
2406
Paul Bakker5121ce52009-01-03 21:22:43 +00002407/*
2408 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002409 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002410 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002411int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002412{
Paul Bakker23986e52011-04-24 08:57:21 +00002413 int ret;
2414 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002415 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002416 const x509_name *name;
Paul Bakker5121ce52009-01-03 21:22:43 +00002417 char s[128], *p;
2418
2419 memset( s, 0, sizeof( s ) );
2420
2421 name = dn;
2422 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002423 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002424
2425 while( name != NULL )
2426 {
Paul Bakker74111d32011-01-15 16:57:55 +00002427 if( name != dn )
2428 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002429 ret = snprintf( p, n, ", " );
2430 SAFE_SNPRINTF();
2431 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002432
2433 if( memcmp( name->oid.p, OID_X520, 2 ) == 0 )
2434 {
2435 switch( name->oid.p[2] )
2436 {
2437 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002438 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002439
2440 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002441 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002442
2443 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002444 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002445
2446 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002447 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002448
2449 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002450 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002451
2452 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002453 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002454
2455 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002456 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002457 name->oid.p[2] );
2458 break;
2459 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002460 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002461 }
2462 else if( memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
2463 {
2464 switch( name->oid.p[8] )
2465 {
2466 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002467 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002468
2469 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002470 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002471 name->oid.p[8] );
2472 break;
2473 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002474 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002475 }
2476 else
Paul Bakker74111d32011-01-15 16:57:55 +00002477 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002478 ret = snprintf( p, n, "\?\?=" );
Paul Bakker74111d32011-01-15 16:57:55 +00002479 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002480 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002481
2482 for( i = 0; i < name->val.len; i++ )
2483 {
Paul Bakker27fdf462011-06-09 13:55:13 +00002484 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002485 break;
2486
2487 c = name->val.p[i];
2488 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2489 s[i] = '?';
2490 else s[i] = c;
2491 }
2492 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002493 ret = snprintf( p, n, "%s", s );
2494 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002495 name = name->next;
2496 }
2497
Paul Bakker23986e52011-04-24 08:57:21 +00002498 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002499}
2500
2501/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002502 * Store the serial in printable form into buf; no more
2503 * than size characters will be written
2504 */
2505int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2506{
Paul Bakker23986e52011-04-24 08:57:21 +00002507 int ret;
2508 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00002509 char *p;
2510
2511 p = buf;
2512 n = size;
2513
2514 nr = ( serial->len <= 32 )
2515 ? serial->len : 32;
2516
2517 for( i = 0; i < nr; i++ )
2518 {
2519 ret = snprintf( p, n, "%02X%s",
2520 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2521 SAFE_SNPRINTF();
2522 }
2523
Paul Bakker23986e52011-04-24 08:57:21 +00002524 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00002525}
2526
2527/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002528 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002529 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002530int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2531 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002532{
Paul Bakker23986e52011-04-24 08:57:21 +00002533 int ret;
2534 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002535 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00002536
2537 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002538 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002539
Paul Bakkerd98030e2009-05-02 15:13:40 +00002540 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002541 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002542 SAFE_SNPRINTF();
2543 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002544 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002545 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002546
Paul Bakkerdd476992011-01-16 21:34:59 +00002547 ret = x509parse_serial_gets( p, n, &crt->serial);
2548 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002549
Paul Bakkerd98030e2009-05-02 15:13:40 +00002550 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2551 SAFE_SNPRINTF();
2552 ret = x509parse_dn_gets( p, n, &crt->issuer );
2553 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002554
Paul Bakkerd98030e2009-05-02 15:13:40 +00002555 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2556 SAFE_SNPRINTF();
2557 ret = x509parse_dn_gets( p, n, &crt->subject );
2558 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002559
Paul Bakkerd98030e2009-05-02 15:13:40 +00002560 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002561 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2562 crt->valid_from.year, crt->valid_from.mon,
2563 crt->valid_from.day, crt->valid_from.hour,
2564 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002565 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002566
Paul Bakkerd98030e2009-05-02 15:13:40 +00002567 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002568 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2569 crt->valid_to.year, crt->valid_to.mon,
2570 crt->valid_to.day, crt->valid_to.hour,
2571 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002572 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002573
Paul Bakkerd98030e2009-05-02 15:13:40 +00002574 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2575 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002576
Paul Bakker27d66162010-03-17 06:56:01 +00002577 switch( crt->sig_alg )
Paul Bakker5121ce52009-01-03 21:22:43 +00002578 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002579 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2580 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2581 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2582 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2583 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2584 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2585 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2586 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2587 default: ret = snprintf( p, n, "???" ); break;
2588 }
2589 SAFE_SNPRINTF();
2590
2591 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
Paul Bakkerf4f69682011-04-24 16:08:12 +00002592 (int) crt->rsa.N.n * (int) sizeof( unsigned long ) * 8 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002593 SAFE_SNPRINTF();
2594
Paul Bakker23986e52011-04-24 08:57:21 +00002595 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002596}
2597
Paul Bakker74111d32011-01-15 16:57:55 +00002598/* Compare a given OID string with an OID x509_buf * */
2599#define OID_CMP(oid_str, oid_buf) \
2600 ( ( OID_SIZE(oid_str) == (oid_buf)->len ) && \
2601 memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0)
2602
2603/*
2604 * Return an informational string describing the given OID
2605 */
2606const char *x509_oid_get_description( x509_buf *oid )
2607{
2608 if ( oid == NULL )
2609 return ( NULL );
2610
2611 else if( OID_CMP( OID_SERVER_AUTH, oid ) )
2612 return( STRING_SERVER_AUTH );
2613
2614 else if( OID_CMP( OID_CLIENT_AUTH, oid ) )
2615 return( STRING_CLIENT_AUTH );
2616
2617 else if( OID_CMP( OID_CODE_SIGNING, oid ) )
2618 return( STRING_CODE_SIGNING );
2619
2620 else if( OID_CMP( OID_EMAIL_PROTECTION, oid ) )
2621 return( STRING_EMAIL_PROTECTION );
2622
2623 else if( OID_CMP( OID_TIME_STAMPING, oid ) )
2624 return( STRING_TIME_STAMPING );
2625
2626 else if( OID_CMP( OID_OCSP_SIGNING, oid ) )
2627 return( STRING_OCSP_SIGNING );
2628
2629 return( NULL );
2630}
2631
2632/* Return the x.y.z.... style numeric string for the given OID */
2633int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2634{
Paul Bakker23986e52011-04-24 08:57:21 +00002635 int ret;
2636 size_t i, n;
Paul Bakker74111d32011-01-15 16:57:55 +00002637 unsigned int value;
2638 char *p;
2639
2640 p = buf;
2641 n = size;
2642
2643 /* First byte contains first two dots */
2644 if( oid->len > 0 )
2645 {
2646 ret = snprintf( p, n, "%d.%d", oid->p[0]/40, oid->p[0]%40 );
2647 SAFE_SNPRINTF();
2648 }
2649
2650 /* TODO: value can overflow in value. */
2651 value = 0;
Paul Bakker23986e52011-04-24 08:57:21 +00002652 for( i = 1; i < oid->len; i++ )
Paul Bakker74111d32011-01-15 16:57:55 +00002653 {
2654 value <<= 7;
2655 value += oid->p[i] & 0x7F;
2656
2657 if( !( oid->p[i] & 0x80 ) )
2658 {
2659 /* Last byte */
2660 ret = snprintf( p, n, ".%d", value );
2661 SAFE_SNPRINTF();
2662 value = 0;
2663 }
2664 }
2665
Paul Bakker23986e52011-04-24 08:57:21 +00002666 return( (int) ( size - n ) );
Paul Bakker74111d32011-01-15 16:57:55 +00002667}
2668
Paul Bakkerd98030e2009-05-02 15:13:40 +00002669/*
2670 * Return an informational string about the CRL.
2671 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002672int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2673 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002674{
Paul Bakker23986e52011-04-24 08:57:21 +00002675 int ret;
2676 size_t i, n, nr;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002677 char *p;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002678 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002679
2680 p = buf;
2681 n = size;
2682
2683 ret = snprintf( p, n, "%sCRL version : %d",
2684 prefix, crl->version );
2685 SAFE_SNPRINTF();
2686
2687 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2688 SAFE_SNPRINTF();
2689 ret = x509parse_dn_gets( p, n, &crl->issuer );
2690 SAFE_SNPRINTF();
2691
2692 ret = snprintf( p, n, "\n%sthis update : " \
2693 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2694 crl->this_update.year, crl->this_update.mon,
2695 crl->this_update.day, crl->this_update.hour,
2696 crl->this_update.min, crl->this_update.sec );
2697 SAFE_SNPRINTF();
2698
2699 ret = snprintf( p, n, "\n%snext update : " \
2700 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2701 crl->next_update.year, crl->next_update.mon,
2702 crl->next_update.day, crl->next_update.hour,
2703 crl->next_update.min, crl->next_update.sec );
2704 SAFE_SNPRINTF();
2705
2706 entry = &crl->entry;
2707
2708 ret = snprintf( p, n, "\n%sRevoked certificates:",
2709 prefix );
2710 SAFE_SNPRINTF();
2711
Paul Bakker9be19372009-07-27 20:21:53 +00002712 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002713 {
2714 ret = snprintf( p, n, "\n%sserial number: ",
2715 prefix );
2716 SAFE_SNPRINTF();
2717
2718 nr = ( entry->serial.len <= 32 )
2719 ? entry->serial.len : 32;
2720
Paul Bakker74111d32011-01-15 16:57:55 +00002721 for( i = 0; i < nr; i++ )
2722 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002723 ret = snprintf( p, n, "%02X%s",
2724 entry->serial.p[i], ( i < nr - 1 ) ? ":" : "" );
2725 SAFE_SNPRINTF();
2726 }
2727
2728 ret = snprintf( p, n, " revocation date: " \
2729 "%04d-%02d-%02d %02d:%02d:%02d",
2730 entry->revocation_date.year, entry->revocation_date.mon,
2731 entry->revocation_date.day, entry->revocation_date.hour,
2732 entry->revocation_date.min, entry->revocation_date.sec );
2733 SAFE_SNPRINTF();
2734
2735 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002736 }
2737
Paul Bakkerd98030e2009-05-02 15:13:40 +00002738 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2739 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002740
Paul Bakker27d66162010-03-17 06:56:01 +00002741 switch( crl->sig_alg )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002742 {
2743 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2744 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2745 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2746 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2747 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2748 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2749 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2750 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2751 default: ret = snprintf( p, n, "???" ); break;
2752 }
2753 SAFE_SNPRINTF();
2754
Paul Bakker1e27bb22009-07-19 20:25:25 +00002755 ret = snprintf( p, n, "\n" );
2756 SAFE_SNPRINTF();
2757
Paul Bakker23986e52011-04-24 08:57:21 +00002758 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002759}
2760
2761/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00002762 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00002763 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002764int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00002765{
2766 struct tm *lt;
2767 time_t tt;
2768
2769 tt = time( NULL );
2770 lt = localtime( &tt );
2771
Paul Bakker40ea7de2009-05-03 10:18:48 +00002772 if( lt->tm_year > to->year - 1900 )
2773 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002774
Paul Bakker40ea7de2009-05-03 10:18:48 +00002775 if( lt->tm_year == to->year - 1900 &&
2776 lt->tm_mon > to->mon - 1 )
2777 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002778
Paul Bakker40ea7de2009-05-03 10:18:48 +00002779 if( lt->tm_year == to->year - 1900 &&
2780 lt->tm_mon == to->mon - 1 &&
2781 lt->tm_mday > to->day )
2782 return( 1 );
2783
Paul Bakkerb6194992011-01-16 21:40:22 +00002784 if( lt->tm_year == to->year - 1900 &&
2785 lt->tm_mon == to->mon - 1 &&
2786 lt->tm_mday == to->day &&
2787 lt->tm_hour > to->hour - 1)
2788 return( 1 );
2789
2790 if( lt->tm_year == to->year - 1900 &&
2791 lt->tm_mon == to->mon - 1 &&
2792 lt->tm_mday == to->day &&
2793 lt->tm_hour == to->hour - 1 &&
2794 lt->tm_min > to->min - 1 )
2795 return( 1 );
2796
2797 if( lt->tm_year == to->year - 1900 &&
2798 lt->tm_mon == to->mon - 1 &&
2799 lt->tm_mday == to->day &&
2800 lt->tm_hour == to->hour - 1 &&
2801 lt->tm_min == to->min - 1 &&
2802 lt->tm_sec > to->sec - 1 )
2803 return( 1 );
2804
Paul Bakker40ea7de2009-05-03 10:18:48 +00002805 return( 0 );
2806}
2807
2808/*
2809 * Return 1 if the certificate is revoked, or 0 otherwise.
2810 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002811int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002812{
Paul Bakkerff60ee62010-03-16 21:09:09 +00002813 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00002814
2815 while( cur != NULL && cur->serial.len != 0 )
2816 {
Paul Bakkera056efc2011-01-16 21:38:35 +00002817 if( crt->serial.len == cur->serial.len &&
2818 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002819 {
2820 if( x509parse_time_expired( &cur->revocation_date ) )
2821 return( 1 );
2822 }
2823
2824 cur = cur->next;
2825 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002826
2827 return( 0 );
2828}
2829
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002830/*
2831 * Wrapper for x509 hashes.
2832 *
Paul Bakker0f5f72e2011-01-18 14:58:55 +00002833 * \param out Buffer to receive the hash (Should be at least 64 bytes)
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002834 */
Paul Bakker23986e52011-04-24 08:57:21 +00002835static void x509_hash( const unsigned char *in, size_t len, int alg,
Paul Bakker5121ce52009-01-03 21:22:43 +00002836 unsigned char *out )
2837{
2838 switch( alg )
2839 {
Paul Bakker40e46942009-01-03 21:51:57 +00002840#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002841 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002842#endif
Paul Bakker40e46942009-01-03 21:51:57 +00002843#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002844 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002845#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002846#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002847 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002848#endif
2849#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002850 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002851#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00002852#if defined(POLARSSL_SHA2_C)
2853 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
2854 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
2855#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00002856#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002857 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
2858 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
2859#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002860 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002861 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002862 break;
2863 }
2864}
2865
2866/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00002867 * Check that the given certificate is valid accoring to the CRL.
2868 */
2869static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
2870 x509_crl *crl_list)
2871{
2872 int flags = 0;
2873 int hash_id;
2874 unsigned char hash[64];
2875
2876 /*
2877 * TODO: What happens if no CRL is present?
2878 * Suggestion: Revocation state should be unknown if no CRL is present.
2879 * For backwards compatibility this is not yet implemented.
2880 */
2881
2882 while( ca != NULL && crl_list != NULL && crl_list->version != 0 )
2883 {
2884 if( crl_list->issuer_raw.len != ca->subject_raw.len ||
2885 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
2886 crl_list->issuer_raw.len ) != 0 )
2887 {
2888 crl_list = crl_list->next;
2889 continue;
2890 }
2891
2892 /*
2893 * Check if CRL is correctly signed by the trusted CA
2894 */
2895 hash_id = crl_list->sig_alg;
2896
2897 x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
2898
2899 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, hash_id,
2900 0, hash, crl_list->sig.p ) == 0 )
2901 {
2902 /*
2903 * CRL is not trusted
2904 */
2905 flags |= BADCRL_NOT_TRUSTED;
2906 break;
2907 }
2908
2909 /*
2910 * Check for validity of CRL (Do not drop out)
2911 */
2912 if( x509parse_time_expired( &crl_list->next_update ) )
2913 flags |= BADCRL_EXPIRED;
2914
2915 /*
2916 * Check if certificate is revoked
2917 */
2918 if( x509parse_revoked(crt, crl_list) )
2919 {
2920 flags |= BADCERT_REVOKED;
2921 break;
2922 }
2923
2924 crl_list = crl_list->next;
2925 }
2926 return flags;
2927}
2928
2929/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002930 * Verify the certificate validity
2931 */
2932int x509parse_verify( x509_cert *crt,
2933 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00002934 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002935 const char *cn, int *flags,
2936 int (*f_vrfy)(void *, x509_cert *, int, int),
2937 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00002938{
Paul Bakker23986e52011-04-24 08:57:21 +00002939 size_t cn_len;
Paul Bakker5121ce52009-01-03 21:22:43 +00002940 int hash_id;
2941 int pathlen;
Paul Bakker76fd75a2011-01-16 21:12:10 +00002942 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00002943 x509_name *name;
Paul Bakker4593aea2009-02-09 22:32:35 +00002944 unsigned char hash[64];
Paul Bakker5121ce52009-01-03 21:22:43 +00002945
Paul Bakker40ea7de2009-05-03 10:18:48 +00002946 *flags = 0;
2947
2948 if( x509parse_time_expired( &crt->valid_to ) )
2949 *flags = BADCERT_EXPIRED;
Paul Bakker5121ce52009-01-03 21:22:43 +00002950
2951 if( cn != NULL )
2952 {
2953 name = &crt->subject;
2954 cn_len = strlen( cn );
2955
2956 while( name != NULL )
2957 {
2958 if( memcmp( name->oid.p, OID_CN, 3 ) == 0 &&
2959 memcmp( name->val.p, cn, cn_len ) == 0 &&
2960 name->val.len == cn_len )
2961 break;
2962
2963 name = name->next;
2964 }
2965
2966 if( name == NULL )
2967 *flags |= BADCERT_CN_MISMATCH;
2968 }
2969
Paul Bakker5121ce52009-01-03 21:22:43 +00002970 /*
2971 * Iterate upwards in the given cert chain,
2972 * ignoring any upper cert with CA != TRUE.
2973 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00002974 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002975
2976 pathlen = 1;
2977
Paul Bakker76fd75a2011-01-16 21:12:10 +00002978 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002979 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002980 if( parent->ca_istrue == 0 ||
2981 crt->issuer_raw.len != parent->subject_raw.len ||
2982 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00002983 crt->issuer_raw.len ) != 0 )
2984 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00002985 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002986 continue;
2987 }
2988
Paul Bakker27d66162010-03-17 06:56:01 +00002989 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00002990
2991 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
2992
Paul Bakker76fd75a2011-01-16 21:12:10 +00002993 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, hash_id, 0, hash,
2994 crt->sig.p ) != 0 )
2995 *flags |= BADCERT_NOT_TRUSTED;
2996
2997 /* Check trusted CA's CRL for the given crt */
2998 *flags |= x509parse_verifycrl(crt, parent, ca_crl);
Paul Bakkerb63b0af2011-01-13 17:54:59 +00002999
3000 /* crt is verified to be a child of the parent cur, call verify callback */
Paul Bakker74111d32011-01-15 16:57:55 +00003001 if( NULL != f_vrfy )
3002 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003003 if( f_vrfy( p_vrfy, crt, pathlen - 1, ( *flags == 0 ) ) != 0 )
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003004 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker76fd75a2011-01-16 21:12:10 +00003005 else
3006 *flags = 0;
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003007 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00003008 else if( *flags != 0 )
3009 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00003010
3011 pathlen++;
3012
Paul Bakker76fd75a2011-01-16 21:12:10 +00003013 crt = parent;
3014 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003015 }
3016
3017 /*
Paul Bakker76fd75a2011-01-16 21:12:10 +00003018 * Attempt to validate topmost cert with our CA chain.
Paul Bakker5121ce52009-01-03 21:22:43 +00003019 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003020 *flags |= BADCERT_NOT_TRUSTED;
3021
Paul Bakker7c6d4a42009-03-28 20:35:47 +00003022 while( trust_ca != NULL && trust_ca->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003023 {
3024 if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
3025 memcmp( crt->issuer_raw.p, trust_ca->subject_raw.p,
3026 crt->issuer_raw.len ) != 0 )
3027 {
3028 trust_ca = trust_ca->next;
3029 continue;
3030 }
3031
3032 if( trust_ca->max_pathlen > 0 &&
3033 trust_ca->max_pathlen < pathlen )
3034 break;
3035
Paul Bakker27d66162010-03-17 06:56:01 +00003036 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00003037
3038 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
3039
3040 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
3041 0, hash, crt->sig.p ) == 0 )
3042 {
3043 /*
3044 * cert. is signed by a trusted CA
3045 */
3046 *flags &= ~BADCERT_NOT_TRUSTED;
3047 break;
3048 }
3049
3050 trust_ca = trust_ca->next;
3051 }
3052
Paul Bakker76fd75a2011-01-16 21:12:10 +00003053 /* Check trusted CA's CRL for the given crt */
3054 *flags |= x509parse_verifycrl( crt, trust_ca, ca_crl );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003055
3056 /* Verification succeeded, call callback on top cert */
Paul Bakker74111d32011-01-15 16:57:55 +00003057 if( NULL != f_vrfy )
3058 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003059 if( f_vrfy(p_vrfy, crt, pathlen-1, ( *flags == 0 ) ) != 0 )
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003060 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker76fd75a2011-01-16 21:12:10 +00003061 else
3062 *flags = 0;
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003063 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00003064 else if( *flags != 0 )
3065 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003066
Paul Bakker5121ce52009-01-03 21:22:43 +00003067 return( 0 );
3068}
3069
3070/*
3071 * Unallocate all certificate data
3072 */
3073void x509_free( x509_cert *crt )
3074{
3075 x509_cert *cert_cur = crt;
3076 x509_cert *cert_prv;
3077 x509_name *name_cur;
3078 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00003079 x509_sequence *seq_cur;
3080 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00003081
3082 if( crt == NULL )
3083 return;
3084
3085 do
3086 {
3087 rsa_free( &cert_cur->rsa );
3088
3089 name_cur = cert_cur->issuer.next;
3090 while( name_cur != NULL )
3091 {
3092 name_prv = name_cur;
3093 name_cur = name_cur->next;
3094 memset( name_prv, 0, sizeof( x509_name ) );
3095 free( name_prv );
3096 }
3097
3098 name_cur = cert_cur->subject.next;
3099 while( name_cur != NULL )
3100 {
3101 name_prv = name_cur;
3102 name_cur = name_cur->next;
3103 memset( name_prv, 0, sizeof( x509_name ) );
3104 free( name_prv );
3105 }
3106
Paul Bakker74111d32011-01-15 16:57:55 +00003107 seq_cur = cert_cur->ext_key_usage.next;
3108 while( seq_cur != NULL )
3109 {
3110 seq_prv = seq_cur;
3111 seq_cur = seq_cur->next;
3112 memset( seq_prv, 0, sizeof( x509_sequence ) );
3113 free( seq_prv );
3114 }
3115
Paul Bakker5121ce52009-01-03 21:22:43 +00003116 if( cert_cur->raw.p != NULL )
3117 {
3118 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
3119 free( cert_cur->raw.p );
3120 }
3121
3122 cert_cur = cert_cur->next;
3123 }
3124 while( cert_cur != NULL );
3125
3126 cert_cur = crt;
3127 do
3128 {
3129 cert_prv = cert_cur;
3130 cert_cur = cert_cur->next;
3131
3132 memset( cert_prv, 0, sizeof( x509_cert ) );
3133 if( cert_prv != crt )
3134 free( cert_prv );
3135 }
3136 while( cert_cur != NULL );
3137}
3138
Paul Bakkerd98030e2009-05-02 15:13:40 +00003139/*
3140 * Unallocate all CRL data
3141 */
3142void x509_crl_free( x509_crl *crl )
3143{
3144 x509_crl *crl_cur = crl;
3145 x509_crl *crl_prv;
3146 x509_name *name_cur;
3147 x509_name *name_prv;
3148 x509_crl_entry *entry_cur;
3149 x509_crl_entry *entry_prv;
3150
3151 if( crl == NULL )
3152 return;
3153
3154 do
3155 {
3156 name_cur = crl_cur->issuer.next;
3157 while( name_cur != NULL )
3158 {
3159 name_prv = name_cur;
3160 name_cur = name_cur->next;
3161 memset( name_prv, 0, sizeof( x509_name ) );
3162 free( name_prv );
3163 }
3164
3165 entry_cur = crl_cur->entry.next;
3166 while( entry_cur != NULL )
3167 {
3168 entry_prv = entry_cur;
3169 entry_cur = entry_cur->next;
3170 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
3171 free( entry_prv );
3172 }
3173
3174 if( crl_cur->raw.p != NULL )
3175 {
3176 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
3177 free( crl_cur->raw.p );
3178 }
3179
3180 crl_cur = crl_cur->next;
3181 }
3182 while( crl_cur != NULL );
3183
3184 crl_cur = crl;
3185 do
3186 {
3187 crl_prv = crl_cur;
3188 crl_cur = crl_cur->next;
3189
3190 memset( crl_prv, 0, sizeof( x509_crl ) );
3191 if( crl_prv != crl )
3192 free( crl_prv );
3193 }
3194 while( crl_cur != NULL );
3195}
3196
Paul Bakker40e46942009-01-03 21:51:57 +00003197#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00003198
Paul Bakker40e46942009-01-03 21:51:57 +00003199#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00003200
3201/*
3202 * Checkup routine
3203 */
3204int x509_self_test( int verbose )
3205{
Paul Bakker5690efc2011-05-26 13:16:06 +00003206#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00003207 int ret;
3208 int flags;
3209 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00003210 x509_cert cacert;
3211 x509_cert clicert;
3212 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00003213#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003214 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00003215#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003216
3217 if( verbose != 0 )
3218 printf( " X.509 certificate load: " );
3219
3220 memset( &clicert, 0, sizeof( x509_cert ) );
3221
3222 ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
3223 strlen( test_cli_crt ) );
3224 if( ret != 0 )
3225 {
3226 if( verbose != 0 )
3227 printf( "failed\n" );
3228
3229 return( ret );
3230 }
3231
3232 memset( &cacert, 0, sizeof( x509_cert ) );
3233
3234 ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
3235 strlen( test_ca_crt ) );
3236 if( ret != 0 )
3237 {
3238 if( verbose != 0 )
3239 printf( "failed\n" );
3240
3241 return( ret );
3242 }
3243
3244 if( verbose != 0 )
3245 printf( "passed\n X.509 private key load: " );
3246
3247 i = strlen( test_ca_key );
3248 j = strlen( test_ca_pwd );
3249
Paul Bakker66b78b22011-03-25 14:22:50 +00003250 rsa_init( &rsa, RSA_PKCS_V15, 0 );
3251
Paul Bakker5121ce52009-01-03 21:22:43 +00003252 if( ( ret = x509parse_key( &rsa,
3253 (unsigned char *) test_ca_key, i,
3254 (unsigned char *) test_ca_pwd, j ) ) != 0 )
3255 {
3256 if( verbose != 0 )
3257 printf( "failed\n" );
3258
3259 return( ret );
3260 }
3261
3262 if( verbose != 0 )
3263 printf( "passed\n X.509 signature verify: ");
3264
Paul Bakker23986e52011-04-24 08:57:21 +00003265 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003266 if( ret != 0 )
3267 {
Paul Bakker23986e52011-04-24 08:57:21 +00003268 printf("%02x", flags);
Paul Bakker5121ce52009-01-03 21:22:43 +00003269 if( verbose != 0 )
3270 printf( "failed\n" );
3271
3272 return( ret );
3273 }
3274
Paul Bakker5690efc2011-05-26 13:16:06 +00003275#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003276 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003277 printf( "passed\n X.509 DHM parameter load: " );
3278
3279 i = strlen( test_dhm_params );
3280 j = strlen( test_ca_pwd );
3281
3282 if( ( ret = x509parse_dhm( &dhm, (unsigned char *) test_dhm_params, i ) ) != 0 )
3283 {
3284 if( verbose != 0 )
3285 printf( "failed\n" );
3286
3287 return( ret );
3288 }
3289
3290 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003291 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00003292#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003293
3294 x509_free( &cacert );
3295 x509_free( &clicert );
3296 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00003297#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003298 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00003299#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003300
3301 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003302#else
3303 ((void) verbose);
3304 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3305#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003306}
3307
3308#endif
3309
3310#endif