blob: 9e05f98cba489d8cc59adcdeb718be30a065df0e [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * X.509 certificate and private key decoding
3 *
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02004 * Copyright (C) 2006-2013, 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/*
Paul Bakkerad8d3542012-02-16 15:28:14 +000026 * The ITU-T X.509 standard defines a certificate format for PKI.
Paul Bakker5121ce52009-01-03 21:22:43 +000027 *
Paul Bakker5121ce52009-01-03 21:22:43 +000028 * http://www.ietf.org/rfc/rfc3279.txt
Paul Bakkerad8d3542012-02-16 15:28:14 +000029 * http://www.ietf.org/rfc/rfc3280.txt
Paul Bakker5121ce52009-01-03 21:22:43 +000030 *
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 Bakkerefc30292011-11-10 14:43:23 +000042#include "polarssl/asn1.h"
Paul Bakkerc70b9822013-04-07 22:00:46 +020043#include "polarssl/oid.h"
Paul Bakker96743fc2011-02-12 14:30:57 +000044#include "polarssl/pem.h"
Paul Bakker1b57b062011-01-06 15:48:19 +000045#include "polarssl/dhm.h"
Paul Bakker28144de2013-06-24 19:28:55 +020046#if defined(POLARSSL_PKCS5_C)
47#include "polarssl/pkcs5.h"
48#endif
Paul Bakker38b50d72013-06-24 19:33:27 +020049#if defined(POLARSSL_PKCS12_C)
50#include "polarssl/pkcs12.h"
51#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000052
Paul Bakker6e339b52013-07-03 13:37:05 +020053#if defined(POLARSSL_MEMORY_C)
54#include "polarssl/memory.h"
55#else
56#define polarssl_malloc malloc
57#define polarssl_free free
58#endif
59
Paul Bakker5121ce52009-01-03 21:22:43 +000060#include <string.h>
61#include <stdlib.h>
Paul Bakker4f229e52011-12-04 22:11:35 +000062#if defined(_WIN32)
Paul Bakkercce9d772011-11-18 14:26:47 +000063#include <windows.h>
64#else
Paul Bakker5121ce52009-01-03 21:22:43 +000065#include <time.h>
Paul Bakkercce9d772011-11-18 14:26:47 +000066#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000067
Paul Bakker335db3f2011-04-25 15:28:35 +000068#if defined(POLARSSL_FS_IO)
69#include <stdio.h>
Paul Bakker4a2bd0d2012-11-02 11:06:08 +000070#if !defined(_WIN32)
Paul Bakker8d914582012-06-04 12:46:42 +000071#include <sys/types.h>
Paul Bakker2c8cdd22013-06-24 19:22:42 +020072#include <sys/stat.h>
Paul Bakker8d914582012-06-04 12:46:42 +000073#include <dirent.h>
74#endif
Paul Bakker335db3f2011-04-25 15:28:35 +000075#endif
76
Paul Bakker5121ce52009-01-03 21:22:43 +000077/*
Paul Bakker5121ce52009-01-03 21:22:43 +000078 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
79 */
80static int x509_get_version( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +000081 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +000082 int *ver )
83{
Paul Bakker23986e52011-04-24 08:57:21 +000084 int ret;
85 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +000086
87 if( ( ret = asn1_get_tag( p, end, &len,
88 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
89 {
Paul Bakker40e46942009-01-03 21:51:57 +000090 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +000091 {
92 *ver = 0;
93 return( 0 );
94 }
Paul Bakker5121ce52009-01-03 21:22:43 +000095
96 return( ret );
97 }
98
99 end = *p + len;
100
101 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000102 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000103
104 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000105 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION +
Paul Bakker40e46942009-01-03 21:51:57 +0000106 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000107
108 return( 0 );
109}
110
111/*
Paul Bakkerfae618f2011-10-12 11:53:52 +0000112 * Version ::= INTEGER { v1(0), v2(1) }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000113 */
114static int x509_crl_get_version( unsigned char **p,
115 const unsigned char *end,
116 int *ver )
117{
118 int ret;
119
120 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
121 {
122 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +0000123 {
124 *ver = 0;
125 return( 0 );
126 }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000127
128 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
129 }
130
131 return( 0 );
132}
133
134/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000135 * CertificateSerialNumber ::= INTEGER
136 */
137static int x509_get_serial( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000138 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000139 x509_buf *serial )
140{
141 int ret;
142
143 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000144 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000145 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000146
147 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
148 **p != ASN1_INTEGER )
Paul Bakker9d781402011-05-09 16:17:09 +0000149 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000150 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000151
152 serial->tag = *(*p)++;
153
154 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000155 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000156
157 serial->p = *p;
158 *p += serial->len;
159
160 return( 0 );
161}
162
Manuel Pégourié-Gonnard0a64e8f2013-07-08 18:26:18 +0200163/* Get an algorithm identifier and its parameters
164 *
165 * AlgorithmIdentifier ::= SEQUENCE {
166 * algorithm OBJECT IDENTIFIER,
167 * parameters ANY DEFINED BY algorithm OPTIONAL }
168 */
169static int x509_get_algid( unsigned char **p,
170 const unsigned char *end,
171 pk_type_t *pk_alg, x509_buf *params )
172{
173 int ret;
174 x509_buf alg_oid;
175
176 memset( params, 0, sizeof(asn1_buf) );
177
178 if( ( ret = asn1_get_alg( p, end, &alg_oid, params ) ) != 0 )
179 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
180
181 if( oid_get_pk_alg( &alg_oid, pk_alg ) != 0 )
182 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
183
184 /*
185 * No parameters with RSA (only for EC)
186 */
187 if( *pk_alg == POLARSSL_PK_RSA &&
188 ( ( params->tag != ASN1_NULL && params->tag != 0 ) ||
189 params->len != 0 ) )
190 {
191 return( POLARSSL_ERR_X509_CERT_INVALID_ALG );
192 }
193
194 return( 0 );
195}
196
Paul Bakker5121ce52009-01-03 21:22:43 +0000197/*
198 * AlgorithmIdentifier ::= SEQUENCE {
199 * algorithm OBJECT IDENTIFIER,
200 * parameters ANY DEFINED BY algorithm OPTIONAL }
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +0200201 *
202 * If params_end is NULL, then parameters must be absent or ANS.1 NULL
Paul Bakker5121ce52009-01-03 21:22:43 +0000203 */
204static int x509_get_alg( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000205 const unsigned char *end,
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +0200206 x509_buf *alg, const unsigned char **params_end )
Paul Bakker5121ce52009-01-03 21:22:43 +0000207{
Paul Bakker23986e52011-04-24 08:57:21 +0000208 int ret;
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +0200209 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000210
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +0200211 if( params_end == NULL ) {
212 if( ( ret = asn1_get_alg_null( p, end, alg ) ) != 0 )
213 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
214
215 return( 0 );
216 }
217
218 /* TODO: use asn1_get_alg */
219 if( ( ret = asn1_get_tag( p, end, &len,
220 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
221 {
222 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
223 }
224
225 end = *p + len;
226 alg->tag = **p;
227
228 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000229 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000230
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +0200231 alg->p = *p;
232 *p += alg->len;
233
234 *params_end = end;
Paul Bakker5121ce52009-01-03 21:22:43 +0000235 return( 0 );
236}
237
Manuel Pégourié-Gonnardf838eed2013-07-02 14:56:43 +0200238/* Get an EC group id from an ECParameters buffer
239 *
240 * ECParameters ::= CHOICE {
241 * namedCurve OBJECT IDENTIFIER
242 * -- implicitCurve NULL
243 * -- specifiedCurve SpecifiedECDomain
244 * }
245 */
Manuel Pégourié-Gonnard0a64e8f2013-07-08 18:26:18 +0200246static int x509_ecparams_get_grp_id( const x509_buf *params,
247 ecp_group_id *grp_id )
248{
249 if( oid_get_ec_grp( params, grp_id ) != 0 )
250 return( POLARSSL_ERR_X509_UNKNOWN_NAMED_CURVE );
251
252 return( 0 );
253}
254
255/* Get an EC group id from an ECParameters buffer
256 *
257 * ECParameters ::= CHOICE {
258 * namedCurve OBJECT IDENTIFIER
259 * -- implicitCurve NULL
260 * -- specifiedCurve SpecifiedECDomain
261 * }
262 */
Manuel Pégourié-Gonnardf838eed2013-07-02 14:56:43 +0200263static int x509_get_ecparams( unsigned char **p, const unsigned char *end,
264 ecp_group_id *grp_id )
265{
266 int ret;
267 x509_buf curve;
268
269 curve.tag = **p;
270
271 if( ( ret = asn1_get_tag( p, end, &curve.len, ASN1_OID ) ) != 0 )
272 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
273
274 curve.p = *p;
275 *p += curve.len;
276
277 if( *p != end )
278 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
279 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
280
Manuel Pégourié-Gonnard0a64e8f2013-07-08 18:26:18 +0200281 return( x509_ecparams_get_grp_id( &curve, grp_id ) );
Manuel Pégourié-Gonnardf838eed2013-07-02 14:56:43 +0200282}
283
Paul Bakker5121ce52009-01-03 21:22:43 +0000284/*
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +0200285 * subjectPublicKey BIT STRING
286 * -- which, in our case, contains
287 * ECPoint ::= octet string (not ASN.1)
288 */
289static int x509_get_subpubkey_ec( unsigned char **p, const unsigned char *end,
290 const ecp_group *grp, ecp_point *pt )
291{
292 int ret;
293 size_t len;
294
295 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
296 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
297
298 if( *p + len != end )
299 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
300 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
301
302 /*
303 * First byte in the content of BIT STRING is the nummber of padding bit.
304 * Here it is always 0 since ECPoint is an octet string, so skip it.
305 */
306 ++*p;
307 --len;
308
309 if( ( ret = ecp_point_read_binary( grp, pt,
310 (const unsigned char *) *p, len ) ) != 0 )
311 {
312 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
313 }
314
315 return( 0 );
316}
317
318/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000319 * AttributeTypeAndValue ::= SEQUENCE {
320 * type AttributeType,
321 * value AttributeValue }
322 *
323 * AttributeType ::= OBJECT IDENTIFIER
324 *
325 * AttributeValue ::= ANY DEFINED BY AttributeType
326 */
Paul Bakker400ff6f2011-02-20 10:40:16 +0000327static int x509_get_attr_type_value( unsigned char **p,
328 const unsigned char *end,
329 x509_name *cur )
Paul Bakker5121ce52009-01-03 21:22:43 +0000330{
Paul Bakker23986e52011-04-24 08:57:21 +0000331 int ret;
332 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000333 x509_buf *oid;
334 x509_buf *val;
335
336 if( ( ret = asn1_get_tag( p, end, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000337 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000338 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000339
Paul Bakker5121ce52009-01-03 21:22:43 +0000340 oid = &cur->oid;
341 oid->tag = **p;
342
343 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000344 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000345
346 oid->p = *p;
347 *p += oid->len;
348
349 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000350 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000351 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000352
353 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
354 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
355 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker9d781402011-05-09 16:17:09 +0000356 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000357 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000358
359 val = &cur->val;
360 val->tag = *(*p)++;
361
362 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000363 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000364
365 val->p = *p;
366 *p += val->len;
367
368 cur->next = NULL;
369
Paul Bakker400ff6f2011-02-20 10:40:16 +0000370 return( 0 );
371}
372
373/*
374 * RelativeDistinguishedName ::=
375 * SET OF AttributeTypeAndValue
376 *
377 * AttributeTypeAndValue ::= SEQUENCE {
378 * type AttributeType,
379 * value AttributeValue }
380 *
381 * AttributeType ::= OBJECT IDENTIFIER
382 *
383 * AttributeValue ::= ANY DEFINED BY AttributeType
384 */
385static int x509_get_name( unsigned char **p,
386 const unsigned char *end,
387 x509_name *cur )
388{
Paul Bakker23986e52011-04-24 08:57:21 +0000389 int ret;
390 size_t len;
Paul Bakker400ff6f2011-02-20 10:40:16 +0000391 const unsigned char *end2;
392 x509_name *use;
393
394 if( ( ret = asn1_get_tag( p, end, &len,
395 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000396 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000397
398 end2 = end;
399 end = *p + len;
400 use = cur;
401
402 do
403 {
404 if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
405 return( ret );
406
407 if( *p != end )
408 {
Paul Bakker6e339b52013-07-03 13:37:05 +0200409 use->next = (x509_name *) polarssl_malloc(
Paul Bakker400ff6f2011-02-20 10:40:16 +0000410 sizeof( x509_name ) );
411
412 if( use->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000413 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000414
415 memset( use->next, 0, sizeof( x509_name ) );
416
417 use = use->next;
418 }
419 }
420 while( *p != end );
Paul Bakker5121ce52009-01-03 21:22:43 +0000421
422 /*
423 * recurse until end of SEQUENCE is reached
424 */
425 if( *p == end2 )
426 return( 0 );
427
Paul Bakker6e339b52013-07-03 13:37:05 +0200428 cur->next = (x509_name *) polarssl_malloc(
Paul Bakker5121ce52009-01-03 21:22:43 +0000429 sizeof( x509_name ) );
430
431 if( cur->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000432 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000433
Paul Bakker430ffbe2012-05-01 08:14:20 +0000434 memset( cur->next, 0, sizeof( x509_name ) );
435
Paul Bakker5121ce52009-01-03 21:22:43 +0000436 return( x509_get_name( p, end2, cur->next ) );
437}
438
439/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000440 * Time ::= CHOICE {
441 * utcTime UTCTime,
442 * generalTime GeneralizedTime }
443 */
Paul Bakker91200182010-02-18 21:26:15 +0000444static int x509_get_time( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000445 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000446 x509_time *time )
447{
Paul Bakker23986e52011-04-24 08:57:21 +0000448 int ret;
449 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000450 char date[64];
Paul Bakker91200182010-02-18 21:26:15 +0000451 unsigned char tag;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000452
Paul Bakker91200182010-02-18 21:26:15 +0000453 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000454 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
455 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000456
Paul Bakker91200182010-02-18 21:26:15 +0000457 tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000458
Paul Bakker91200182010-02-18 21:26:15 +0000459 if ( tag == ASN1_UTC_TIME )
460 {
461 (*p)++;
462 ret = asn1_get_len( p, end, &len );
463
464 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000465 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000466
Paul Bakker91200182010-02-18 21:26:15 +0000467 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000468 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
469 len : sizeof( date ) - 1 );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000470
Paul Bakker91200182010-02-18 21:26:15 +0000471 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
472 &time->year, &time->mon, &time->day,
473 &time->hour, &time->min, &time->sec ) < 5 )
474 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000475
Paul Bakker400ff6f2011-02-20 10:40:16 +0000476 time->year += 100 * ( time->year < 50 );
Paul Bakker91200182010-02-18 21:26:15 +0000477 time->year += 1900;
478
479 *p += len;
480
481 return( 0 );
482 }
483 else if ( tag == ASN1_GENERALIZED_TIME )
484 {
485 (*p)++;
486 ret = asn1_get_len( p, end, &len );
487
488 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000489 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker91200182010-02-18 21:26:15 +0000490
491 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000492 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
493 len : sizeof( date ) - 1 );
Paul Bakker91200182010-02-18 21:26:15 +0000494
495 if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
496 &time->year, &time->mon, &time->day,
497 &time->hour, &time->min, &time->sec ) < 5 )
498 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
499
500 *p += len;
501
502 return( 0 );
503 }
504 else
Paul Bakker9d781402011-05-09 16:17:09 +0000505 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000506}
507
508
509/*
510 * Validity ::= SEQUENCE {
511 * notBefore Time,
512 * notAfter Time }
513 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000514static int x509_get_dates( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000515 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000516 x509_time *from,
517 x509_time *to )
518{
Paul Bakker23986e52011-04-24 08:57:21 +0000519 int ret;
520 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000521
522 if( ( ret = asn1_get_tag( p, end, &len,
523 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000524 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000525
526 end = *p + len;
527
Paul Bakker91200182010-02-18 21:26:15 +0000528 if( ( ret = x509_get_time( p, end, from ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000529 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000530
Paul Bakker91200182010-02-18 21:26:15 +0000531 if( ( ret = x509_get_time( p, end, to ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000532 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000533
534 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000535 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker40e46942009-01-03 21:51:57 +0000536 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000537
538 return( 0 );
539}
540
541/*
Manuel Pégourié-Gonnard094ad9e2013-07-09 12:32:51 +0200542 * RSAPublicKey ::= SEQUENCE {
543 * modulus INTEGER, -- n
544 * publicExponent INTEGER -- e
545 * }
546 */
547static int x509_get_rsapubkey( unsigned char **p,
548 const unsigned char *end,
549 rsa_context *rsa )
550{
551 int ret;
552 size_t len;
553
554 if( ( ret = asn1_get_tag( p, end, &len,
555 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
556 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
557
558 if( *p + len != end )
559 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
560 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
561
562 if( ( ret = asn1_get_mpi( p, end, &rsa->N ) ) != 0 ||
563 ( ret = asn1_get_mpi( p, end, &rsa->E ) ) != 0 )
564 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
565
566 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
567 return( ret );
568
569 rsa->len = mpi_size( &rsa->N );
570
571 return( 0 );
572}
573
Manuel Pégourié-Gonnardc296c592013-07-09 12:54:04 +0200574static int x509_get_ecpubkey( unsigned char **p, const unsigned char *end,
575 x509_buf *alg_params, ecp_keypair *key )
576{
577 int ret;
578 ecp_group_id grp_id;
579
580 if( ( ret = x509_ecparams_get_grp_id( alg_params, &grp_id ) ) != 0 )
581 return( ret );
582
583 if( ( ret = ecp_use_known_dp( &key->grp, grp_id ) ) != 0 )
584 return( ret );
585
586 if( ( ret = ecp_point_read_binary( &key->grp, &key->Q,
587 (const unsigned char *) *p, end - *p ) ) != 0 )
588 {
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +0200589 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Manuel Pégourié-Gonnardc296c592013-07-09 12:54:04 +0200590 }
591
592 return( 0 );
593}
594
595/*
596 * SubjectPublicKeyInfo ::= SEQUENCE {
597 * algorithm AlgorithmIdentifier,
598 * subjectPublicKey BIT STRING }
599 */
600static int x509_get_pubkey( unsigned char **p,
601 const unsigned char *end,
602 pk_context *pk )
603{
604 int ret;
605 size_t len;
606 x509_buf alg_params;
607 pk_type_t pk_alg = POLARSSL_PK_NONE;
608
609 if( ( ret = asn1_get_tag( p, end, &len,
610 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
611 {
612 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
613 }
614
615 end = *p + len;
616
617 if( ( ret = x509_get_algid( p, end, &pk_alg, &alg_params ) ) != 0 )
618 return( ret );
619
620 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
621 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
622
623 if( ( end - *p ) < 1 )
624 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
625 POLARSSL_ERR_ASN1_OUT_OF_DATA );
626
627 if( *p + len != end )
628 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
629 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
630
631 if( *(*p)++ != 0 )
632 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
633
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +0200634 if( ( ret = pk_set_type( pk, pk_alg ) ) != 0 )
635 return( ret );
Manuel Pégourié-Gonnardc296c592013-07-09 12:54:04 +0200636
637 switch( pk_alg )
638 {
639 case POLARSSL_PK_NONE:
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +0200640 ret = POLARSSL_ERR_X509_UNKNOWN_PK_ALG;
641 break;
Manuel Pégourié-Gonnardc296c592013-07-09 12:54:04 +0200642
643 case POLARSSL_PK_RSA:
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +0200644 ret = x509_get_rsapubkey( p, end, pk->data );
645 break;
Manuel Pégourié-Gonnardc296c592013-07-09 12:54:04 +0200646
647 case POLARSSL_PK_ECKEY_DH:
648 ((ecp_keypair *) pk->data)->alg = POLARSSL_ECP_KEY_ALG_ECDH;
649 /* FALLTHROUGH */
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +0200650
Manuel Pégourié-Gonnardc296c592013-07-09 12:54:04 +0200651 case POLARSSL_PK_ECKEY:
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +0200652 ret = x509_get_ecpubkey( p, end, &alg_params, pk->data );
653 break;
Manuel Pégourié-Gonnardc296c592013-07-09 12:54:04 +0200654 }
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +0200655
656 if( ret != 0 )
657 pk_free( pk );
658
659 return( ret );
Manuel Pégourié-Gonnardc296c592013-07-09 12:54:04 +0200660}
661
Manuel Pégourié-Gonnard094ad9e2013-07-09 12:32:51 +0200662/*
Manuel Pégourié-Gonnard244569f2013-07-10 09:46:30 +0200663 * Get an RSA public key (compatibility wrapper)
Paul Bakker5121ce52009-01-03 21:22:43 +0000664 */
Manuel Pégourié-Gonnard094ad9e2013-07-09 12:32:51 +0200665static int x509_get_pubkey_rsa( unsigned char **p,
666 const unsigned char *end,
667 rsa_context *rsa )
Paul Bakker5121ce52009-01-03 21:22:43 +0000668{
Manuel Pégourié-Gonnard244569f2013-07-10 09:46:30 +0200669 pk_context pk_ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000670
Manuel Pégourié-Gonnard244569f2013-07-10 09:46:30 +0200671 pk_init( &pk_ctx );
672 pk_wrap_rsa( &pk_ctx, rsa );
Manuel Pégourié-Gonnard20c12f62013-07-09 12:13:24 +0200673
Manuel Pégourié-Gonnard244569f2013-07-10 09:46:30 +0200674 return( x509_get_pubkey( p, end, &pk_ctx ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000675}
676
677static int x509_get_sig( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000678 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000679 x509_buf *sig )
680{
Paul Bakker23986e52011-04-24 08:57:21 +0000681 int ret;
682 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000683
Paul Bakker8afa70d2012-02-11 18:42:45 +0000684 if( ( end - *p ) < 1 )
685 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE +
686 POLARSSL_ERR_ASN1_OUT_OF_DATA );
687
Paul Bakker5121ce52009-01-03 21:22:43 +0000688 sig->tag = **p;
689
690 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000691 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000692
Paul Bakker74111d32011-01-15 16:57:55 +0000693
Paul Bakker5121ce52009-01-03 21:22:43 +0000694 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000695 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000696
697 sig->len = len;
698 sig->p = *p;
699
700 *p += len;
701
702 return( 0 );
703}
704
705/*
706 * X.509 v2/v3 unique identifier (not parsed)
707 */
708static int x509_get_uid( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000709 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000710 x509_buf *uid, int n )
711{
712 int ret;
713
714 if( *p == end )
715 return( 0 );
716
717 uid->tag = **p;
718
719 if( ( ret = asn1_get_tag( p, end, &uid->len,
720 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
721 {
Paul Bakker40e46942009-01-03 21:51:57 +0000722 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000723 return( 0 );
724
725 return( ret );
726 }
727
728 uid->p = *p;
729 *p += uid->len;
730
731 return( 0 );
732}
733
734/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000735 * X.509 Extensions (No parsing of extensions, pointer should
736 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000737 */
738static int x509_get_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000739 const unsigned char *end,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000740 x509_buf *ext, int tag )
Paul Bakker5121ce52009-01-03 21:22:43 +0000741{
Paul Bakker23986e52011-04-24 08:57:21 +0000742 int ret;
743 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000744
745 if( *p == end )
746 return( 0 );
747
748 ext->tag = **p;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000749
Paul Bakker5121ce52009-01-03 21:22:43 +0000750 if( ( ret = asn1_get_tag( p, end, &ext->len,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000751 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000752 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000753
754 ext->p = *p;
755 end = *p + ext->len;
756
757 /*
758 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
759 *
760 * Extension ::= SEQUENCE {
761 * extnID OBJECT IDENTIFIER,
762 * critical BOOLEAN DEFAULT FALSE,
763 * extnValue OCTET STRING }
764 */
765 if( ( ret = asn1_get_tag( p, end, &len,
766 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000767 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000768
769 if( end != *p + len )
Paul Bakker9d781402011-05-09 16:17:09 +0000770 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +0000771 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000772
Paul Bakkerd98030e2009-05-02 15:13:40 +0000773 return( 0 );
774}
775
776/*
777 * X.509 CRL v2 extensions (no extensions parsed yet.)
778 */
779static int x509_get_crl_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000780 const unsigned char *end,
781 x509_buf *ext )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000782{
Paul Bakker23986e52011-04-24 08:57:21 +0000783 int ret;
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000784 size_t len = 0;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000785
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000786 /* Get explicit tag */
787 if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000788 {
789 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
790 return( 0 );
791
792 return( ret );
793 }
794
795 while( *p < end )
796 {
797 if( ( ret = asn1_get_tag( p, end, &len,
798 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000799 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000800
801 *p += len;
802 }
803
804 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000805 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerd98030e2009-05-02 15:13:40 +0000806 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
807
808 return( 0 );
809}
810
Paul Bakkerb5a11ab2011-10-12 09:58:41 +0000811/*
812 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
813 */
814static int x509_get_crl_entry_ext( unsigned char **p,
815 const unsigned char *end,
816 x509_buf *ext )
817{
818 int ret;
819 size_t len = 0;
820
821 /* OPTIONAL */
822 if (end <= *p)
823 return( 0 );
824
825 ext->tag = **p;
826 ext->p = *p;
827
828 /*
829 * Get CRL-entry extension sequence header
830 * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
831 */
832 if( ( ret = asn1_get_tag( p, end, &ext->len,
833 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
834 {
835 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
836 {
837 ext->p = NULL;
838 return( 0 );
839 }
840 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
841 }
842
843 end = *p + ext->len;
844
845 if( end != *p + ext->len )
846 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
847 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
848
849 while( *p < end )
850 {
851 if( ( ret = asn1_get_tag( p, end, &len,
852 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
853 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
854
855 *p += len;
856 }
857
858 if( *p != end )
859 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
860 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
861
862 return( 0 );
863}
864
Paul Bakker74111d32011-01-15 16:57:55 +0000865static int x509_get_basic_constraints( unsigned char **p,
866 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000867 int *ca_istrue,
868 int *max_pathlen )
869{
Paul Bakker23986e52011-04-24 08:57:21 +0000870 int ret;
871 size_t len;
Paul Bakker74111d32011-01-15 16:57:55 +0000872
873 /*
874 * BasicConstraints ::= SEQUENCE {
875 * cA BOOLEAN DEFAULT FALSE,
876 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
877 */
Paul Bakker3cccddb2011-01-16 21:46:31 +0000878 *ca_istrue = 0; /* DEFAULT FALSE */
Paul Bakker74111d32011-01-15 16:57:55 +0000879 *max_pathlen = 0; /* endless */
880
881 if( ( ret = asn1_get_tag( p, end, &len,
882 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000883 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000884
885 if( *p == end )
886 return 0;
887
Paul Bakker3cccddb2011-01-16 21:46:31 +0000888 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000889 {
890 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker3cccddb2011-01-16 21:46:31 +0000891 ret = asn1_get_int( p, end, ca_istrue );
Paul Bakker74111d32011-01-15 16:57:55 +0000892
893 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000894 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000895
Paul Bakker3cccddb2011-01-16 21:46:31 +0000896 if( *ca_istrue != 0 )
897 *ca_istrue = 1;
Paul Bakker74111d32011-01-15 16:57:55 +0000898 }
899
900 if( *p == end )
901 return 0;
902
903 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000904 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000905
906 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000907 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000908 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
909
910 (*max_pathlen)++;
911
Paul Bakker74111d32011-01-15 16:57:55 +0000912 return 0;
913}
914
915static int x509_get_ns_cert_type( unsigned char **p,
916 const unsigned char *end,
917 unsigned char *ns_cert_type)
918{
919 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000920 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000921
922 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000923 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000924
925 if( bs.len != 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000926 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000927 POLARSSL_ERR_ASN1_INVALID_LENGTH );
928
929 /* Get actual bitstring */
930 *ns_cert_type = *bs.p;
931 return 0;
932}
933
934static int x509_get_key_usage( unsigned char **p,
935 const unsigned char *end,
936 unsigned char *key_usage)
937{
938 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000939 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000940
941 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000942 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000943
Paul Bakker94a67962012-08-23 13:03:52 +0000944 if( bs.len < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000945 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000946 POLARSSL_ERR_ASN1_INVALID_LENGTH );
947
948 /* Get actual bitstring */
949 *key_usage = *bs.p;
950 return 0;
951}
952
Paul Bakkerd98030e2009-05-02 15:13:40 +0000953/*
Paul Bakker74111d32011-01-15 16:57:55 +0000954 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
955 *
956 * KeyPurposeId ::= OBJECT IDENTIFIER
957 */
958static int x509_get_ext_key_usage( unsigned char **p,
959 const unsigned char *end,
960 x509_sequence *ext_key_usage)
961{
962 int ret;
963
964 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000965 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000966
967 /* Sequence length must be >= 1 */
968 if( ext_key_usage->buf.p == NULL )
Paul Bakker9d781402011-05-09 16:17:09 +0000969 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000970 POLARSSL_ERR_ASN1_INVALID_LENGTH );
971
972 return 0;
973}
974
975/*
Paul Bakkera8cd2392012-02-11 16:09:32 +0000976 * SubjectAltName ::= GeneralNames
977 *
978 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
979 *
980 * GeneralName ::= CHOICE {
981 * otherName [0] OtherName,
982 * rfc822Name [1] IA5String,
983 * dNSName [2] IA5String,
984 * x400Address [3] ORAddress,
985 * directoryName [4] Name,
986 * ediPartyName [5] EDIPartyName,
987 * uniformResourceIdentifier [6] IA5String,
988 * iPAddress [7] OCTET STRING,
989 * registeredID [8] OBJECT IDENTIFIER }
990 *
991 * OtherName ::= SEQUENCE {
992 * type-id OBJECT IDENTIFIER,
993 * value [0] EXPLICIT ANY DEFINED BY type-id }
994 *
995 * EDIPartyName ::= SEQUENCE {
996 * nameAssigner [0] DirectoryString OPTIONAL,
997 * partyName [1] DirectoryString }
998 *
999 * NOTE: PolarSSL only parses and uses dNSName at this point.
1000 */
1001static int x509_get_subject_alt_name( unsigned char **p,
1002 const unsigned char *end,
1003 x509_sequence *subject_alt_name )
1004{
1005 int ret;
1006 size_t len, tag_len;
1007 asn1_buf *buf;
1008 unsigned char tag;
1009 asn1_sequence *cur = subject_alt_name;
1010
1011 /* Get main sequence tag */
1012 if( ( ret = asn1_get_tag( p, end, &len,
1013 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1014 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
1015
1016 if( *p + len != end )
1017 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
1018 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1019
1020 while( *p < end )
1021 {
1022 if( ( end - *p ) < 1 )
1023 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
1024 POLARSSL_ERR_ASN1_OUT_OF_DATA );
1025
1026 tag = **p;
1027 (*p)++;
1028 if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 )
1029 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
1030
1031 if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC )
1032 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
1033 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
1034
1035 if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) )
1036 {
1037 *p += tag_len;
1038 continue;
1039 }
1040
1041 buf = &(cur->buf);
1042 buf->tag = tag;
1043 buf->p = *p;
1044 buf->len = tag_len;
1045 *p += buf->len;
1046
1047 /* Allocate and assign next pointer */
1048 if (*p < end)
1049 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001050 cur->next = (asn1_sequence *) polarssl_malloc(
Paul Bakkera8cd2392012-02-11 16:09:32 +00001051 sizeof( asn1_sequence ) );
1052
1053 if( cur->next == NULL )
1054 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
1055 POLARSSL_ERR_ASN1_MALLOC_FAILED );
1056
Paul Bakker535e97d2012-08-23 10:49:55 +00001057 memset( cur->next, 0, sizeof( asn1_sequence ) );
Paul Bakkera8cd2392012-02-11 16:09:32 +00001058 cur = cur->next;
1059 }
1060 }
1061
1062 /* Set final sequence entry's next pointer to NULL */
1063 cur->next = NULL;
1064
1065 if( *p != end )
1066 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
1067 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1068
1069 return( 0 );
1070}
1071
1072/*
Paul Bakker74111d32011-01-15 16:57:55 +00001073 * X.509 v3 extensions
1074 *
1075 * TODO: Perform all of the basic constraints tests required by the RFC
1076 * TODO: Set values for undetected extensions to a sane default?
1077 *
Paul Bakkerd98030e2009-05-02 15:13:40 +00001078 */
1079static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001080 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +00001081 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001082{
Paul Bakker23986e52011-04-24 08:57:21 +00001083 int ret;
1084 size_t len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001085 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001086
Paul Bakkerfbc09f32011-10-12 09:56:41 +00001087 if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001088 {
1089 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
1090 return( 0 );
1091
1092 return( ret );
1093 }
1094
Paul Bakker5121ce52009-01-03 21:22:43 +00001095 while( *p < end )
1096 {
Paul Bakker74111d32011-01-15 16:57:55 +00001097 /*
1098 * Extension ::= SEQUENCE {
1099 * extnID OBJECT IDENTIFIER,
1100 * critical BOOLEAN DEFAULT FALSE,
1101 * extnValue OCTET STRING }
1102 */
1103 x509_buf extn_oid = {0, 0, NULL};
1104 int is_critical = 0; /* DEFAULT FALSE */
Paul Bakkerc70b9822013-04-07 22:00:46 +02001105 int ext_type = 0;
Paul Bakker74111d32011-01-15 16:57:55 +00001106
Paul Bakker5121ce52009-01-03 21:22:43 +00001107 if( ( ret = asn1_get_tag( p, end, &len,
1108 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +00001109 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001110
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001111 end_ext_data = *p + len;
1112
Paul Bakker74111d32011-01-15 16:57:55 +00001113 /* Get extension ID */
1114 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +00001115
Paul Bakker74111d32011-01-15 16:57:55 +00001116 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +00001117 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001118
Paul Bakker74111d32011-01-15 16:57:55 +00001119 extn_oid.p = *p;
1120 *p += extn_oid.len;
1121
1122 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +00001123 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +00001124 POLARSSL_ERR_ASN1_OUT_OF_DATA );
1125
1126 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001127 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +00001128 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
Paul Bakker9d781402011-05-09 16:17:09 +00001129 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001130
Paul Bakker74111d32011-01-15 16:57:55 +00001131 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001132 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +00001133 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +00001134 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001135
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001136 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +00001137
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001138 if( end_ext_octet != end_ext_data )
Paul Bakker9d781402011-05-09 16:17:09 +00001139 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001140 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001141
Paul Bakker74111d32011-01-15 16:57:55 +00001142 /*
1143 * Detect supported extensions
1144 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02001145 ret = oid_get_x509_ext_type( &extn_oid, &ext_type );
1146
1147 if( ret != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +00001148 {
1149 /* No parser found, skip extension */
1150 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +00001151
Paul Bakker5c721f92011-07-27 16:51:09 +00001152#if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
Paul Bakker74111d32011-01-15 16:57:55 +00001153 if( is_critical )
1154 {
1155 /* Data is marked as critical: fail */
Paul Bakker9d781402011-05-09 16:17:09 +00001156 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +00001157 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
1158 }
Paul Bakker5c721f92011-07-27 16:51:09 +00001159#endif
Paul Bakkerc70b9822013-04-07 22:00:46 +02001160 continue;
1161 }
1162
1163 crt->ext_types |= ext_type;
1164
1165 switch( ext_type )
1166 {
1167 case EXT_BASIC_CONSTRAINTS:
1168 /* Parse basic constraints */
1169 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
1170 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
1171 return ( ret );
1172 break;
1173
1174 case EXT_KEY_USAGE:
1175 /* Parse key usage */
1176 if( ( ret = x509_get_key_usage( p, end_ext_octet,
1177 &crt->key_usage ) ) != 0 )
1178 return ( ret );
1179 break;
1180
1181 case EXT_EXTENDED_KEY_USAGE:
1182 /* Parse extended key usage */
1183 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
1184 &crt->ext_key_usage ) ) != 0 )
1185 return ( ret );
1186 break;
1187
1188 case EXT_SUBJECT_ALT_NAME:
1189 /* Parse subject alt name */
1190 if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
1191 &crt->subject_alt_names ) ) != 0 )
1192 return ( ret );
1193 break;
1194
1195 case EXT_NS_CERT_TYPE:
1196 /* Parse netscape certificate type */
1197 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
1198 &crt->ns_cert_type ) ) != 0 )
1199 return ( ret );
1200 break;
1201
1202 default:
1203 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker74111d32011-01-15 16:57:55 +00001204 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001205 }
1206
1207 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +00001208 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +00001209 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001210
Paul Bakker5121ce52009-01-03 21:22:43 +00001211 return( 0 );
1212}
1213
1214/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001215 * X.509 CRL Entries
1216 */
1217static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001218 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001219 x509_crl_entry *entry )
1220{
Paul Bakker23986e52011-04-24 08:57:21 +00001221 int ret;
1222 size_t entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001223 x509_crl_entry *cur_entry = entry;
1224
1225 if( *p == end )
1226 return( 0 );
1227
Paul Bakker9be19372009-07-27 20:21:53 +00001228 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001229 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1230 {
1231 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
1232 return( 0 );
1233
1234 return( ret );
1235 }
1236
Paul Bakker9be19372009-07-27 20:21:53 +00001237 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001238
1239 while( *p < end )
1240 {
Paul Bakker23986e52011-04-24 08:57:21 +00001241 size_t len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001242 const unsigned char *end2;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001243
1244 if( ( ret = asn1_get_tag( p, end, &len2,
1245 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1246 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001247 return( ret );
1248 }
1249
Paul Bakker9be19372009-07-27 20:21:53 +00001250 cur_entry->raw.tag = **p;
1251 cur_entry->raw.p = *p;
1252 cur_entry->raw.len = len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001253 end2 = *p + len2;
Paul Bakker9be19372009-07-27 20:21:53 +00001254
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001255 if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001256 return( ret );
1257
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001258 if( ( ret = x509_get_time( p, end2, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001259 return( ret );
1260
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001261 if( ( ret = x509_get_crl_entry_ext( p, end2, &cur_entry->entry_ext ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001262 return( ret );
1263
Paul Bakker74111d32011-01-15 16:57:55 +00001264 if ( *p < end )
1265 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001266 cur_entry->next = polarssl_malloc( sizeof( x509_crl_entry ) );
Paul Bakkerb15b8512012-01-13 13:44:06 +00001267
1268 if( cur_entry->next == NULL )
1269 return( POLARSSL_ERR_X509_MALLOC_FAILED );
1270
Paul Bakkerd98030e2009-05-02 15:13:40 +00001271 cur_entry = cur_entry->next;
1272 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
1273 }
1274 }
1275
1276 return( 0 );
1277}
1278
Paul Bakkerc70b9822013-04-07 22:00:46 +02001279static int x509_get_sig_alg( const x509_buf *sig_oid, md_type_t *md_alg,
1280 pk_type_t *pk_alg )
Paul Bakker27d66162010-03-17 06:56:01 +00001281{
Paul Bakkerc70b9822013-04-07 22:00:46 +02001282 int ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg );
Paul Bakker27d66162010-03-17 06:56:01 +00001283
Paul Bakkerc70b9822013-04-07 22:00:46 +02001284 if( ret != 0 )
1285 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG + ret );
Paul Bakker27d66162010-03-17 06:56:01 +00001286
Paul Bakkerc70b9822013-04-07 22:00:46 +02001287 return( 0 );
Paul Bakker27d66162010-03-17 06:56:01 +00001288}
1289
Paul Bakkerd98030e2009-05-02 15:13:40 +00001290/*
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001291 * Parse and fill a single X.509 certificate in DER format
Paul Bakker5121ce52009-01-03 21:22:43 +00001292 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02001293static int x509parse_crt_der_core( x509_cert *crt, const unsigned char *buf,
1294 size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001295{
Paul Bakker23986e52011-04-24 08:57:21 +00001296 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001297 size_t len;
Paul Bakkerb00ca422012-09-25 12:10:00 +00001298 unsigned char *p, *end, *crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001299
Paul Bakker320a4b52009-03-28 18:52:39 +00001300 /*
1301 * Check for valid input
1302 */
1303 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001304 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker320a4b52009-03-28 18:52:39 +00001305
Paul Bakker6e339b52013-07-03 13:37:05 +02001306 p = (unsigned char *) polarssl_malloc( len = buflen );
Paul Bakker96743fc2011-02-12 14:30:57 +00001307
1308 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001309 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001310
1311 memcpy( p, buf, buflen );
1312
1313 buflen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001314
1315 crt->raw.p = p;
1316 crt->raw.len = len;
1317 end = p + len;
1318
1319 /*
1320 * Certificate ::= SEQUENCE {
1321 * tbsCertificate TBSCertificate,
1322 * signatureAlgorithm AlgorithmIdentifier,
1323 * signatureValue BIT STRING }
1324 */
1325 if( ( ret = asn1_get_tag( &p, end, &len,
1326 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1327 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001328 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001329 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001330 }
1331
Paul Bakkerb00ca422012-09-25 12:10:00 +00001332 if( len > (size_t) ( end - p ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001333 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001334 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001335 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001336 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001337 }
Paul Bakkerb00ca422012-09-25 12:10:00 +00001338 crt_end = p + len;
Paul Bakker42c65812013-06-24 19:21:59 +02001339
Paul Bakker5121ce52009-01-03 21:22:43 +00001340 /*
1341 * TBSCertificate ::= SEQUENCE {
1342 */
1343 crt->tbs.p = p;
1344
1345 if( ( ret = asn1_get_tag( &p, end, &len,
1346 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1347 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001348 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001349 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001350 }
1351
1352 end = p + len;
1353 crt->tbs.len = end - crt->tbs.p;
1354
1355 /*
1356 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1357 *
1358 * CertificateSerialNumber ::= INTEGER
1359 *
1360 * signature AlgorithmIdentifier
1361 */
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +02001362 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1363 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1364 ( ret = x509_get_alg( &p, end, &crt->sig_oid1, NULL ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001365 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001366 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001367 return( ret );
1368 }
1369
1370 crt->version++;
1371
1372 if( crt->version > 3 )
1373 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001374 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001375 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001376 }
1377
Paul Bakkerc70b9822013-04-07 22:00:46 +02001378 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_md,
1379 &crt->sig_pk ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001380 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001381 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001382 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001383 }
1384
1385 /*
1386 * issuer Name
1387 */
1388 crt->issuer_raw.p = p;
1389
1390 if( ( ret = asn1_get_tag( &p, end, &len,
1391 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1392 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001393 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001394 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001395 }
1396
1397 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1398 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001399 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001400 return( ret );
1401 }
1402
1403 crt->issuer_raw.len = p - crt->issuer_raw.p;
1404
1405 /*
1406 * Validity ::= SEQUENCE {
1407 * notBefore Time,
1408 * notAfter Time }
1409 *
1410 */
1411 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1412 &crt->valid_to ) ) != 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 * subject Name
1420 */
1421 crt->subject_raw.p = p;
1422
1423 if( ( ret = asn1_get_tag( &p, end, &len,
1424 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1425 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001426 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001427 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001428 }
1429
Paul Bakkercefb3962012-06-27 11:51:09 +00001430 if( len && ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001431 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001432 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001433 return( ret );
1434 }
1435
1436 crt->subject_raw.len = p - crt->subject_raw.p;
1437
1438 /*
Manuel Pégourié-Gonnard20c12f62013-07-09 12:13:24 +02001439 * SubjectPublicKeyInfo
Paul Bakker5121ce52009-01-03 21:22:43 +00001440 */
Manuel Pégourié-Gonnard094ad9e2013-07-09 12:32:51 +02001441 if( ( ret = x509_get_pubkey_rsa( &p, end, &crt->rsa ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001442 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001443 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001444 return( ret );
1445 }
1446
Paul Bakker5121ce52009-01-03 21:22:43 +00001447 /*
1448 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1449 * -- If present, version shall be v2 or v3
1450 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1451 * -- If present, version shall be v2 or v3
1452 * extensions [3] EXPLICIT Extensions OPTIONAL
1453 * -- If present, version shall be v3
1454 */
1455 if( crt->version == 2 || crt->version == 3 )
1456 {
1457 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1458 if( ret != 0 )
1459 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001460 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001461 return( ret );
1462 }
1463 }
1464
1465 if( crt->version == 2 || crt->version == 3 )
1466 {
1467 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1468 if( ret != 0 )
1469 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001470 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001471 return( ret );
1472 }
1473 }
1474
1475 if( crt->version == 3 )
1476 {
Paul Bakker74111d32011-01-15 16:57:55 +00001477 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001478 if( ret != 0 )
1479 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001480 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001481 return( ret );
1482 }
1483 }
1484
1485 if( p != end )
1486 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001487 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001488 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001489 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001490 }
1491
Paul Bakkerb00ca422012-09-25 12:10:00 +00001492 end = crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001493
1494 /*
Manuel Pégourié-Gonnard20c12f62013-07-09 12:13:24 +02001495 * }
1496 * -- end of TBSCertificate
1497 *
Paul Bakker5121ce52009-01-03 21:22:43 +00001498 * signatureAlgorithm AlgorithmIdentifier,
1499 * signatureValue BIT STRING
1500 */
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +02001501 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2, NULL ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001502 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001503 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001504 return( ret );
1505 }
1506
Paul Bakker535e97d2012-08-23 10:49:55 +00001507 if( crt->sig_oid1.len != crt->sig_oid2.len ||
1508 memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001509 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001510 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001511 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001512 }
1513
1514 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1515 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001516 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001517 return( ret );
1518 }
1519
1520 if( p != end )
1521 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001522 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001523 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001524 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001525 }
1526
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001527 return( 0 );
1528}
1529
1530/*
Paul Bakker42c65812013-06-24 19:21:59 +02001531 * Parse one X.509 certificate in DER format from a buffer and add them to a
1532 * chained list
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001533 */
Paul Bakker42c65812013-06-24 19:21:59 +02001534int x509parse_crt_der( x509_cert *chain, const unsigned char *buf, size_t buflen )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001535{
Paul Bakker42c65812013-06-24 19:21:59 +02001536 int ret;
1537 x509_cert *crt = chain, *prev = NULL;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001538
1539 /*
1540 * Check for valid input
1541 */
1542 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001543 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001544
1545 while( crt->version != 0 && crt->next != NULL )
1546 {
1547 prev = crt;
1548 crt = crt->next;
1549 }
1550
1551 /*
1552 * Add new certificate on the end of the chain if needed.
1553 */
1554 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001555 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001556 crt->next = (x509_cert *) polarssl_malloc( sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001557
Paul Bakker7d06ad22009-05-02 15:53:56 +00001558 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001559 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker320a4b52009-03-28 18:52:39 +00001560
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001561 prev = crt;
Paul Bakker7d06ad22009-05-02 15:53:56 +00001562 crt = crt->next;
1563 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001564 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001565
Paul Bakker42c65812013-06-24 19:21:59 +02001566 if( ( ret = x509parse_crt_der_core( crt, buf, buflen ) ) != 0 )
1567 {
1568 if( prev )
1569 prev->next = NULL;
1570
1571 if( crt != chain )
Paul Bakker6e339b52013-07-03 13:37:05 +02001572 polarssl_free( crt );
Paul Bakker42c65812013-06-24 19:21:59 +02001573
1574 return( ret );
1575 }
1576
1577 return( 0 );
1578}
1579
1580/*
1581 * Parse one or more PEM certificates from a buffer and add them to the chained list
1582 */
1583int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
1584{
1585 int ret, success = 0, first_error = 0, total_failed = 0;
1586 int buf_format = X509_FORMAT_DER;
1587
1588 /*
1589 * Check for valid input
1590 */
1591 if( chain == NULL || buf == NULL )
1592 return( POLARSSL_ERR_X509_INVALID_INPUT );
1593
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001594 /*
1595 * Determine buffer content. Buffer contains either one DER certificate or
1596 * one or more PEM certificates.
1597 */
1598#if defined(POLARSSL_PEM_C)
Paul Bakker3c2122f2013-06-24 19:03:14 +02001599 if( strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001600 buf_format = X509_FORMAT_PEM;
1601#endif
1602
1603 if( buf_format == X509_FORMAT_DER )
Paul Bakker42c65812013-06-24 19:21:59 +02001604 return x509parse_crt_der( chain, buf, buflen );
1605
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001606#if defined(POLARSSL_PEM_C)
1607 if( buf_format == X509_FORMAT_PEM )
1608 {
1609 pem_context pem;
1610
1611 while( buflen > 0 )
1612 {
1613 size_t use_len;
1614 pem_init( &pem );
1615
1616 ret = pem_read_buffer( &pem,
1617 "-----BEGIN CERTIFICATE-----",
1618 "-----END CERTIFICATE-----",
1619 buf, NULL, 0, &use_len );
1620
1621 if( ret == 0 )
1622 {
1623 /*
1624 * Was PEM encoded
1625 */
1626 buflen -= use_len;
1627 buf += use_len;
1628 }
Paul Bakker5ed3b342013-06-24 19:05:46 +02001629 else if( ret == POLARSSL_ERR_PEM_BAD_INPUT_DATA )
1630 {
1631 return( ret );
1632 }
Paul Bakker00b28602013-06-24 13:02:41 +02001633 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001634 {
1635 pem_free( &pem );
1636
Paul Bakker5ed3b342013-06-24 19:05:46 +02001637 /*
1638 * PEM header and footer were found
1639 */
1640 buflen -= use_len;
1641 buf += use_len;
1642
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001643 if( first_error == 0 )
1644 first_error = ret;
1645
1646 continue;
1647 }
1648 else
1649 break;
1650
Paul Bakker42c65812013-06-24 19:21:59 +02001651 ret = x509parse_crt_der( chain, pem.buf, pem.buflen );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001652
1653 pem_free( &pem );
1654
1655 if( ret != 0 )
1656 {
1657 /*
Paul Bakker42c65812013-06-24 19:21:59 +02001658 * Quit parsing on a memory error
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001659 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001660 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001661 return( ret );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001662
1663 if( first_error == 0 )
1664 first_error = ret;
1665
Paul Bakker42c65812013-06-24 19:21:59 +02001666 total_failed++;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001667 continue;
1668 }
1669
1670 success = 1;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001671 }
1672 }
1673#endif
1674
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001675 if( success )
Paul Bakker69e095c2011-12-10 21:55:01 +00001676 return( total_failed );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001677 else if( first_error )
1678 return( first_error );
1679 else
1680 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001681}
1682
1683/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001684 * Parse one or more CRLs and add them to the chained list
1685 */
Paul Bakker23986e52011-04-24 08:57:21 +00001686int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001687{
Paul Bakker23986e52011-04-24 08:57:21 +00001688 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001689 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001690 unsigned char *p, *end;
1691 x509_crl *crl;
Paul Bakker96743fc2011-02-12 14:30:57 +00001692#if defined(POLARSSL_PEM_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00001693 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001694 pem_context pem;
1695#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001696
1697 crl = chain;
1698
1699 /*
1700 * Check for valid input
1701 */
1702 if( crl == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001703 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001704
1705 while( crl->version != 0 && crl->next != NULL )
1706 crl = crl->next;
1707
1708 /*
1709 * Add new CRL on the end of the chain if needed.
1710 */
1711 if ( crl->version != 0 && crl->next == NULL)
1712 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001713 crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001714
Paul Bakker7d06ad22009-05-02 15:53:56 +00001715 if( crl->next == NULL )
1716 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001717 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001718 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001719 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001720
Paul Bakker7d06ad22009-05-02 15:53:56 +00001721 crl = crl->next;
1722 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001723 }
1724
Paul Bakker96743fc2011-02-12 14:30:57 +00001725#if defined(POLARSSL_PEM_C)
1726 pem_init( &pem );
1727 ret = pem_read_buffer( &pem,
1728 "-----BEGIN X509 CRL-----",
1729 "-----END X509 CRL-----",
1730 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001731
Paul Bakker96743fc2011-02-12 14:30:57 +00001732 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001733 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001734 /*
1735 * Was PEM encoded
1736 */
1737 buflen -= use_len;
1738 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001739
1740 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001741 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001742 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001743 p = pem.buf;
1744 pem.buf = NULL;
1745 len = pem.buflen;
1746 pem_free( &pem );
1747 }
Paul Bakker00b28602013-06-24 13:02:41 +02001748 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker96743fc2011-02-12 14:30:57 +00001749 {
1750 pem_free( &pem );
1751 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001752 }
1753 else
1754 {
1755 /*
1756 * nope, copy the raw DER data
1757 */
Paul Bakker6e339b52013-07-03 13:37:05 +02001758 p = (unsigned char *) polarssl_malloc( len = buflen );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001759
1760 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001761 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001762
1763 memcpy( p, buf, buflen );
1764
1765 buflen = 0;
1766 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001767#else
Paul Bakker6e339b52013-07-03 13:37:05 +02001768 p = (unsigned char *) polarssl_malloc( len = buflen );
Paul Bakker96743fc2011-02-12 14:30:57 +00001769
1770 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001771 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001772
1773 memcpy( p, buf, buflen );
1774
1775 buflen = 0;
1776#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001777
1778 crl->raw.p = p;
1779 crl->raw.len = len;
1780 end = p + len;
1781
1782 /*
1783 * CertificateList ::= SEQUENCE {
1784 * tbsCertList TBSCertList,
1785 * signatureAlgorithm AlgorithmIdentifier,
1786 * signatureValue BIT STRING }
1787 */
1788 if( ( ret = asn1_get_tag( &p, end, &len,
1789 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1790 {
1791 x509_crl_free( crl );
1792 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1793 }
1794
Paul Bakker23986e52011-04-24 08:57:21 +00001795 if( len != (size_t) ( end - p ) )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001796 {
1797 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001798 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001799 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1800 }
1801
1802 /*
1803 * TBSCertList ::= SEQUENCE {
1804 */
1805 crl->tbs.p = p;
1806
1807 if( ( ret = asn1_get_tag( &p, end, &len,
1808 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1809 {
1810 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001811 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001812 }
1813
1814 end = p + len;
1815 crl->tbs.len = end - crl->tbs.p;
1816
1817 /*
1818 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1819 * -- if present, MUST be v2
1820 *
1821 * signature AlgorithmIdentifier
1822 */
Paul Bakker3329d1f2011-10-12 09:55:01 +00001823 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +02001824 ( ret = x509_get_alg( &p, end, &crl->sig_oid1, NULL ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001825 {
1826 x509_crl_free( crl );
1827 return( ret );
1828 }
1829
1830 crl->version++;
1831
1832 if( crl->version > 2 )
1833 {
1834 x509_crl_free( crl );
1835 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1836 }
1837
Paul Bakkerc70b9822013-04-07 22:00:46 +02001838 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_md,
1839 &crl->sig_pk ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001840 {
1841 x509_crl_free( crl );
1842 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1843 }
1844
1845 /*
1846 * issuer Name
1847 */
1848 crl->issuer_raw.p = p;
1849
1850 if( ( ret = asn1_get_tag( &p, end, &len,
1851 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1852 {
1853 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001854 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001855 }
1856
1857 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1858 {
1859 x509_crl_free( crl );
1860 return( ret );
1861 }
1862
1863 crl->issuer_raw.len = p - crl->issuer_raw.p;
1864
1865 /*
1866 * thisUpdate Time
1867 * nextUpdate Time OPTIONAL
1868 */
Paul Bakker91200182010-02-18 21:26:15 +00001869 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001870 {
1871 x509_crl_free( crl );
1872 return( ret );
1873 }
1874
Paul Bakker91200182010-02-18 21:26:15 +00001875 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001876 {
Paul Bakker9d781402011-05-09 16:17:09 +00001877 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001878 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker9d781402011-05-09 16:17:09 +00001879 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001880 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001881 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001882 x509_crl_free( crl );
1883 return( ret );
1884 }
1885 }
1886
1887 /*
1888 * revokedCertificates SEQUENCE OF SEQUENCE {
1889 * userCertificate CertificateSerialNumber,
1890 * revocationDate Time,
1891 * crlEntryExtensions Extensions OPTIONAL
1892 * -- if present, MUST be v2
1893 * } OPTIONAL
1894 */
1895 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1896 {
1897 x509_crl_free( crl );
1898 return( ret );
1899 }
1900
1901 /*
1902 * crlExtensions EXPLICIT Extensions OPTIONAL
1903 * -- if present, MUST be v2
1904 */
1905 if( crl->version == 2 )
1906 {
1907 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1908
1909 if( ret != 0 )
1910 {
1911 x509_crl_free( crl );
1912 return( ret );
1913 }
1914 }
1915
1916 if( p != end )
1917 {
1918 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001919 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001920 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1921 }
1922
1923 end = crl->raw.p + crl->raw.len;
1924
1925 /*
1926 * signatureAlgorithm AlgorithmIdentifier,
1927 * signatureValue BIT STRING
1928 */
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +02001929 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2, NULL ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001930 {
1931 x509_crl_free( crl );
1932 return( ret );
1933 }
1934
Paul Bakker535e97d2012-08-23 10:49:55 +00001935 if( crl->sig_oid1.len != crl->sig_oid2.len ||
1936 memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001937 {
1938 x509_crl_free( crl );
1939 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1940 }
1941
1942 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1943 {
1944 x509_crl_free( crl );
1945 return( ret );
1946 }
1947
1948 if( p != end )
1949 {
1950 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001951 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001952 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1953 }
1954
1955 if( buflen > 0 )
1956 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001957 crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001958
Paul Bakker7d06ad22009-05-02 15:53:56 +00001959 if( crl->next == NULL )
1960 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001961 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001962 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001963 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001964
Paul Bakker7d06ad22009-05-02 15:53:56 +00001965 crl = crl->next;
1966 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001967
1968 return( x509parse_crl( crl, buf, buflen ) );
1969 }
1970
1971 return( 0 );
1972}
1973
Paul Bakker335db3f2011-04-25 15:28:35 +00001974#if defined(POLARSSL_FS_IO)
Paul Bakkerd98030e2009-05-02 15:13:40 +00001975/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001976 * Load all data from a file into a given buffer.
1977 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02001978static int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001979{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001980 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001981
Paul Bakkerd98030e2009-05-02 15:13:40 +00001982 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001983 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001984
Paul Bakkerd98030e2009-05-02 15:13:40 +00001985 fseek( f, 0, SEEK_END );
1986 *n = (size_t) ftell( f );
1987 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001988
Paul Bakker6e339b52013-07-03 13:37:05 +02001989 if( ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
Paul Bakkerf6a19bd2013-05-14 13:26:51 +02001990 {
1991 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +00001992 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerf6a19bd2013-05-14 13:26:51 +02001993 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001994
Paul Bakkerd98030e2009-05-02 15:13:40 +00001995 if( fread( *buf, 1, *n, f ) != *n )
1996 {
1997 fclose( f );
Paul Bakker6e339b52013-07-03 13:37:05 +02001998 polarssl_free( *buf );
Paul Bakker69e095c2011-12-10 21:55:01 +00001999 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002000 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00002001
Paul Bakkerd98030e2009-05-02 15:13:40 +00002002 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00002003
Paul Bakkerd98030e2009-05-02 15:13:40 +00002004 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00002005
Paul Bakkerd98030e2009-05-02 15:13:40 +00002006 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00002007}
2008
2009/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002010 * Load one or more certificates and add them to the chained list
2011 */
Paul Bakker69e095c2011-12-10 21:55:01 +00002012int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00002013{
2014 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002015 size_t n;
2016 unsigned char *buf;
2017
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02002018 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00002019 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002020
Paul Bakker69e095c2011-12-10 21:55:01 +00002021 ret = x509parse_crt( chain, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002022
2023 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02002024 polarssl_free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00002025
2026 return( ret );
2027}
2028
Paul Bakker8d914582012-06-04 12:46:42 +00002029int x509parse_crtpath( x509_cert *chain, const char *path )
2030{
2031 int ret = 0;
2032#if defined(_WIN32)
Paul Bakker3338b792012-10-01 21:13:10 +00002033 int w_ret;
2034 WCHAR szDir[MAX_PATH];
2035 char filename[MAX_PATH];
2036 char *p;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002037 int len = strlen( path );
Paul Bakker3338b792012-10-01 21:13:10 +00002038
Paul Bakker97872ac2012-11-02 12:53:26 +00002039 WIN32_FIND_DATAW file_data;
Paul Bakker8d914582012-06-04 12:46:42 +00002040 HANDLE hFind;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002041
2042 if( len > MAX_PATH - 3 )
2043 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker8d914582012-06-04 12:46:42 +00002044
Paul Bakker3338b792012-10-01 21:13:10 +00002045 memset( szDir, 0, sizeof(szDir) );
2046 memset( filename, 0, MAX_PATH );
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002047 memcpy( filename, path, len );
2048 filename[len++] = '\\';
2049 p = filename + len;
2050 filename[len++] = '*';
Paul Bakker3338b792012-10-01 21:13:10 +00002051
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002052 w_ret = MultiByteToWideChar( CP_ACP, 0, path, len, szDir, MAX_PATH - 3 );
Paul Bakker8d914582012-06-04 12:46:42 +00002053
Paul Bakker97872ac2012-11-02 12:53:26 +00002054 hFind = FindFirstFileW( szDir, &file_data );
Paul Bakker8d914582012-06-04 12:46:42 +00002055 if (hFind == INVALID_HANDLE_VALUE)
2056 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
2057
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002058 len = MAX_PATH - len;
Paul Bakker8d914582012-06-04 12:46:42 +00002059 do
2060 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002061 memset( p, 0, len );
Paul Bakker3338b792012-10-01 21:13:10 +00002062
Paul Bakkere4791f32012-06-04 21:29:15 +00002063 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
Paul Bakker8d914582012-06-04 12:46:42 +00002064 continue;
2065
Paul Bakker3338b792012-10-01 21:13:10 +00002066 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
2067 lstrlenW(file_data.cFileName),
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002068 p, len - 1,
2069 NULL, NULL );
Paul Bakker8d914582012-06-04 12:46:42 +00002070
Paul Bakker3338b792012-10-01 21:13:10 +00002071 w_ret = x509parse_crtfile( chain, filename );
2072 if( w_ret < 0 )
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002073 ret++;
2074 else
2075 ret += w_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00002076 }
Paul Bakker97872ac2012-11-02 12:53:26 +00002077 while( FindNextFileW( hFind, &file_data ) != 0 );
Paul Bakker8d914582012-06-04 12:46:42 +00002078
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002079 if (GetLastError() != ERROR_NO_MORE_FILES)
2080 ret = POLARSSL_ERR_X509_FILE_IO_ERROR;
Paul Bakker8d914582012-06-04 12:46:42 +00002081
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002082cleanup:
Paul Bakker8d914582012-06-04 12:46:42 +00002083 FindClose( hFind );
2084#else
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002085 int t_ret, i;
2086 struct stat sb;
2087 struct dirent entry, *result = NULL;
Paul Bakker8d914582012-06-04 12:46:42 +00002088 char entry_name[255];
2089 DIR *dir = opendir( path );
2090
2091 if( dir == NULL)
2092 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
2093
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002094 while( ( t_ret = readdir_r( dir, &entry, &result ) ) == 0 )
Paul Bakker8d914582012-06-04 12:46:42 +00002095 {
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002096 if( result == NULL )
2097 break;
2098
2099 snprintf( entry_name, sizeof(entry_name), "%s/%s", path, entry.d_name );
2100
2101 i = stat( entry_name, &sb );
2102
2103 if( i == -1 )
2104 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
2105
2106 if( !S_ISREG( sb.st_mode ) )
Paul Bakker8d914582012-06-04 12:46:42 +00002107 continue;
2108
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002109 // Ignore parse errors
2110 //
Paul Bakker8d914582012-06-04 12:46:42 +00002111 t_ret = x509parse_crtfile( chain, entry_name );
2112 if( t_ret < 0 )
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002113 ret++;
2114 else
2115 ret += t_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00002116 }
2117 closedir( dir );
2118#endif
2119
2120 return( ret );
2121}
2122
Paul Bakkerd98030e2009-05-02 15:13:40 +00002123/*
2124 * Load one or more CRLs and add them to the chained list
2125 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002126int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002127{
2128 int ret;
2129 size_t n;
2130 unsigned char *buf;
2131
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02002132 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00002133 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002134
Paul Bakker27fdf462011-06-09 13:55:13 +00002135 ret = x509parse_crl( chain, buf, n );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002136
2137 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02002138 polarssl_free( buf );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002139
2140 return( ret );
2141}
2142
Paul Bakker5121ce52009-01-03 21:22:43 +00002143/*
Paul Bakker335db3f2011-04-25 15:28:35 +00002144 * Load and parse a private RSA key
2145 */
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002146int x509parse_keyfile_rsa( rsa_context *rsa, const char *path, const char *pwd )
Paul Bakker335db3f2011-04-25 15:28:35 +00002147{
2148 int ret;
2149 size_t n;
2150 unsigned char *buf;
2151
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02002152 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00002153 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002154
2155 if( pwd == NULL )
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002156 ret = x509parse_key_rsa( rsa, buf, n, NULL, 0 );
Paul Bakker335db3f2011-04-25 15:28:35 +00002157 else
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002158 ret = x509parse_key_rsa( rsa, buf, n,
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02002159 (const unsigned char *) pwd, strlen( pwd ) );
Paul Bakker335db3f2011-04-25 15:28:35 +00002160
2161 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02002162 polarssl_free( buf );
Paul Bakker335db3f2011-04-25 15:28:35 +00002163
2164 return( ret );
2165}
2166
2167/*
2168 * Load and parse a public RSA key
2169 */
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002170int x509parse_public_keyfile_rsa( rsa_context *rsa, const char *path )
Paul Bakker335db3f2011-04-25 15:28:35 +00002171{
2172 int ret;
2173 size_t n;
2174 unsigned char *buf;
2175
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02002176 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00002177 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002178
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002179 ret = x509parse_public_key_rsa( rsa, buf, n );
Paul Bakker335db3f2011-04-25 15:28:35 +00002180
2181 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02002182 polarssl_free( buf );
Paul Bakker335db3f2011-04-25 15:28:35 +00002183
2184 return( ret );
2185}
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002186
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002187/*
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002188 * Load and parse a private key
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002189 */
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002190int x509parse_keyfile( pk_context *ctx,
2191 const char *path, const char *pwd )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002192{
2193 int ret;
2194 size_t n;
2195 unsigned char *buf;
2196
2197 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2198 return( ret );
2199
2200 if( pwd == NULL )
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002201 ret = x509parse_key( ctx, buf, n, NULL, 0 );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002202 else
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002203 ret = x509parse_key( ctx, buf, n,
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002204 (const unsigned char *) pwd, strlen( pwd ) );
2205
2206 memset( buf, 0, n + 1 );
2207 free( buf );
2208
2209 return( ret );
2210}
2211
2212/*
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002213 * Load and parse a public key
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002214 */
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002215int x509parse_public_keyfile( pk_context *ctx, const char *path )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002216{
2217 int ret;
2218 size_t n;
2219 unsigned char *buf;
2220
2221 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2222 return( ret );
2223
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002224 ret = x509parse_public_key( ctx, buf, n );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002225
2226 memset( buf, 0, n + 1 );
2227 free( buf );
2228
2229 return( ret );
2230}
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002231
Paul Bakker335db3f2011-04-25 15:28:35 +00002232#endif /* POLARSSL_FS_IO */
2233
2234/*
Paul Bakkere2f50402013-06-24 19:00:59 +02002235 * Parse a PKCS#1 encoded private RSA key
Paul Bakker5121ce52009-01-03 21:22:43 +00002236 */
Paul Bakkere2f50402013-06-24 19:00:59 +02002237static int x509parse_key_pkcs1_der( rsa_context *rsa,
2238 const unsigned char *key,
2239 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +00002240{
Paul Bakker23986e52011-04-24 08:57:21 +00002241 int ret;
2242 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00002243 unsigned char *p, *end;
Paul Bakkered56b222011-07-13 11:26:43 +00002244
Paul Bakker96743fc2011-02-12 14:30:57 +00002245 p = (unsigned char *) key;
Paul Bakker96743fc2011-02-12 14:30:57 +00002246 end = p + keylen;
2247
Paul Bakker5121ce52009-01-03 21:22:43 +00002248 /*
Paul Bakkere2f50402013-06-24 19:00:59 +02002249 * This function parses the RSAPrivateKey (PKCS#1)
Paul Bakkered56b222011-07-13 11:26:43 +00002250 *
Paul Bakker5121ce52009-01-03 21:22:43 +00002251 * RSAPrivateKey ::= SEQUENCE {
2252 * version Version,
2253 * modulus INTEGER, -- n
2254 * publicExponent INTEGER, -- e
2255 * privateExponent INTEGER, -- d
2256 * prime1 INTEGER, -- p
2257 * prime2 INTEGER, -- q
2258 * exponent1 INTEGER, -- d mod (p-1)
2259 * exponent2 INTEGER, -- d mod (q-1)
2260 * coefficient INTEGER, -- (inverse of q) mod p
2261 * otherPrimeInfos OtherPrimeInfos OPTIONAL
2262 * }
2263 */
2264 if( ( ret = asn1_get_tag( &p, end, &len,
2265 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2266 {
Paul Bakker9d781402011-05-09 16:17:09 +00002267 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002268 }
2269
2270 end = p + len;
2271
2272 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2273 {
Paul Bakker9d781402011-05-09 16:17:09 +00002274 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002275 }
2276
2277 if( rsa->ver != 0 )
2278 {
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002279 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00002280 }
2281
2282 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
2283 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
2284 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
2285 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
2286 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
2287 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
2288 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
2289 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
2290 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002291 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002292 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002293 }
2294
2295 rsa->len = mpi_size( &rsa->N );
2296
2297 if( p != end )
2298 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002299 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002300 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00002301 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002302 }
2303
2304 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2305 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002306 rsa_free( rsa );
2307 return( ret );
2308 }
2309
Paul Bakkere2f50402013-06-24 19:00:59 +02002310 return( 0 );
2311}
2312
2313/*
2314 * Parse an unencrypted PKCS#8 encoded private RSA key
2315 */
2316static int x509parse_key_pkcs8_unencrypted_der(
2317 rsa_context *rsa,
2318 const unsigned char *key,
2319 size_t keylen )
2320{
2321 int ret;
2322 size_t len;
2323 unsigned char *p, *end;
2324 x509_buf pk_alg_oid;
2325 pk_type_t pk_alg = POLARSSL_PK_NONE;
2326
2327 p = (unsigned char *) key;
2328 end = p + keylen;
2329
2330 /*
2331 * This function parses the PrivatKeyInfo object (PKCS#8)
2332 *
2333 * PrivateKeyInfo ::= SEQUENCE {
2334 * version Version,
2335 * algorithm AlgorithmIdentifier,
2336 * PrivateKey BIT STRING
2337 * }
2338 *
2339 * AlgorithmIdentifier ::= SEQUENCE {
2340 * algorithm OBJECT IDENTIFIER,
2341 * parameters ANY DEFINED BY algorithm OPTIONAL
2342 * }
2343 *
2344 * The PrivateKey BIT STRING is a PKCS#1 RSAPrivateKey
2345 */
2346 if( ( ret = asn1_get_tag( &p, end, &len,
2347 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2348 {
2349 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2350 }
2351
2352 end = p + len;
2353
2354 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2355 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2356
2357 if( rsa->ver != 0 )
2358 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2359
Paul Bakkerf8d018a2013-06-29 12:16:17 +02002360 if( ( ret = asn1_get_alg_null( &p, end, &pk_alg_oid ) ) != 0 )
Paul Bakkere2f50402013-06-24 19:00:59 +02002361 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2362
2363 /*
2364 * only RSA keys handled at this time
2365 */
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002366 if( oid_get_pk_alg( &pk_alg_oid, &pk_alg ) != 0 )
Manuel Pégourié-Gonnard80300ad2013-07-04 11:57:13 +02002367 {
Paul Bakkere2f50402013-06-24 19:00:59 +02002368 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
Manuel Pégourié-Gonnard80300ad2013-07-04 11:57:13 +02002369 }
Paul Bakkere2f50402013-06-24 19:00:59 +02002370
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002371 if (pk_alg != POLARSSL_PK_RSA )
2372 return( POLARSSL_ERR_X509_CERT_INVALID_ALG );
2373
Paul Bakkere2f50402013-06-24 19:00:59 +02002374 /*
2375 * Get the OCTET STRING and parse the PKCS#1 format inside
2376 */
2377 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2378 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2379
2380 if( ( end - p ) < 1 )
2381 {
2382 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
2383 POLARSSL_ERR_ASN1_OUT_OF_DATA );
2384 }
2385
2386 end = p + len;
2387
2388 if( ( ret = x509parse_key_pkcs1_der( rsa, p, end - p ) ) != 0 )
2389 return( ret );
2390
2391 return( 0 );
2392}
2393
2394/*
Manuel Pégourié-Gonnarda5d99742013-07-04 11:08:31 +02002395 * Decrypt the content of a PKCS#8 EncryptedPrivateKeyInfo
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002396 */
Manuel Pégourié-Gonnarda5d99742013-07-04 11:08:31 +02002397static int x509parse_pkcs8_decrypt( unsigned char *buf, size_t buflen,
2398 size_t *used_len,
2399 const unsigned char *key, size_t keylen,
2400 const unsigned char *pwd, size_t pwdlen )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002401{
2402 int ret;
2403 size_t len;
Paul Bakkerf8d018a2013-06-29 12:16:17 +02002404 unsigned char *p, *end;
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002405 x509_buf pbe_alg_oid, pbe_params;
Paul Bakker7749a222013-06-28 17:28:20 +02002406#if defined(POLARSSL_PKCS12_C)
2407 cipher_type_t cipher_alg;
2408 md_type_t md_alg;
2409#endif
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002410
Manuel Pégourié-Gonnarda5d99742013-07-04 11:08:31 +02002411 memset(buf, 0, buflen);
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002412
2413 p = (unsigned char *) key;
2414 end = p + keylen;
2415
Paul Bakker28144de2013-06-24 19:28:55 +02002416 if( pwdlen == 0 )
2417 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
2418
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002419 /*
2420 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
2421 *
2422 * EncryptedPrivateKeyInfo ::= SEQUENCE {
2423 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
2424 * encryptedData EncryptedData
2425 * }
2426 *
2427 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
2428 *
2429 * EncryptedData ::= OCTET STRING
2430 *
2431 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
2432 */
2433 if( ( ret = asn1_get_tag( &p, end, &len,
2434 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2435 {
2436 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2437 }
2438
2439 end = p + len;
2440
Paul Bakkerf8d018a2013-06-29 12:16:17 +02002441 if( ( ret = asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002442 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002443
2444 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2445 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2446
Manuel Pégourié-Gonnarda5d99742013-07-04 11:08:31 +02002447 if( len > buflen )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002448 return( POLARSSL_ERR_X509_INVALID_INPUT );
2449
2450 /*
2451 * Decrypt EncryptedData with appropriate PDE
2452 */
Paul Bakker38b50d72013-06-24 19:33:27 +02002453#if defined(POLARSSL_PKCS12_C)
Paul Bakker7749a222013-06-28 17:28:20 +02002454 if( oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002455 {
Paul Bakker38b50d72013-06-24 19:33:27 +02002456 if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
Paul Bakker7749a222013-06-28 17:28:20 +02002457 cipher_alg, md_alg,
Paul Bakker38b50d72013-06-24 19:33:27 +02002458 pwd, pwdlen, p, len, buf ) ) != 0 )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002459 {
Paul Bakker38b50d72013-06-24 19:33:27 +02002460 if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH )
2461 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2462
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002463 return( ret );
2464 }
2465 }
2466 else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) )
2467 {
2468 if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params,
2469 PKCS12_PBE_DECRYPT,
2470 pwd, pwdlen,
2471 p, len, buf ) ) != 0 )
2472 {
2473 return( ret );
2474 }
Paul Bakker38b50d72013-06-24 19:33:27 +02002475
2476 // Best guess for password mismatch when using RC4. If first tag is
2477 // not ASN1_CONSTRUCTED | ASN1_SEQUENCE
2478 //
2479 if( *buf != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
2480 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002481 }
Paul Bakker38b50d72013-06-24 19:33:27 +02002482 else
2483#endif /* POLARSSL_PKCS12_C */
Paul Bakker28144de2013-06-24 19:28:55 +02002484#if defined(POLARSSL_PKCS5_C)
Paul Bakker38b50d72013-06-24 19:33:27 +02002485 if( OID_CMP( OID_PKCS5_PBES2, &pbe_alg_oid ) )
Paul Bakker28144de2013-06-24 19:28:55 +02002486 {
2487 if( ( ret = pkcs5_pbes2( &pbe_params, PKCS5_DECRYPT, pwd, pwdlen,
2488 p, len, buf ) ) != 0 )
2489 {
2490 if( ret == POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH )
2491 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2492
2493 return( ret );
2494 }
2495 }
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002496 else
Paul Bakker38b50d72013-06-24 19:33:27 +02002497#endif /* POLARSSL_PKCS5_C */
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002498 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
2499
Manuel Pégourié-Gonnarda5d99742013-07-04 11:08:31 +02002500 *used_len = len;
2501 return( 0 );
2502}
2503
2504/*
2505 * Parse an encrypted PKCS#8 encoded private RSA key
2506 */
2507static int x509parse_key_pkcs8_encrypted_der(
2508 rsa_context *rsa,
2509 const unsigned char *key, size_t keylen,
2510 const unsigned char *pwd, size_t pwdlen )
2511{
2512 int ret;
2513 unsigned char buf[2048];
2514 size_t len = 0;
2515
2516 if( ( ret = x509parse_pkcs8_decrypt( buf, sizeof( buf ), &len,
2517 key, keylen, pwd, pwdlen ) ) != 0 )
2518 {
2519 return( ret );
2520 }
2521
2522 return( x509parse_key_pkcs8_unencrypted_der( rsa, buf, len ) );
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002523}
2524
2525/*
Paul Bakkere2f50402013-06-24 19:00:59 +02002526 * Parse a private RSA key
2527 */
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002528int x509parse_key_rsa( rsa_context *rsa,
2529 const unsigned char *key, size_t keylen,
2530 const unsigned char *pwd, size_t pwdlen )
Paul Bakkere2f50402013-06-24 19:00:59 +02002531{
2532 int ret;
2533
Paul Bakker96743fc2011-02-12 14:30:57 +00002534#if defined(POLARSSL_PEM_C)
Paul Bakkere2f50402013-06-24 19:00:59 +02002535 size_t len;
2536 pem_context pem;
2537
2538 pem_init( &pem );
2539 ret = pem_read_buffer( &pem,
2540 "-----BEGIN RSA PRIVATE KEY-----",
2541 "-----END RSA PRIVATE KEY-----",
2542 key, pwd, pwdlen, &len );
2543 if( ret == 0 )
2544 {
2545 if( ( ret = x509parse_key_pkcs1_der( rsa, pem.buf, pem.buflen ) ) != 0 )
2546 {
2547 rsa_free( rsa );
2548 }
2549
2550 pem_free( &pem );
2551 return( ret );
2552 }
Paul Bakkera4232a72013-06-24 19:32:25 +02002553 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
2554 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2555 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
2556 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
Paul Bakkere2f50402013-06-24 19:00:59 +02002557 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkere2f50402013-06-24 19:00:59 +02002558 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002559
2560 ret = pem_read_buffer( &pem,
2561 "-----BEGIN PRIVATE KEY-----",
2562 "-----END PRIVATE KEY-----",
2563 key, NULL, 0, &len );
2564 if( ret == 0 )
2565 {
2566 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa,
2567 pem.buf, pem.buflen ) ) != 0 )
2568 {
2569 rsa_free( rsa );
2570 }
2571
2572 pem_free( &pem );
2573 return( ret );
2574 }
2575 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkere2f50402013-06-24 19:00:59 +02002576 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002577
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002578 ret = pem_read_buffer( &pem,
2579 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
2580 "-----END ENCRYPTED PRIVATE KEY-----",
2581 key, NULL, 0, &len );
2582 if( ret == 0 )
2583 {
2584 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa,
2585 pem.buf, pem.buflen,
2586 pwd, pwdlen ) ) != 0 )
2587 {
2588 rsa_free( rsa );
2589 }
2590
2591 pem_free( &pem );
2592 return( ret );
2593 }
2594 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002595 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002596#else
2597 ((void) pwd);
2598 ((void) pwdlen);
2599#endif /* POLARSSL_PEM_C */
2600
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002601 /*
2602 * At this point we only know it's not a PEM formatted key. Could be any
2603 * of the known DER encoded private key formats
2604 *
2605 * We try the different DER format parsers to see if one passes without
2606 * error
2607 */
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002608 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa, key, keylen,
2609 pwd, pwdlen ) ) == 0 )
Paul Bakkere2f50402013-06-24 19:00:59 +02002610 {
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002611 return( 0 );
Paul Bakkere2f50402013-06-24 19:00:59 +02002612 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002613
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002614 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002615
2616 if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH )
2617 {
2618 return( ret );
2619 }
2620
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002621 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa, key, keylen ) ) == 0 )
2622 return( 0 );
2623
2624 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002625
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002626 if( ( ret = x509parse_key_pkcs1_der( rsa, key, keylen ) ) == 0 )
2627 return( 0 );
2628
2629 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002630
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002631 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00002632}
2633
2634/*
Paul Bakker53019ae2011-03-25 13:58:48 +00002635 * Parse a public RSA key
2636 */
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002637int x509parse_public_key_rsa( rsa_context *rsa,
2638 const unsigned char *key, size_t keylen )
Paul Bakker53019ae2011-03-25 13:58:48 +00002639{
Manuel Pégourié-Gonnard244569f2013-07-10 09:46:30 +02002640 pk_context pk_ctx;
Paul Bakker53019ae2011-03-25 13:58:48 +00002641
Manuel Pégourié-Gonnard244569f2013-07-10 09:46:30 +02002642 pk_init( &pk_ctx );
2643 pk_wrap_rsa( &pk_ctx, rsa );
Paul Bakker53019ae2011-03-25 13:58:48 +00002644
Manuel Pégourié-Gonnard244569f2013-07-10 09:46:30 +02002645 return( x509parse_public_key( &pk_ctx, key, keylen ) );
Paul Bakker53019ae2011-03-25 13:58:48 +00002646}
2647
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002648#if defined(POLARSSL_ECP_C)
2649/*
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002650 * Parse a SEC1 encoded private EC key
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002651 */
2652static int x509parse_key_sec1_der( ecp_keypair *eck,
2653 const unsigned char *key,
2654 size_t keylen )
2655{
2656 int ret;
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002657 int version;
2658 size_t len;
2659 ecp_group_id grp_id;
2660 unsigned char *p = (unsigned char *) key;
2661 unsigned char *end = p + keylen;
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002662
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002663 /*
2664 * RFC 5915, orf SEC1 Appendix C.4
2665 *
2666 * ECPrivateKey ::= SEQUENCE {
2667 * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
2668 * privateKey OCTET STRING,
2669 * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
2670 * publicKey [1] BIT STRING OPTIONAL
2671 * }
2672 */
2673 if( ( ret = asn1_get_tag( &p, end, &len,
2674 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2675 {
2676 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2677 }
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002678
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002679 end = p + len;
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002680
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002681 if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 )
2682 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002683
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002684 if( version != 1 )
2685 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION );
2686
2687 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2688 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2689
2690 if( ( ret = mpi_read_binary( &eck->d, p, len ) ) != 0 )
2691 {
2692 ecp_keypair_free( eck );
2693 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2694 }
2695
2696 p += len;
2697
2698 /*
2699 * Is 'parameters' present?
2700 */
2701 if( ( ret = asn1_get_tag( &p, end, &len,
2702 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) == 0 )
2703 {
2704 if( ( ret = x509_get_ecparams( &p, p + len, &grp_id) ) != 0 )
2705 return( ret );
2706
Manuel Pégourié-Gonnardd4ec21d2013-07-04 12:04:57 +02002707 /*
2708 * If we're wrapped in a bigger structure (eg PKCS#8), grp may have been
2709 * defined externally. In this case, make sure both definitions match.
2710 */
2711 if( eck->grp.id != 0 )
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002712 {
Manuel Pégourié-Gonnardd4ec21d2013-07-04 12:04:57 +02002713 if( eck->grp.id != grp_id )
2714 {
2715 ecp_keypair_free( eck );
2716 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2717 }
2718 }
2719 else
2720 {
2721 if( ( ret = ecp_use_known_dp( &eck->grp, grp_id ) ) != 0 )
2722 {
2723 ecp_keypair_free( eck );
2724 return( ret );
2725 }
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002726 }
2727 }
2728 else if ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
2729 {
2730 ecp_keypair_free( eck );
2731 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2732 }
2733
2734 /*
2735 * Is 'publickey' present?
2736 */
2737 if( ( ret = asn1_get_tag( &p, end, &len,
2738 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 )
2739 {
2740 if( ( ret = x509_get_subpubkey_ec( &p, p + len, &eck->grp, &eck->Q ) )
2741 != 0 )
2742 {
2743 ecp_keypair_free( eck );
2744 return( ret );
2745 }
2746
2747 if( ( ret = ecp_check_pubkey( &eck->grp, &eck->Q ) ) != 0 )
2748 {
2749 ecp_keypair_free( eck );
2750 return( ret );
2751 }
2752 }
2753 else if ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
2754 {
2755 ecp_keypair_free( eck );
2756 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2757 }
2758
Manuel Pégourié-Gonnardde44a4a2013-07-09 16:05:52 +02002759 if( ( ret = ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 )
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002760 {
2761 ecp_keypair_free( eck );
2762 return( ret );
2763 }
2764
2765 return 0;
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002766}
2767
2768/*
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002769 * Parse an unencrypted PKCS#8 encoded private EC key
2770 */
2771static int x509parse_key_pkcs8_unencrypted_der_ec(
2772 ecp_keypair *eck,
2773 const unsigned char* key,
2774 size_t keylen )
2775{
2776 int ret, version;
2777 size_t len;
Manuel Pégourié-Gonnard0a64e8f2013-07-08 18:26:18 +02002778 x509_buf alg_params;
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002779 ecp_group_id grp_id;
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002780 unsigned char *p = (unsigned char *) key;
2781 unsigned char *end = p + keylen;
2782 pk_type_t pk_alg = POLARSSL_PK_NONE;
2783
2784 /*
2785 * This function parses the PrivatKeyInfo object (PKCS#8 v1.2 = RFC 5208)
2786 *
2787 * PrivateKeyInfo ::= SEQUENCE {
2788 * version Version,
2789 * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
2790 * privateKey PrivateKey,
2791 * attributes [0] IMPLICIT Attributes OPTIONAL }
2792 *
2793 * Version ::= INTEGER
2794 * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
2795 * PrivateKey ::= OCTET STRING
2796 *
2797 * The PrivateKey OCTET STRING is a SEC1 ECPrivateKey
2798 */
2799
2800 if( ( ret = asn1_get_tag( &p, end, &len,
2801 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2802 {
2803 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2804 }
2805
2806 end = p + len;
2807
2808 if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 )
2809 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2810
2811 if( version != 0 )
2812 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2813
Manuel Pégourié-Gonnard0a64e8f2013-07-08 18:26:18 +02002814 if( ( ret = x509_get_algid( &p, end, &pk_alg, &alg_params ) ) != 0 )
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002815 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2816
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002817 if( pk_alg != POLARSSL_PK_ECKEY && pk_alg != POLARSSL_PK_ECKEY_DH )
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002818 return( POLARSSL_ERR_X509_CERT_INVALID_ALG );
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002819
2820 if( pk_alg == POLARSSL_PK_ECKEY_DH )
2821 eck->alg = POLARSSL_ECP_KEY_ALG_ECDH;
2822
Manuel Pégourié-Gonnard0a64e8f2013-07-08 18:26:18 +02002823 if( ( ret = x509_ecparams_get_grp_id( &alg_params, &grp_id ) ) != 0 )
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002824 {
2825 ecp_keypair_free( eck );
2826 return( ret );
2827 }
2828
2829 if( ( ret = ecp_use_known_dp( &eck->grp, grp_id ) ) != 0 )
2830 {
2831 ecp_keypair_free( eck );
2832 return( ret );
2833 }
2834
2835 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2836 {
2837 ecp_keypair_free( eck );
2838 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2839 }
2840
2841 if( ( ret = x509parse_key_sec1_der( eck, p, len ) ) != 0 )
2842 {
2843 ecp_keypair_free( eck );
2844 return( ret );
2845 }
2846
Manuel Pégourié-Gonnardde44a4a2013-07-09 16:05:52 +02002847 if( ( ret = ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 )
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002848 {
2849 ecp_keypair_free( eck );
2850 return( ret );
2851 }
2852
2853 return 0;
2854}
2855
2856/*
2857 * Parse an encrypted PKCS#8 encoded private EC key
2858 */
2859static int x509parse_key_pkcs8_encrypted_der_ec(
2860 ecp_keypair *eck,
Manuel Pégourié-Gonnard9c1cf452013-07-04 11:20:24 +02002861 const unsigned char *key, size_t keylen,
2862 const unsigned char *pwd, size_t pwdlen )
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002863{
2864 int ret;
Manuel Pégourié-Gonnard9c1cf452013-07-04 11:20:24 +02002865 unsigned char buf[2048];
2866 size_t len = 0;
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002867
Manuel Pégourié-Gonnard9c1cf452013-07-04 11:20:24 +02002868 if( ( ret = x509parse_pkcs8_decrypt( buf, sizeof( buf ), &len,
2869 key, keylen, pwd, pwdlen ) ) != 0 )
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002870 {
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002871 return( ret );
2872 }
2873
Manuel Pégourié-Gonnard9c1cf452013-07-04 11:20:24 +02002874 return( x509parse_key_pkcs8_unencrypted_der_ec( eck, buf, len ) );
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002875}
2876
2877/*
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002878 * Parse a private EC key
2879 */
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002880static int x509parse_key_ec( ecp_keypair *eck,
2881 const unsigned char *key, size_t keylen,
2882 const unsigned char *pwd, size_t pwdlen )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002883{
2884 int ret;
2885
2886#if defined(POLARSSL_PEM_C)
2887 size_t len;
2888 pem_context pem;
2889
2890 pem_init( &pem );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002891 ret = pem_read_buffer( &pem,
2892 "-----BEGIN EC PRIVATE KEY-----",
2893 "-----END EC PRIVATE KEY-----",
2894 key, pwd, pwdlen, &len );
2895 if( ret == 0 )
2896 {
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002897 if( ( ret = x509parse_key_sec1_der( eck, pem.buf, pem.buflen ) ) != 0 )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002898 {
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002899 ecp_keypair_free( eck );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002900 }
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002901
2902 pem_free( &pem );
2903 return( ret );
2904 }
2905 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
2906 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2907 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
2908 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
2909 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2910 return( ret );
2911
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002912 ret = pem_read_buffer( &pem,
2913 "-----BEGIN PRIVATE KEY-----",
2914 "-----END PRIVATE KEY-----",
2915 key, NULL, 0, &len );
2916 if( ret == 0 )
2917 {
2918 if( ( ret = x509parse_key_pkcs8_unencrypted_der_ec( eck,
2919 pem.buf, pem.buflen ) ) != 0 )
2920 {
2921 ecp_keypair_free( eck );
2922 }
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002923
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002924 pem_free( &pem );
2925 return( ret );
2926 }
2927 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2928 return( ret );
2929
2930 ret = pem_read_buffer( &pem,
2931 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
2932 "-----END ENCRYPTED PRIVATE KEY-----",
2933 key, NULL, 0, &len );
2934 if( ret == 0 )
2935 {
2936 if( ( ret = x509parse_key_pkcs8_encrypted_der_ec( eck,
2937 pem.buf, pem.buflen,
2938 pwd, pwdlen ) ) != 0 )
2939 {
2940 ecp_keypair_free( eck );
2941 }
2942
2943 pem_free( &pem );
2944 return( ret );
2945 }
2946 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2947 return( ret );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002948#else
2949 ((void) pwd);
2950 ((void) pwdlen);
2951#endif /* POLARSSL_PEM_C */
2952
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002953 /*
2954 * At this point we only know it's not a PEM formatted key. Could be any
2955 * of the known DER encoded private key formats
2956 *
2957 * We try the different DER format parsers to see if one passes without
2958 * error
2959 */
2960 if( ( ret = x509parse_key_pkcs8_encrypted_der_ec( eck, key, keylen,
2961 pwd, pwdlen ) ) == 0 )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002962 {
2963 return( 0 );
2964 }
2965
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002966 ecp_keypair_free( eck );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002967
2968 if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH )
2969 {
2970 return( ret );
2971 }
2972
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002973 if( ( ret = x509parse_key_pkcs8_unencrypted_der_ec( eck,
2974 key, keylen ) ) == 0 )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002975 return( 0 );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002976
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002977 ecp_keypair_free( eck );
2978
2979 if( ( ret = x509parse_key_sec1_der( eck, key, keylen ) ) == 0 )
2980 return( 0 );
2981
2982 ecp_keypair_free( eck );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002983
2984 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
2985}
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002986#endif /* defined(POLARSSL_ECP_C) */
2987
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002988/*
2989 * Parse a private key
2990 */
2991int x509parse_key( pk_context *ctx,
2992 const unsigned char *key, size_t keylen,
2993 const unsigned char *pwd, size_t pwdlen )
2994{
2995 int ret;
2996
2997 if ( ( ret = pk_set_type( ctx, POLARSSL_PK_RSA ) ) != 0 )
2998 return( ret );
2999
3000 if( ( ret = x509parse_key_rsa( ctx->data, key, keylen, pwd, pwdlen ) )
3001 == 0 )
3002 {
3003 return( 0 );
3004 }
3005
Manuel Pégourié-Gonnard374e4b82013-07-09 10:21:34 +02003006 pk_free( ctx );
3007
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02003008 if ( ( ret = pk_set_type( ctx, POLARSSL_PK_ECKEY ) ) != 0 )
3009 return( ret );
3010
3011 if( ( ret = x509parse_key_ec( ctx->data, key, keylen, pwd, pwdlen ) ) == 0 )
3012 {
3013 return( 0 );
3014 }
3015
Manuel Pégourié-Gonnard374e4b82013-07-09 10:21:34 +02003016 pk_free( ctx );
3017
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02003018 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
3019}
3020
3021/*
3022 * Parse a public key
3023 */
3024int x509parse_public_key( pk_context *ctx,
3025 const unsigned char *key, size_t keylen )
3026{
3027 int ret;
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +02003028 unsigned char *p;
3029#if defined(POLARSSL_PEM_C)
3030 size_t len;
3031 pem_context pem;
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02003032
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +02003033 pem_init( &pem );
3034 ret = pem_read_buffer( &pem,
3035 "-----BEGIN PUBLIC KEY-----",
3036 "-----END PUBLIC KEY-----",
3037 key, NULL, 0, &len );
3038
3039 if( ret == 0 )
3040 {
3041 /*
3042 * Was PEM encoded
3043 */
3044 key = pem.buf;
3045 keylen = pem.buflen;
3046 }
3047 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
3048 {
3049 pem_free( &pem );
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02003050 return( ret );
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +02003051 }
3052#endif
3053 p = (unsigned char *) key;
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02003054
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +02003055 ret = x509_get_pubkey( &p, p + keylen, ctx );
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02003056
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +02003057#if defined(POLARSSL_PEM_C)
3058 pem_free( &pem );
3059#endif
Manuel Pégourié-Gonnard374e4b82013-07-09 10:21:34 +02003060
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +02003061 return( ret );
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02003062}
3063
Paul Bakkereaa89f82011-04-04 21:36:15 +00003064#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00003065/*
Paul Bakker1b57b062011-01-06 15:48:19 +00003066 * Parse DHM parameters
3067 */
Paul Bakker23986e52011-04-24 08:57:21 +00003068int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
Paul Bakker1b57b062011-01-06 15:48:19 +00003069{
Paul Bakker23986e52011-04-24 08:57:21 +00003070 int ret;
3071 size_t len;
Paul Bakker1b57b062011-01-06 15:48:19 +00003072 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00003073#if defined(POLARSSL_PEM_C)
3074 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00003075
Paul Bakker96743fc2011-02-12 14:30:57 +00003076 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00003077
Paul Bakker96743fc2011-02-12 14:30:57 +00003078 ret = pem_read_buffer( &pem,
3079 "-----BEGIN DH PARAMETERS-----",
3080 "-----END DH PARAMETERS-----",
3081 dhmin, NULL, 0, &dhminlen );
3082
3083 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003084 {
Paul Bakker96743fc2011-02-12 14:30:57 +00003085 /*
3086 * Was PEM encoded
3087 */
3088 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00003089 }
Paul Bakker00b28602013-06-24 13:02:41 +02003090 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00003091 {
Paul Bakker96743fc2011-02-12 14:30:57 +00003092 pem_free( &pem );
3093 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00003094 }
3095
Paul Bakker96743fc2011-02-12 14:30:57 +00003096 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
3097#else
3098 p = (unsigned char *) dhmin;
3099#endif
3100 end = p + dhminlen;
3101
Paul Bakker1b57b062011-01-06 15:48:19 +00003102 memset( dhm, 0, sizeof( dhm_context ) );
3103
Paul Bakker1b57b062011-01-06 15:48:19 +00003104 /*
3105 * DHParams ::= SEQUENCE {
3106 * prime INTEGER, -- P
3107 * generator INTEGER, -- g
3108 * }
3109 */
3110 if( ( ret = asn1_get_tag( &p, end, &len,
3111 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
3112 {
Paul Bakker96743fc2011-02-12 14:30:57 +00003113#if defined(POLARSSL_PEM_C)
3114 pem_free( &pem );
3115#endif
Paul Bakker9d781402011-05-09 16:17:09 +00003116 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00003117 }
3118
3119 end = p + len;
3120
3121 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
3122 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
3123 {
Paul Bakker96743fc2011-02-12 14:30:57 +00003124#if defined(POLARSSL_PEM_C)
3125 pem_free( &pem );
3126#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00003127 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00003128 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00003129 }
3130
3131 if( p != end )
3132 {
Paul Bakker96743fc2011-02-12 14:30:57 +00003133#if defined(POLARSSL_PEM_C)
3134 pem_free( &pem );
3135#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00003136 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00003137 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker1b57b062011-01-06 15:48:19 +00003138 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
3139 }
3140
Paul Bakker96743fc2011-02-12 14:30:57 +00003141#if defined(POLARSSL_PEM_C)
3142 pem_free( &pem );
3143#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00003144
3145 return( 0 );
3146}
3147
Paul Bakker335db3f2011-04-25 15:28:35 +00003148#if defined(POLARSSL_FS_IO)
Paul Bakker1b57b062011-01-06 15:48:19 +00003149/*
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02003150 * Load and parse DHM parameters
Paul Bakker1b57b062011-01-06 15:48:19 +00003151 */
3152int x509parse_dhmfile( dhm_context *dhm, const char *path )
3153{
3154 int ret;
3155 size_t n;
3156 unsigned char *buf;
3157
Paul Bakker69e095c2011-12-10 21:55:01 +00003158 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
3159 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00003160
Paul Bakker27fdf462011-06-09 13:55:13 +00003161 ret = x509parse_dhm( dhm, buf, n );
Paul Bakker1b57b062011-01-06 15:48:19 +00003162
3163 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02003164 polarssl_free( buf );
Paul Bakker1b57b062011-01-06 15:48:19 +00003165
3166 return( ret );
3167}
Paul Bakker335db3f2011-04-25 15:28:35 +00003168#endif /* POLARSSL_FS_IO */
Paul Bakkereaa89f82011-04-04 21:36:15 +00003169#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00003170
Paul Bakker5121ce52009-01-03 21:22:43 +00003171#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00003172#include <stdarg.h>
3173
3174#if !defined vsnprintf
3175#define vsnprintf _vsnprintf
3176#endif // vsnprintf
3177
3178/*
3179 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
3180 * Result value is not size of buffer needed, but -1 if no fit is possible.
3181 *
3182 * This fuction tries to 'fix' this by at least suggesting enlarging the
3183 * size by 20.
3184 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02003185static int compat_snprintf(char *str, size_t size, const char *format, ...)
Paul Bakkerd98030e2009-05-02 15:13:40 +00003186{
3187 va_list ap;
3188 int res = -1;
3189
3190 va_start( ap, format );
3191
3192 res = vsnprintf( str, size, format, ap );
3193
3194 va_end( ap );
3195
3196 // No quick fix possible
3197 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00003198 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003199
3200 return res;
3201}
3202
3203#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00003204#endif
3205
Paul Bakkerd98030e2009-05-02 15:13:40 +00003206#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
3207
3208#define SAFE_SNPRINTF() \
3209{ \
3210 if( ret == -1 ) \
3211 return( -1 ); \
3212 \
Paul Bakker23986e52011-04-24 08:57:21 +00003213 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00003214 p[n - 1] = '\0'; \
3215 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
3216 } \
3217 \
Paul Bakker23986e52011-04-24 08:57:21 +00003218 n -= (unsigned int) ret; \
3219 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00003220}
3221
Paul Bakker5121ce52009-01-03 21:22:43 +00003222/*
3223 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00003224 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00003225 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003226int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00003227{
Paul Bakker23986e52011-04-24 08:57:21 +00003228 int ret;
3229 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00003230 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00003231 const x509_name *name;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003232 const char *short_name = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003233 char s[128], *p;
3234
3235 memset( s, 0, sizeof( s ) );
3236
3237 name = dn;
3238 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003239 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00003240
3241 while( name != NULL )
3242 {
Paul Bakkercefb3962012-06-27 11:51:09 +00003243 if( !name->oid.p )
3244 {
3245 name = name->next;
3246 continue;
3247 }
3248
Paul Bakker74111d32011-01-15 16:57:55 +00003249 if( name != dn )
3250 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00003251 ret = snprintf( p, n, ", " );
3252 SAFE_SNPRINTF();
3253 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003254
Paul Bakkerc70b9822013-04-07 22:00:46 +02003255 ret = oid_get_attr_short_name( &name->oid, &short_name );
Paul Bakker5121ce52009-01-03 21:22:43 +00003256
Paul Bakkerc70b9822013-04-07 22:00:46 +02003257 if( ret == 0 )
3258 ret = snprintf( p, n, "%s=", short_name );
Paul Bakker5121ce52009-01-03 21:22:43 +00003259 else
Paul Bakkerd98030e2009-05-02 15:13:40 +00003260 ret = snprintf( p, n, "\?\?=" );
Paul Bakkerc70b9822013-04-07 22:00:46 +02003261 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003262
3263 for( i = 0; i < name->val.len; i++ )
3264 {
Paul Bakker27fdf462011-06-09 13:55:13 +00003265 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003266 break;
3267
3268 c = name->val.p[i];
3269 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
3270 s[i] = '?';
3271 else s[i] = c;
3272 }
3273 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00003274 ret = snprintf( p, n, "%s", s );
Paul Bakkerc70b9822013-04-07 22:00:46 +02003275 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003276 name = name->next;
3277 }
3278
Paul Bakker23986e52011-04-24 08:57:21 +00003279 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003280}
3281
3282/*
Paul Bakkerdd476992011-01-16 21:34:59 +00003283 * Store the serial in printable form into buf; no more
3284 * than size characters will be written
3285 */
3286int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
3287{
Paul Bakker23986e52011-04-24 08:57:21 +00003288 int ret;
3289 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00003290 char *p;
3291
3292 p = buf;
3293 n = size;
3294
3295 nr = ( serial->len <= 32 )
Paul Bakker03c7c252011-11-25 12:37:37 +00003296 ? serial->len : 28;
Paul Bakkerdd476992011-01-16 21:34:59 +00003297
3298 for( i = 0; i < nr; i++ )
3299 {
Paul Bakker93048802011-12-05 14:38:06 +00003300 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003301 continue;
3302
Paul Bakkerdd476992011-01-16 21:34:59 +00003303 ret = snprintf( p, n, "%02X%s",
3304 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
3305 SAFE_SNPRINTF();
3306 }
3307
Paul Bakker03c7c252011-11-25 12:37:37 +00003308 if( nr != serial->len )
3309 {
3310 ret = snprintf( p, n, "...." );
3311 SAFE_SNPRINTF();
3312 }
3313
Paul Bakker23986e52011-04-24 08:57:21 +00003314 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00003315}
3316
3317/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00003318 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00003319 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003320int x509parse_cert_info( char *buf, size_t size, const char *prefix,
3321 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00003322{
Paul Bakker23986e52011-04-24 08:57:21 +00003323 int ret;
3324 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003325 char *p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003326 const char *desc = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003327
3328 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003329 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00003330
Paul Bakkerd98030e2009-05-02 15:13:40 +00003331 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00003332 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003333 SAFE_SNPRINTF();
3334 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00003335 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003336 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003337
Paul Bakkerdd476992011-01-16 21:34:59 +00003338 ret = x509parse_serial_gets( p, n, &crt->serial);
3339 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003340
Paul Bakkerd98030e2009-05-02 15:13:40 +00003341 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
3342 SAFE_SNPRINTF();
3343 ret = x509parse_dn_gets( p, n, &crt->issuer );
3344 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003345
Paul Bakkerd98030e2009-05-02 15:13:40 +00003346 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
3347 SAFE_SNPRINTF();
3348 ret = x509parse_dn_gets( p, n, &crt->subject );
3349 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003350
Paul Bakkerd98030e2009-05-02 15:13:40 +00003351 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00003352 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3353 crt->valid_from.year, crt->valid_from.mon,
3354 crt->valid_from.day, crt->valid_from.hour,
3355 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003356 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003357
Paul Bakkerd98030e2009-05-02 15:13:40 +00003358 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00003359 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3360 crt->valid_to.year, crt->valid_to.mon,
3361 crt->valid_to.day, crt->valid_to.hour,
3362 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003363 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003364
Paul Bakkerc70b9822013-04-07 22:00:46 +02003365 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003366 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003367
Paul Bakkerc70b9822013-04-07 22:00:46 +02003368 ret = oid_get_sig_alg_desc( &crt->sig_oid1, &desc );
3369 if( ret != 0 )
3370 ret = snprintf( p, n, "???" );
3371 else
3372 ret = snprintf( p, n, desc );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003373 SAFE_SNPRINTF();
3374
3375 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
Paul Bakker5c2364c2012-10-01 14:41:15 +00003376 (int) crt->rsa.N.n * (int) sizeof( t_uint ) * 8 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003377 SAFE_SNPRINTF();
3378
Paul Bakker23986e52011-04-24 08:57:21 +00003379 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003380}
3381
Paul Bakker74111d32011-01-15 16:57:55 +00003382/*
3383 * Return an informational string describing the given OID
3384 */
3385const char *x509_oid_get_description( x509_buf *oid )
3386{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003387 const char *desc = NULL;
3388 int ret;
Paul Bakker74111d32011-01-15 16:57:55 +00003389
Paul Bakkerc70b9822013-04-07 22:00:46 +02003390 ret = oid_get_extended_key_usage( oid, &desc );
Paul Bakker74111d32011-01-15 16:57:55 +00003391
Paul Bakkerc70b9822013-04-07 22:00:46 +02003392 if( ret != 0 )
3393 return( NULL );
Paul Bakker74111d32011-01-15 16:57:55 +00003394
Paul Bakkerc70b9822013-04-07 22:00:46 +02003395 return( desc );
Paul Bakker74111d32011-01-15 16:57:55 +00003396}
3397
3398/* Return the x.y.z.... style numeric string for the given OID */
3399int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
3400{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003401 return oid_get_numeric_string( buf, size, oid );
Paul Bakker74111d32011-01-15 16:57:55 +00003402}
3403
Paul Bakkerd98030e2009-05-02 15:13:40 +00003404/*
3405 * Return an informational string about the CRL.
3406 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003407int x509parse_crl_info( char *buf, size_t size, const char *prefix,
3408 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003409{
Paul Bakker23986e52011-04-24 08:57:21 +00003410 int ret;
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003411 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003412 char *p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003413 const char *desc;
Paul Bakkerff60ee62010-03-16 21:09:09 +00003414 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003415
3416 p = buf;
3417 n = size;
3418
3419 ret = snprintf( p, n, "%sCRL version : %d",
3420 prefix, crl->version );
3421 SAFE_SNPRINTF();
3422
3423 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
3424 SAFE_SNPRINTF();
3425 ret = x509parse_dn_gets( p, n, &crl->issuer );
3426 SAFE_SNPRINTF();
3427
3428 ret = snprintf( p, n, "\n%sthis update : " \
3429 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3430 crl->this_update.year, crl->this_update.mon,
3431 crl->this_update.day, crl->this_update.hour,
3432 crl->this_update.min, crl->this_update.sec );
3433 SAFE_SNPRINTF();
3434
3435 ret = snprintf( p, n, "\n%snext update : " \
3436 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3437 crl->next_update.year, crl->next_update.mon,
3438 crl->next_update.day, crl->next_update.hour,
3439 crl->next_update.min, crl->next_update.sec );
3440 SAFE_SNPRINTF();
3441
3442 entry = &crl->entry;
3443
3444 ret = snprintf( p, n, "\n%sRevoked certificates:",
3445 prefix );
3446 SAFE_SNPRINTF();
3447
Paul Bakker9be19372009-07-27 20:21:53 +00003448 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003449 {
3450 ret = snprintf( p, n, "\n%sserial number: ",
3451 prefix );
3452 SAFE_SNPRINTF();
3453
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003454 ret = x509parse_serial_gets( p, n, &entry->serial);
3455 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003456
Paul Bakkerd98030e2009-05-02 15:13:40 +00003457 ret = snprintf( p, n, " revocation date: " \
3458 "%04d-%02d-%02d %02d:%02d:%02d",
3459 entry->revocation_date.year, entry->revocation_date.mon,
3460 entry->revocation_date.day, entry->revocation_date.hour,
3461 entry->revocation_date.min, entry->revocation_date.sec );
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003462 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003463
3464 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003465 }
3466
Paul Bakkerc70b9822013-04-07 22:00:46 +02003467 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003468 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003469
Paul Bakkerc70b9822013-04-07 22:00:46 +02003470 ret = oid_get_sig_alg_desc( &crl->sig_oid1, &desc );
3471 if( ret != 0 )
3472 ret = snprintf( p, n, "???" );
3473 else
3474 ret = snprintf( p, n, desc );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003475 SAFE_SNPRINTF();
3476
Paul Bakker1e27bb22009-07-19 20:25:25 +00003477 ret = snprintf( p, n, "\n" );
3478 SAFE_SNPRINTF();
3479
Paul Bakker23986e52011-04-24 08:57:21 +00003480 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003481}
3482
3483/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00003484 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00003485 */
Paul Bakkerfa9b1002013-07-03 15:31:03 +02003486#if defined(POLARSSL_HAVE_TIME)
Paul Bakkerff60ee62010-03-16 21:09:09 +00003487int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00003488{
Paul Bakkercce9d772011-11-18 14:26:47 +00003489 int year, mon, day;
3490 int hour, min, sec;
3491
3492#if defined(_WIN32)
3493 SYSTEMTIME st;
3494
3495 GetLocalTime(&st);
3496
3497 year = st.wYear;
3498 mon = st.wMonth;
3499 day = st.wDay;
3500 hour = st.wHour;
3501 min = st.wMinute;
3502 sec = st.wSecond;
3503#else
Paul Bakker5121ce52009-01-03 21:22:43 +00003504 struct tm *lt;
3505 time_t tt;
3506
3507 tt = time( NULL );
3508 lt = localtime( &tt );
3509
Paul Bakkercce9d772011-11-18 14:26:47 +00003510 year = lt->tm_year + 1900;
3511 mon = lt->tm_mon + 1;
3512 day = lt->tm_mday;
3513 hour = lt->tm_hour;
3514 min = lt->tm_min;
3515 sec = lt->tm_sec;
3516#endif
3517
3518 if( year > to->year )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003519 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003520
Paul Bakkercce9d772011-11-18 14:26:47 +00003521 if( year == to->year &&
3522 mon > to->mon )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003523 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003524
Paul Bakkercce9d772011-11-18 14:26:47 +00003525 if( year == to->year &&
3526 mon == to->mon &&
3527 day > to->day )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003528 return( 1 );
3529
Paul Bakkercce9d772011-11-18 14:26:47 +00003530 if( year == to->year &&
3531 mon == to->mon &&
3532 day == to->day &&
3533 hour > to->hour )
Paul Bakkerb6194992011-01-16 21:40:22 +00003534 return( 1 );
3535
Paul Bakkercce9d772011-11-18 14:26:47 +00003536 if( year == to->year &&
3537 mon == to->mon &&
3538 day == to->day &&
3539 hour == to->hour &&
3540 min > to->min )
Paul Bakkerb6194992011-01-16 21:40:22 +00003541 return( 1 );
3542
Paul Bakkercce9d772011-11-18 14:26:47 +00003543 if( year == to->year &&
3544 mon == to->mon &&
3545 day == to->day &&
3546 hour == to->hour &&
3547 min == to->min &&
3548 sec > to->sec )
Paul Bakkerb6194992011-01-16 21:40:22 +00003549 return( 1 );
3550
Paul Bakker40ea7de2009-05-03 10:18:48 +00003551 return( 0 );
3552}
Paul Bakkerfa9b1002013-07-03 15:31:03 +02003553#else /* POLARSSL_HAVE_TIME */
3554int x509parse_time_expired( const x509_time *to )
3555{
3556 ((void) to);
3557 return( 0 );
3558}
3559#endif /* POLARSSL_HAVE_TIME */
Paul Bakker40ea7de2009-05-03 10:18:48 +00003560
3561/*
3562 * Return 1 if the certificate is revoked, or 0 otherwise.
3563 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003564int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003565{
Paul Bakkerff60ee62010-03-16 21:09:09 +00003566 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00003567
3568 while( cur != NULL && cur->serial.len != 0 )
3569 {
Paul Bakkera056efc2011-01-16 21:38:35 +00003570 if( crt->serial.len == cur->serial.len &&
3571 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003572 {
3573 if( x509parse_time_expired( &cur->revocation_date ) )
3574 return( 1 );
3575 }
3576
3577 cur = cur->next;
3578 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003579
3580 return( 0 );
3581}
3582
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003583/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00003584 * Check that the given certificate is valid accoring to the CRL.
3585 */
3586static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
3587 x509_crl *crl_list)
3588{
3589 int flags = 0;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003590 unsigned char hash[POLARSSL_MD_MAX_SIZE];
3591 const md_info_t *md_info;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003592
Paul Bakker915275b2012-09-28 07:10:55 +00003593 if( ca == NULL )
3594 return( flags );
3595
Paul Bakker76fd75a2011-01-16 21:12:10 +00003596 /*
3597 * TODO: What happens if no CRL is present?
3598 * Suggestion: Revocation state should be unknown if no CRL is present.
3599 * For backwards compatibility this is not yet implemented.
3600 */
3601
Paul Bakker915275b2012-09-28 07:10:55 +00003602 while( crl_list != NULL )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003603 {
Paul Bakker915275b2012-09-28 07:10:55 +00003604 if( crl_list->version == 0 ||
3605 crl_list->issuer_raw.len != ca->subject_raw.len ||
Paul Bakker76fd75a2011-01-16 21:12:10 +00003606 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
3607 crl_list->issuer_raw.len ) != 0 )
3608 {
3609 crl_list = crl_list->next;
3610 continue;
3611 }
3612
3613 /*
3614 * Check if CRL is correctly signed by the trusted CA
3615 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02003616 md_info = md_info_from_type( crl_list->sig_md );
3617 if( md_info == NULL )
3618 {
3619 /*
3620 * Cannot check 'unknown' hash
3621 */
3622 flags |= BADCRL_NOT_TRUSTED;
3623 break;
3624 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00003625
Paul Bakkerc70b9822013-04-07 22:00:46 +02003626 md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
Paul Bakker76fd75a2011-01-16 21:12:10 +00003627
Paul Bakkerc70b9822013-04-07 22:00:46 +02003628 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, crl_list->sig_md,
Paul Bakker76fd75a2011-01-16 21:12:10 +00003629 0, hash, crl_list->sig.p ) == 0 )
3630 {
3631 /*
3632 * CRL is not trusted
3633 */
3634 flags |= BADCRL_NOT_TRUSTED;
3635 break;
3636 }
3637
3638 /*
3639 * Check for validity of CRL (Do not drop out)
3640 */
3641 if( x509parse_time_expired( &crl_list->next_update ) )
3642 flags |= BADCRL_EXPIRED;
3643
3644 /*
3645 * Check if certificate is revoked
3646 */
3647 if( x509parse_revoked(crt, crl_list) )
3648 {
3649 flags |= BADCERT_REVOKED;
3650 break;
3651 }
3652
3653 crl_list = crl_list->next;
3654 }
3655 return flags;
3656}
3657
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02003658static int x509_wildcard_verify( const char *cn, x509_buf *name )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003659{
3660 size_t i;
3661 size_t cn_idx = 0;
3662
Paul Bakker57b12982012-02-11 17:38:38 +00003663 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003664 return( 0 );
3665
3666 for( i = 0; i < strlen( cn ); ++i )
3667 {
3668 if( cn[i] == '.' )
3669 {
3670 cn_idx = i;
3671 break;
3672 }
3673 }
3674
3675 if( cn_idx == 0 )
3676 return( 0 );
3677
Paul Bakker535e97d2012-08-23 10:49:55 +00003678 if( strlen( cn ) - cn_idx == name->len - 1 &&
3679 memcmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003680 {
3681 return( 1 );
3682 }
3683
3684 return( 0 );
3685}
3686
Paul Bakker915275b2012-09-28 07:10:55 +00003687static int x509parse_verify_top(
3688 x509_cert *child, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003689 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003690 int (*f_vrfy)(void *, x509_cert *, int, int *),
3691 void *p_vrfy )
3692{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003693 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003694 int ca_flags = 0, check_path_cnt = path_cnt + 1;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003695 unsigned char hash[POLARSSL_MD_MAX_SIZE];
3696 const md_info_t *md_info;
Paul Bakker915275b2012-09-28 07:10:55 +00003697
3698 if( x509parse_time_expired( &child->valid_to ) )
3699 *flags |= BADCERT_EXPIRED;
3700
3701 /*
3702 * Child is the top of the chain. Check against the trust_ca list.
3703 */
3704 *flags |= BADCERT_NOT_TRUSTED;
3705
3706 while( trust_ca != NULL )
3707 {
3708 if( trust_ca->version == 0 ||
3709 child->issuer_raw.len != trust_ca->subject_raw.len ||
3710 memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
3711 child->issuer_raw.len ) != 0 )
3712 {
3713 trust_ca = trust_ca->next;
3714 continue;
3715 }
3716
Paul Bakker9a736322012-11-14 12:39:52 +00003717 /*
3718 * Reduce path_len to check against if top of the chain is
3719 * the same as the trusted CA
3720 */
3721 if( child->subject_raw.len == trust_ca->subject_raw.len &&
3722 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3723 child->issuer_raw.len ) == 0 )
3724 {
3725 check_path_cnt--;
3726 }
3727
Paul Bakker915275b2012-09-28 07:10:55 +00003728 if( trust_ca->max_pathlen > 0 &&
Paul Bakker9a736322012-11-14 12:39:52 +00003729 trust_ca->max_pathlen < check_path_cnt )
Paul Bakker915275b2012-09-28 07:10:55 +00003730 {
3731 trust_ca = trust_ca->next;
3732 continue;
3733 }
3734
Paul Bakkerc70b9822013-04-07 22:00:46 +02003735 md_info = md_info_from_type( child->sig_md );
3736 if( md_info == NULL )
3737 {
3738 /*
3739 * Cannot check 'unknown' hash
3740 */
3741 continue;
3742 }
Paul Bakker915275b2012-09-28 07:10:55 +00003743
Paul Bakkerc70b9822013-04-07 22:00:46 +02003744 md( md_info, child->tbs.p, child->tbs.len, hash );
Paul Bakker915275b2012-09-28 07:10:55 +00003745
Paul Bakkerc70b9822013-04-07 22:00:46 +02003746 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, child->sig_md,
Paul Bakker915275b2012-09-28 07:10:55 +00003747 0, hash, child->sig.p ) != 0 )
3748 {
3749 trust_ca = trust_ca->next;
3750 continue;
3751 }
3752
3753 /*
3754 * Top of chain is signed by a trusted CA
3755 */
3756 *flags &= ~BADCERT_NOT_TRUSTED;
3757 break;
3758 }
3759
Paul Bakker9a736322012-11-14 12:39:52 +00003760 /*
Paul Bakker3497d8c2012-11-24 11:53:17 +01003761 * If top of chain is not the same as the trusted CA send a verify request
3762 * to the callback for any issues with validity and CRL presence for the
3763 * trusted CA certificate.
Paul Bakker9a736322012-11-14 12:39:52 +00003764 */
3765 if( trust_ca != NULL &&
3766 ( child->subject_raw.len != trust_ca->subject_raw.len ||
3767 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3768 child->issuer_raw.len ) != 0 ) )
Paul Bakker915275b2012-09-28 07:10:55 +00003769 {
3770 /* Check trusted CA's CRL for then chain's top crt */
3771 *flags |= x509parse_verifycrl( child, trust_ca, ca_crl );
3772
3773 if( x509parse_time_expired( &trust_ca->valid_to ) )
3774 ca_flags |= BADCERT_EXPIRED;
3775
Paul Bakker915275b2012-09-28 07:10:55 +00003776 if( NULL != f_vrfy )
3777 {
Paul Bakker9a736322012-11-14 12:39:52 +00003778 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003779 return( ret );
3780 }
3781 }
3782
3783 /* Call callback on top cert */
3784 if( NULL != f_vrfy )
3785 {
Paul Bakker9a736322012-11-14 12:39:52 +00003786 if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003787 return( ret );
3788 }
3789
Paul Bakker915275b2012-09-28 07:10:55 +00003790 *flags |= ca_flags;
3791
3792 return( 0 );
3793}
3794
3795static int x509parse_verify_child(
3796 x509_cert *child, x509_cert *parent, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003797 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003798 int (*f_vrfy)(void *, x509_cert *, int, int *),
3799 void *p_vrfy )
3800{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003801 int ret;
Paul Bakker915275b2012-09-28 07:10:55 +00003802 int parent_flags = 0;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003803 unsigned char hash[POLARSSL_MD_MAX_SIZE];
Paul Bakker915275b2012-09-28 07:10:55 +00003804 x509_cert *grandparent;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003805 const md_info_t *md_info;
Paul Bakker915275b2012-09-28 07:10:55 +00003806
3807 if( x509parse_time_expired( &child->valid_to ) )
3808 *flags |= BADCERT_EXPIRED;
3809
Paul Bakkerc70b9822013-04-07 22:00:46 +02003810 md_info = md_info_from_type( child->sig_md );
3811 if( md_info == NULL )
3812 {
3813 /*
3814 * Cannot check 'unknown' hash
3815 */
Paul Bakker915275b2012-09-28 07:10:55 +00003816 *flags |= BADCERT_NOT_TRUSTED;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003817 }
3818 else
3819 {
3820 md( md_info, child->tbs.p, child->tbs.len, hash );
3821
3822 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, child->sig_md, 0, hash,
3823 child->sig.p ) != 0 )
3824 *flags |= BADCERT_NOT_TRUSTED;
3825 }
3826
Paul Bakker915275b2012-09-28 07:10:55 +00003827 /* Check trusted CA's CRL for the given crt */
3828 *flags |= x509parse_verifycrl(child, parent, ca_crl);
3829
3830 grandparent = parent->next;
3831
3832 while( grandparent != NULL )
3833 {
3834 if( grandparent->version == 0 ||
3835 grandparent->ca_istrue == 0 ||
3836 parent->issuer_raw.len != grandparent->subject_raw.len ||
3837 memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
3838 parent->issuer_raw.len ) != 0 )
3839 {
3840 grandparent = grandparent->next;
3841 continue;
3842 }
3843 break;
3844 }
3845
Paul Bakker915275b2012-09-28 07:10:55 +00003846 if( grandparent != NULL )
3847 {
3848 /*
3849 * Part of the chain
3850 */
Paul Bakker9a736322012-11-14 12:39:52 +00003851 ret = x509parse_verify_child( parent, grandparent, trust_ca, ca_crl, path_cnt + 1, &parent_flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003852 if( ret != 0 )
3853 return( ret );
3854 }
3855 else
3856 {
Paul Bakker9a736322012-11-14 12:39:52 +00003857 ret = x509parse_verify_top( parent, trust_ca, ca_crl, path_cnt + 1, &parent_flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003858 if( ret != 0 )
3859 return( ret );
3860 }
3861
3862 /* child is verified to be a child of the parent, call verify callback */
3863 if( NULL != f_vrfy )
Paul Bakker9a736322012-11-14 12:39:52 +00003864 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003865 return( ret );
Paul Bakker915275b2012-09-28 07:10:55 +00003866
3867 *flags |= parent_flags;
3868
3869 return( 0 );
3870}
3871
Paul Bakker76fd75a2011-01-16 21:12:10 +00003872/*
Paul Bakker5121ce52009-01-03 21:22:43 +00003873 * Verify the certificate validity
3874 */
3875int x509parse_verify( x509_cert *crt,
3876 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00003877 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003878 const char *cn, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003879 int (*f_vrfy)(void *, x509_cert *, int, int *),
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003880 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00003881{
Paul Bakker23986e52011-04-24 08:57:21 +00003882 size_t cn_len;
Paul Bakker915275b2012-09-28 07:10:55 +00003883 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003884 int pathlen = 0;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003885 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00003886 x509_name *name;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003887 x509_sequence *cur = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003888
Paul Bakker40ea7de2009-05-03 10:18:48 +00003889 *flags = 0;
3890
Paul Bakker5121ce52009-01-03 21:22:43 +00003891 if( cn != NULL )
3892 {
3893 name = &crt->subject;
3894 cn_len = strlen( cn );
3895
Paul Bakker4d2c1242012-05-10 14:12:46 +00003896 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
Paul Bakker5121ce52009-01-03 21:22:43 +00003897 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00003898 cur = &crt->subject_alt_names;
3899
3900 while( cur != NULL )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003901 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003902 if( cur->buf.len == cn_len &&
3903 memcmp( cn, cur->buf.p, cn_len ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003904 break;
3905
Paul Bakker535e97d2012-08-23 10:49:55 +00003906 if( cur->buf.len > 2 &&
3907 memcmp( cur->buf.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003908 x509_wildcard_verify( cn, &cur->buf ) )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003909 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003910
Paul Bakker4d2c1242012-05-10 14:12:46 +00003911 cur = cur->next;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003912 }
3913
3914 if( cur == NULL )
3915 *flags |= BADCERT_CN_MISMATCH;
3916 }
Paul Bakker4d2c1242012-05-10 14:12:46 +00003917 else
3918 {
3919 while( name != NULL )
3920 {
Paul Bakkerc70b9822013-04-07 22:00:46 +02003921 if( OID_CMP( OID_AT_CN, &name->oid ) )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003922 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003923 if( name->val.len == cn_len &&
3924 memcmp( name->val.p, cn, cn_len ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003925 break;
3926
Paul Bakker535e97d2012-08-23 10:49:55 +00003927 if( name->val.len > 2 &&
3928 memcmp( name->val.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003929 x509_wildcard_verify( cn, &name->val ) )
3930 break;
3931 }
3932
3933 name = name->next;
3934 }
3935
3936 if( name == NULL )
3937 *flags |= BADCERT_CN_MISMATCH;
3938 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003939 }
3940
Paul Bakker5121ce52009-01-03 21:22:43 +00003941 /*
Paul Bakker915275b2012-09-28 07:10:55 +00003942 * Iterate upwards in the given cert chain, to find our crt parent.
3943 * Ignore any upper cert with CA != TRUE.
Paul Bakker5121ce52009-01-03 21:22:43 +00003944 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003945 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003946
Paul Bakker76fd75a2011-01-16 21:12:10 +00003947 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003948 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003949 if( parent->ca_istrue == 0 ||
3950 crt->issuer_raw.len != parent->subject_raw.len ||
3951 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00003952 crt->issuer_raw.len ) != 0 )
3953 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003954 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003955 continue;
3956 }
Paul Bakker915275b2012-09-28 07:10:55 +00003957 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003958 }
3959
Paul Bakker915275b2012-09-28 07:10:55 +00003960 if( parent != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003961 {
Paul Bakker915275b2012-09-28 07:10:55 +00003962 /*
3963 * Part of the chain
3964 */
Paul Bakker9a736322012-11-14 12:39:52 +00003965 ret = x509parse_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003966 if( ret != 0 )
3967 return( ret );
3968 }
3969 else
Paul Bakker74111d32011-01-15 16:57:55 +00003970 {
Paul Bakker9a736322012-11-14 12:39:52 +00003971 ret = x509parse_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003972 if( ret != 0 )
3973 return( ret );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003974 }
Paul Bakker915275b2012-09-28 07:10:55 +00003975
3976 if( *flags != 0 )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003977 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003978
Paul Bakker5121ce52009-01-03 21:22:43 +00003979 return( 0 );
3980}
3981
3982/*
3983 * Unallocate all certificate data
3984 */
3985void x509_free( x509_cert *crt )
3986{
3987 x509_cert *cert_cur = crt;
3988 x509_cert *cert_prv;
3989 x509_name *name_cur;
3990 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00003991 x509_sequence *seq_cur;
3992 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00003993
3994 if( crt == NULL )
3995 return;
3996
3997 do
3998 {
3999 rsa_free( &cert_cur->rsa );
4000
4001 name_cur = cert_cur->issuer.next;
4002 while( name_cur != NULL )
4003 {
4004 name_prv = name_cur;
4005 name_cur = name_cur->next;
4006 memset( name_prv, 0, sizeof( x509_name ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02004007 polarssl_free( name_prv );
Paul Bakker5121ce52009-01-03 21:22:43 +00004008 }
4009
4010 name_cur = cert_cur->subject.next;
4011 while( name_cur != NULL )
4012 {
4013 name_prv = name_cur;
4014 name_cur = name_cur->next;
4015 memset( name_prv, 0, sizeof( x509_name ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02004016 polarssl_free( name_prv );
Paul Bakker5121ce52009-01-03 21:22:43 +00004017 }
4018
Paul Bakker74111d32011-01-15 16:57:55 +00004019 seq_cur = cert_cur->ext_key_usage.next;
4020 while( seq_cur != NULL )
4021 {
4022 seq_prv = seq_cur;
4023 seq_cur = seq_cur->next;
4024 memset( seq_prv, 0, sizeof( x509_sequence ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02004025 polarssl_free( seq_prv );
Paul Bakker74111d32011-01-15 16:57:55 +00004026 }
4027
Paul Bakker8afa70d2012-02-11 18:42:45 +00004028 seq_cur = cert_cur->subject_alt_names.next;
4029 while( seq_cur != NULL )
4030 {
4031 seq_prv = seq_cur;
4032 seq_cur = seq_cur->next;
4033 memset( seq_prv, 0, sizeof( x509_sequence ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02004034 polarssl_free( seq_prv );
Paul Bakker8afa70d2012-02-11 18:42:45 +00004035 }
4036
Paul Bakker5121ce52009-01-03 21:22:43 +00004037 if( cert_cur->raw.p != NULL )
4038 {
4039 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
Paul Bakker6e339b52013-07-03 13:37:05 +02004040 polarssl_free( cert_cur->raw.p );
Paul Bakker5121ce52009-01-03 21:22:43 +00004041 }
4042
4043 cert_cur = cert_cur->next;
4044 }
4045 while( cert_cur != NULL );
4046
4047 cert_cur = crt;
4048 do
4049 {
4050 cert_prv = cert_cur;
4051 cert_cur = cert_cur->next;
4052
4053 memset( cert_prv, 0, sizeof( x509_cert ) );
4054 if( cert_prv != crt )
Paul Bakker6e339b52013-07-03 13:37:05 +02004055 polarssl_free( cert_prv );
Paul Bakker5121ce52009-01-03 21:22:43 +00004056 }
4057 while( cert_cur != NULL );
4058}
4059
Paul Bakkerd98030e2009-05-02 15:13:40 +00004060/*
4061 * Unallocate all CRL data
4062 */
4063void x509_crl_free( x509_crl *crl )
4064{
4065 x509_crl *crl_cur = crl;
4066 x509_crl *crl_prv;
4067 x509_name *name_cur;
4068 x509_name *name_prv;
4069 x509_crl_entry *entry_cur;
4070 x509_crl_entry *entry_prv;
4071
4072 if( crl == NULL )
4073 return;
4074
4075 do
4076 {
4077 name_cur = crl_cur->issuer.next;
4078 while( name_cur != NULL )
4079 {
4080 name_prv = name_cur;
4081 name_cur = name_cur->next;
4082 memset( name_prv, 0, sizeof( x509_name ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02004083 polarssl_free( name_prv );
Paul Bakkerd98030e2009-05-02 15:13:40 +00004084 }
4085
4086 entry_cur = crl_cur->entry.next;
4087 while( entry_cur != NULL )
4088 {
4089 entry_prv = entry_cur;
4090 entry_cur = entry_cur->next;
4091 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02004092 polarssl_free( entry_prv );
Paul Bakkerd98030e2009-05-02 15:13:40 +00004093 }
4094
4095 if( crl_cur->raw.p != NULL )
4096 {
4097 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
Paul Bakker6e339b52013-07-03 13:37:05 +02004098 polarssl_free( crl_cur->raw.p );
Paul Bakkerd98030e2009-05-02 15:13:40 +00004099 }
4100
4101 crl_cur = crl_cur->next;
4102 }
4103 while( crl_cur != NULL );
4104
4105 crl_cur = crl;
4106 do
4107 {
4108 crl_prv = crl_cur;
4109 crl_cur = crl_cur->next;
4110
4111 memset( crl_prv, 0, sizeof( x509_crl ) );
4112 if( crl_prv != crl )
Paul Bakker6e339b52013-07-03 13:37:05 +02004113 polarssl_free( crl_prv );
Paul Bakkerd98030e2009-05-02 15:13:40 +00004114 }
4115 while( crl_cur != NULL );
4116}
4117
Paul Bakker40e46942009-01-03 21:51:57 +00004118#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00004119
Paul Bakker40e46942009-01-03 21:51:57 +00004120#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00004121
4122/*
4123 * Checkup routine
4124 */
4125int x509_self_test( int verbose )
4126{
Paul Bakker5690efc2011-05-26 13:16:06 +00004127#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00004128 int ret;
4129 int flags;
4130 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00004131 x509_cert cacert;
4132 x509_cert clicert;
4133 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00004134#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00004135 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00004136#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00004137
4138 if( verbose != 0 )
4139 printf( " X.509 certificate load: " );
4140
4141 memset( &clicert, 0, sizeof( x509_cert ) );
4142
Paul Bakker3c2122f2013-06-24 19:03:14 +02004143 ret = x509parse_crt( &clicert, (const unsigned char *) test_cli_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00004144 strlen( test_cli_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00004145 if( ret != 0 )
4146 {
4147 if( verbose != 0 )
4148 printf( "failed\n" );
4149
4150 return( ret );
4151 }
4152
4153 memset( &cacert, 0, sizeof( x509_cert ) );
4154
Paul Bakker3c2122f2013-06-24 19:03:14 +02004155 ret = x509parse_crt( &cacert, (const unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00004156 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00004157 if( ret != 0 )
4158 {
4159 if( verbose != 0 )
4160 printf( "failed\n" );
4161
4162 return( ret );
4163 }
4164
4165 if( verbose != 0 )
4166 printf( "passed\n X.509 private key load: " );
4167
4168 i = strlen( test_ca_key );
4169 j = strlen( test_ca_pwd );
4170
Paul Bakker66b78b22011-03-25 14:22:50 +00004171 rsa_init( &rsa, RSA_PKCS_V15, 0 );
4172
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02004173 if( ( ret = x509parse_key_rsa( &rsa,
Paul Bakker3c2122f2013-06-24 19:03:14 +02004174 (const unsigned char *) test_ca_key, i,
4175 (const unsigned char *) test_ca_pwd, j ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00004176 {
4177 if( verbose != 0 )
4178 printf( "failed\n" );
4179
4180 return( ret );
4181 }
4182
4183 if( verbose != 0 )
4184 printf( "passed\n X.509 signature verify: ");
4185
Paul Bakker23986e52011-04-24 08:57:21 +00004186 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00004187 if( ret != 0 )
4188 {
Paul Bakker23986e52011-04-24 08:57:21 +00004189 printf("%02x", flags);
Paul Bakker5121ce52009-01-03 21:22:43 +00004190 if( verbose != 0 )
4191 printf( "failed\n" );
4192
4193 return( ret );
4194 }
4195
Paul Bakker5690efc2011-05-26 13:16:06 +00004196#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00004197 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00004198 printf( "passed\n X.509 DHM parameter load: " );
4199
4200 i = strlen( test_dhm_params );
4201 j = strlen( test_ca_pwd );
4202
Paul Bakker3c2122f2013-06-24 19:03:14 +02004203 if( ( ret = x509parse_dhm( &dhm, (const unsigned char *) test_dhm_params, i ) ) != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00004204 {
4205 if( verbose != 0 )
4206 printf( "failed\n" );
4207
4208 return( ret );
4209 }
4210
4211 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00004212 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00004213#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00004214
4215 x509_free( &cacert );
4216 x509_free( &clicert );
4217 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00004218#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00004219 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00004220#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00004221
4222 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00004223#else
4224 ((void) verbose);
4225 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
4226#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00004227}
4228
4229#endif
4230
4231#endif