blob: 6f20919552a8b611b2e22b5a4bb52330d423d20a [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 {
589 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
590 }
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
634 pk_set_type( pk, pk_alg );
635
636 switch( pk_alg )
637 {
638 case POLARSSL_PK_NONE:
639 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
640
641 case POLARSSL_PK_RSA:
642 return( x509_get_rsapubkey( p, end, pk->data ) );
643
644 case POLARSSL_PK_ECKEY_DH:
645 ((ecp_keypair *) pk->data)->alg = POLARSSL_ECP_KEY_ALG_ECDH;
646 /* FALLTHROUGH */
647 case POLARSSL_PK_ECKEY:
648 return( x509_get_ecpubkey( p, end, &alg_params, pk->data ) );
649 }
650}
651
Manuel Pégourié-Gonnard094ad9e2013-07-09 12:32:51 +0200652/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000653 * SubjectPublicKeyInfo ::= SEQUENCE {
654 * algorithm AlgorithmIdentifier,
655 * subjectPublicKey BIT STRING }
656 */
Manuel Pégourié-Gonnard094ad9e2013-07-09 12:32:51 +0200657static int x509_get_pubkey_rsa( unsigned char **p,
658 const unsigned char *end,
659 rsa_context *rsa )
Paul Bakker5121ce52009-01-03 21:22:43 +0000660{
Paul Bakkerc70b9822013-04-07 22:00:46 +0200661 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000662 size_t len;
Manuel Pégourié-Gonnard788db112013-07-09 11:26:17 +0200663 x509_buf pk_alg_oid;
Paul Bakkerc70b9822013-04-07 22:00:46 +0200664 pk_type_t pk_alg = POLARSSL_PK_NONE;
Paul Bakker5121ce52009-01-03 21:22:43 +0000665
Manuel Pégourié-Gonnard20c12f62013-07-09 12:13:24 +0200666 if( ( ret = asn1_get_tag( p, end, &len,
667 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
668 {
669 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
670 }
671
672 end = *p + len;
673
Manuel Pégourié-Gonnard788db112013-07-09 11:26:17 +0200674 if( ( ret = asn1_get_alg_null( p, end, &pk_alg_oid ) ) != 0 )
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200675 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000676
677 /*
678 * only RSA public keys handled at this time
679 */
Manuel Pégourié-Gonnard788db112013-07-09 11:26:17 +0200680 if( oid_get_pk_alg( &pk_alg_oid, &pk_alg ) != 0 )
Manuel Pégourié-Gonnard80300ad2013-07-04 11:57:13 +0200681 {
Paul Bakkered56b222011-07-13 11:26:43 +0000682 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
Manuel Pégourié-Gonnard80300ad2013-07-04 11:57:13 +0200683 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000684
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +0200685 if (pk_alg != POLARSSL_PK_RSA )
686 return( POLARSSL_ERR_X509_CERT_INVALID_ALG );
687
Paul Bakker5121ce52009-01-03 21:22:43 +0000688 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000689 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000690
691 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000692 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000693 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000694
Manuel Pégourié-Gonnardf16ac762013-07-09 12:26:00 +0200695 if( *p + len != end )
696 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
697 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000698
699 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000700 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000701
Manuel Pégourié-Gonnard094ad9e2013-07-09 12:32:51 +0200702 return( x509_get_rsapubkey( p, end, rsa ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000703}
704
705static int x509_get_sig( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000706 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000707 x509_buf *sig )
708{
Paul Bakker23986e52011-04-24 08:57:21 +0000709 int ret;
710 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000711
Paul Bakker8afa70d2012-02-11 18:42:45 +0000712 if( ( end - *p ) < 1 )
713 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE +
714 POLARSSL_ERR_ASN1_OUT_OF_DATA );
715
Paul Bakker5121ce52009-01-03 21:22:43 +0000716 sig->tag = **p;
717
718 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000719 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000720
Paul Bakker74111d32011-01-15 16:57:55 +0000721
Paul Bakker5121ce52009-01-03 21:22:43 +0000722 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000723 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000724
725 sig->len = len;
726 sig->p = *p;
727
728 *p += len;
729
730 return( 0 );
731}
732
733/*
734 * X.509 v2/v3 unique identifier (not parsed)
735 */
736static int x509_get_uid( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000737 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000738 x509_buf *uid, int n )
739{
740 int ret;
741
742 if( *p == end )
743 return( 0 );
744
745 uid->tag = **p;
746
747 if( ( ret = asn1_get_tag( p, end, &uid->len,
748 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
749 {
Paul Bakker40e46942009-01-03 21:51:57 +0000750 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000751 return( 0 );
752
753 return( ret );
754 }
755
756 uid->p = *p;
757 *p += uid->len;
758
759 return( 0 );
760}
761
762/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000763 * X.509 Extensions (No parsing of extensions, pointer should
764 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000765 */
766static int x509_get_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000767 const unsigned char *end,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000768 x509_buf *ext, int tag )
Paul Bakker5121ce52009-01-03 21:22:43 +0000769{
Paul Bakker23986e52011-04-24 08:57:21 +0000770 int ret;
771 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000772
773 if( *p == end )
774 return( 0 );
775
776 ext->tag = **p;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000777
Paul Bakker5121ce52009-01-03 21:22:43 +0000778 if( ( ret = asn1_get_tag( p, end, &ext->len,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000779 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000780 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000781
782 ext->p = *p;
783 end = *p + ext->len;
784
785 /*
786 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
787 *
788 * Extension ::= SEQUENCE {
789 * extnID OBJECT IDENTIFIER,
790 * critical BOOLEAN DEFAULT FALSE,
791 * extnValue OCTET STRING }
792 */
793 if( ( ret = asn1_get_tag( p, end, &len,
794 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000795 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000796
797 if( end != *p + len )
Paul Bakker9d781402011-05-09 16:17:09 +0000798 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +0000799 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000800
Paul Bakkerd98030e2009-05-02 15:13:40 +0000801 return( 0 );
802}
803
804/*
805 * X.509 CRL v2 extensions (no extensions parsed yet.)
806 */
807static int x509_get_crl_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000808 const unsigned char *end,
809 x509_buf *ext )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000810{
Paul Bakker23986e52011-04-24 08:57:21 +0000811 int ret;
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000812 size_t len = 0;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000813
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000814 /* Get explicit tag */
815 if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000816 {
817 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
818 return( 0 );
819
820 return( ret );
821 }
822
823 while( *p < end )
824 {
825 if( ( ret = asn1_get_tag( p, end, &len,
826 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000827 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000828
829 *p += len;
830 }
831
832 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000833 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerd98030e2009-05-02 15:13:40 +0000834 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
835
836 return( 0 );
837}
838
Paul Bakkerb5a11ab2011-10-12 09:58:41 +0000839/*
840 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
841 */
842static int x509_get_crl_entry_ext( unsigned char **p,
843 const unsigned char *end,
844 x509_buf *ext )
845{
846 int ret;
847 size_t len = 0;
848
849 /* OPTIONAL */
850 if (end <= *p)
851 return( 0 );
852
853 ext->tag = **p;
854 ext->p = *p;
855
856 /*
857 * Get CRL-entry extension sequence header
858 * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
859 */
860 if( ( ret = asn1_get_tag( p, end, &ext->len,
861 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
862 {
863 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
864 {
865 ext->p = NULL;
866 return( 0 );
867 }
868 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
869 }
870
871 end = *p + ext->len;
872
873 if( end != *p + ext->len )
874 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
875 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
876
877 while( *p < end )
878 {
879 if( ( ret = asn1_get_tag( p, end, &len,
880 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
881 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
882
883 *p += len;
884 }
885
886 if( *p != end )
887 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
888 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
889
890 return( 0 );
891}
892
Paul Bakker74111d32011-01-15 16:57:55 +0000893static int x509_get_basic_constraints( unsigned char **p,
894 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000895 int *ca_istrue,
896 int *max_pathlen )
897{
Paul Bakker23986e52011-04-24 08:57:21 +0000898 int ret;
899 size_t len;
Paul Bakker74111d32011-01-15 16:57:55 +0000900
901 /*
902 * BasicConstraints ::= SEQUENCE {
903 * cA BOOLEAN DEFAULT FALSE,
904 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
905 */
Paul Bakker3cccddb2011-01-16 21:46:31 +0000906 *ca_istrue = 0; /* DEFAULT FALSE */
Paul Bakker74111d32011-01-15 16:57:55 +0000907 *max_pathlen = 0; /* endless */
908
909 if( ( ret = asn1_get_tag( p, end, &len,
910 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000911 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000912
913 if( *p == end )
914 return 0;
915
Paul Bakker3cccddb2011-01-16 21:46:31 +0000916 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000917 {
918 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker3cccddb2011-01-16 21:46:31 +0000919 ret = asn1_get_int( p, end, ca_istrue );
Paul Bakker74111d32011-01-15 16:57:55 +0000920
921 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000922 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000923
Paul Bakker3cccddb2011-01-16 21:46:31 +0000924 if( *ca_istrue != 0 )
925 *ca_istrue = 1;
Paul Bakker74111d32011-01-15 16:57:55 +0000926 }
927
928 if( *p == end )
929 return 0;
930
931 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000932 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000933
934 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000935 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000936 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
937
938 (*max_pathlen)++;
939
Paul Bakker74111d32011-01-15 16:57:55 +0000940 return 0;
941}
942
943static int x509_get_ns_cert_type( unsigned char **p,
944 const unsigned char *end,
945 unsigned char *ns_cert_type)
946{
947 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000948 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000949
950 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000951 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000952
953 if( bs.len != 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000954 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000955 POLARSSL_ERR_ASN1_INVALID_LENGTH );
956
957 /* Get actual bitstring */
958 *ns_cert_type = *bs.p;
959 return 0;
960}
961
962static int x509_get_key_usage( unsigned char **p,
963 const unsigned char *end,
964 unsigned char *key_usage)
965{
966 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000967 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000968
969 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000970 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000971
Paul Bakker94a67962012-08-23 13:03:52 +0000972 if( bs.len < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000973 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000974 POLARSSL_ERR_ASN1_INVALID_LENGTH );
975
976 /* Get actual bitstring */
977 *key_usage = *bs.p;
978 return 0;
979}
980
Paul Bakkerd98030e2009-05-02 15:13:40 +0000981/*
Paul Bakker74111d32011-01-15 16:57:55 +0000982 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
983 *
984 * KeyPurposeId ::= OBJECT IDENTIFIER
985 */
986static int x509_get_ext_key_usage( unsigned char **p,
987 const unsigned char *end,
988 x509_sequence *ext_key_usage)
989{
990 int ret;
991
992 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000993 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000994
995 /* Sequence length must be >= 1 */
996 if( ext_key_usage->buf.p == NULL )
Paul Bakker9d781402011-05-09 16:17:09 +0000997 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000998 POLARSSL_ERR_ASN1_INVALID_LENGTH );
999
1000 return 0;
1001}
1002
1003/*
Paul Bakkera8cd2392012-02-11 16:09:32 +00001004 * SubjectAltName ::= GeneralNames
1005 *
1006 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
1007 *
1008 * GeneralName ::= CHOICE {
1009 * otherName [0] OtherName,
1010 * rfc822Name [1] IA5String,
1011 * dNSName [2] IA5String,
1012 * x400Address [3] ORAddress,
1013 * directoryName [4] Name,
1014 * ediPartyName [5] EDIPartyName,
1015 * uniformResourceIdentifier [6] IA5String,
1016 * iPAddress [7] OCTET STRING,
1017 * registeredID [8] OBJECT IDENTIFIER }
1018 *
1019 * OtherName ::= SEQUENCE {
1020 * type-id OBJECT IDENTIFIER,
1021 * value [0] EXPLICIT ANY DEFINED BY type-id }
1022 *
1023 * EDIPartyName ::= SEQUENCE {
1024 * nameAssigner [0] DirectoryString OPTIONAL,
1025 * partyName [1] DirectoryString }
1026 *
1027 * NOTE: PolarSSL only parses and uses dNSName at this point.
1028 */
1029static int x509_get_subject_alt_name( unsigned char **p,
1030 const unsigned char *end,
1031 x509_sequence *subject_alt_name )
1032{
1033 int ret;
1034 size_t len, tag_len;
1035 asn1_buf *buf;
1036 unsigned char tag;
1037 asn1_sequence *cur = subject_alt_name;
1038
1039 /* Get main sequence tag */
1040 if( ( ret = asn1_get_tag( p, end, &len,
1041 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1042 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
1043
1044 if( *p + len != end )
1045 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
1046 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1047
1048 while( *p < end )
1049 {
1050 if( ( end - *p ) < 1 )
1051 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
1052 POLARSSL_ERR_ASN1_OUT_OF_DATA );
1053
1054 tag = **p;
1055 (*p)++;
1056 if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 )
1057 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
1058
1059 if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC )
1060 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
1061 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
1062
1063 if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) )
1064 {
1065 *p += tag_len;
1066 continue;
1067 }
1068
1069 buf = &(cur->buf);
1070 buf->tag = tag;
1071 buf->p = *p;
1072 buf->len = tag_len;
1073 *p += buf->len;
1074
1075 /* Allocate and assign next pointer */
1076 if (*p < end)
1077 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001078 cur->next = (asn1_sequence *) polarssl_malloc(
Paul Bakkera8cd2392012-02-11 16:09:32 +00001079 sizeof( asn1_sequence ) );
1080
1081 if( cur->next == NULL )
1082 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
1083 POLARSSL_ERR_ASN1_MALLOC_FAILED );
1084
Paul Bakker535e97d2012-08-23 10:49:55 +00001085 memset( cur->next, 0, sizeof( asn1_sequence ) );
Paul Bakkera8cd2392012-02-11 16:09:32 +00001086 cur = cur->next;
1087 }
1088 }
1089
1090 /* Set final sequence entry's next pointer to NULL */
1091 cur->next = NULL;
1092
1093 if( *p != end )
1094 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
1095 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1096
1097 return( 0 );
1098}
1099
1100/*
Paul Bakker74111d32011-01-15 16:57:55 +00001101 * X.509 v3 extensions
1102 *
1103 * TODO: Perform all of the basic constraints tests required by the RFC
1104 * TODO: Set values for undetected extensions to a sane default?
1105 *
Paul Bakkerd98030e2009-05-02 15:13:40 +00001106 */
1107static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001108 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +00001109 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001110{
Paul Bakker23986e52011-04-24 08:57:21 +00001111 int ret;
1112 size_t len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001113 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001114
Paul Bakkerfbc09f32011-10-12 09:56:41 +00001115 if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001116 {
1117 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
1118 return( 0 );
1119
1120 return( ret );
1121 }
1122
Paul Bakker5121ce52009-01-03 21:22:43 +00001123 while( *p < end )
1124 {
Paul Bakker74111d32011-01-15 16:57:55 +00001125 /*
1126 * Extension ::= SEQUENCE {
1127 * extnID OBJECT IDENTIFIER,
1128 * critical BOOLEAN DEFAULT FALSE,
1129 * extnValue OCTET STRING }
1130 */
1131 x509_buf extn_oid = {0, 0, NULL};
1132 int is_critical = 0; /* DEFAULT FALSE */
Paul Bakkerc70b9822013-04-07 22:00:46 +02001133 int ext_type = 0;
Paul Bakker74111d32011-01-15 16:57:55 +00001134
Paul Bakker5121ce52009-01-03 21:22:43 +00001135 if( ( ret = asn1_get_tag( p, end, &len,
1136 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +00001137 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001138
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001139 end_ext_data = *p + len;
1140
Paul Bakker74111d32011-01-15 16:57:55 +00001141 /* Get extension ID */
1142 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +00001143
Paul Bakker74111d32011-01-15 16:57:55 +00001144 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +00001145 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001146
Paul Bakker74111d32011-01-15 16:57:55 +00001147 extn_oid.p = *p;
1148 *p += extn_oid.len;
1149
1150 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +00001151 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +00001152 POLARSSL_ERR_ASN1_OUT_OF_DATA );
1153
1154 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001155 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +00001156 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
Paul Bakker9d781402011-05-09 16:17:09 +00001157 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001158
Paul Bakker74111d32011-01-15 16:57:55 +00001159 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001160 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +00001161 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +00001162 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001163
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001164 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +00001165
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001166 if( end_ext_octet != end_ext_data )
Paul Bakker9d781402011-05-09 16:17:09 +00001167 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001168 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001169
Paul Bakker74111d32011-01-15 16:57:55 +00001170 /*
1171 * Detect supported extensions
1172 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02001173 ret = oid_get_x509_ext_type( &extn_oid, &ext_type );
1174
1175 if( ret != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +00001176 {
1177 /* No parser found, skip extension */
1178 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +00001179
Paul Bakker5c721f92011-07-27 16:51:09 +00001180#if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
Paul Bakker74111d32011-01-15 16:57:55 +00001181 if( is_critical )
1182 {
1183 /* Data is marked as critical: fail */
Paul Bakker9d781402011-05-09 16:17:09 +00001184 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +00001185 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
1186 }
Paul Bakker5c721f92011-07-27 16:51:09 +00001187#endif
Paul Bakkerc70b9822013-04-07 22:00:46 +02001188 continue;
1189 }
1190
1191 crt->ext_types |= ext_type;
1192
1193 switch( ext_type )
1194 {
1195 case EXT_BASIC_CONSTRAINTS:
1196 /* Parse basic constraints */
1197 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
1198 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
1199 return ( ret );
1200 break;
1201
1202 case EXT_KEY_USAGE:
1203 /* Parse key usage */
1204 if( ( ret = x509_get_key_usage( p, end_ext_octet,
1205 &crt->key_usage ) ) != 0 )
1206 return ( ret );
1207 break;
1208
1209 case EXT_EXTENDED_KEY_USAGE:
1210 /* Parse extended key usage */
1211 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
1212 &crt->ext_key_usage ) ) != 0 )
1213 return ( ret );
1214 break;
1215
1216 case EXT_SUBJECT_ALT_NAME:
1217 /* Parse subject alt name */
1218 if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
1219 &crt->subject_alt_names ) ) != 0 )
1220 return ( ret );
1221 break;
1222
1223 case EXT_NS_CERT_TYPE:
1224 /* Parse netscape certificate type */
1225 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
1226 &crt->ns_cert_type ) ) != 0 )
1227 return ( ret );
1228 break;
1229
1230 default:
1231 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker74111d32011-01-15 16:57:55 +00001232 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001233 }
1234
1235 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +00001236 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +00001237 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001238
Paul Bakker5121ce52009-01-03 21:22:43 +00001239 return( 0 );
1240}
1241
1242/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001243 * X.509 CRL Entries
1244 */
1245static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001246 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001247 x509_crl_entry *entry )
1248{
Paul Bakker23986e52011-04-24 08:57:21 +00001249 int ret;
1250 size_t entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001251 x509_crl_entry *cur_entry = entry;
1252
1253 if( *p == end )
1254 return( 0 );
1255
Paul Bakker9be19372009-07-27 20:21:53 +00001256 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001257 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1258 {
1259 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
1260 return( 0 );
1261
1262 return( ret );
1263 }
1264
Paul Bakker9be19372009-07-27 20:21:53 +00001265 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001266
1267 while( *p < end )
1268 {
Paul Bakker23986e52011-04-24 08:57:21 +00001269 size_t len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001270 const unsigned char *end2;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001271
1272 if( ( ret = asn1_get_tag( p, end, &len2,
1273 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1274 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001275 return( ret );
1276 }
1277
Paul Bakker9be19372009-07-27 20:21:53 +00001278 cur_entry->raw.tag = **p;
1279 cur_entry->raw.p = *p;
1280 cur_entry->raw.len = len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001281 end2 = *p + len2;
Paul Bakker9be19372009-07-27 20:21:53 +00001282
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001283 if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001284 return( ret );
1285
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001286 if( ( ret = x509_get_time( p, end2, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001287 return( ret );
1288
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001289 if( ( ret = x509_get_crl_entry_ext( p, end2, &cur_entry->entry_ext ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001290 return( ret );
1291
Paul Bakker74111d32011-01-15 16:57:55 +00001292 if ( *p < end )
1293 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001294 cur_entry->next = polarssl_malloc( sizeof( x509_crl_entry ) );
Paul Bakkerb15b8512012-01-13 13:44:06 +00001295
1296 if( cur_entry->next == NULL )
1297 return( POLARSSL_ERR_X509_MALLOC_FAILED );
1298
Paul Bakkerd98030e2009-05-02 15:13:40 +00001299 cur_entry = cur_entry->next;
1300 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
1301 }
1302 }
1303
1304 return( 0 );
1305}
1306
Paul Bakkerc70b9822013-04-07 22:00:46 +02001307static int x509_get_sig_alg( const x509_buf *sig_oid, md_type_t *md_alg,
1308 pk_type_t *pk_alg )
Paul Bakker27d66162010-03-17 06:56:01 +00001309{
Paul Bakkerc70b9822013-04-07 22:00:46 +02001310 int ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg );
Paul Bakker27d66162010-03-17 06:56:01 +00001311
Paul Bakkerc70b9822013-04-07 22:00:46 +02001312 if( ret != 0 )
1313 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG + ret );
Paul Bakker27d66162010-03-17 06:56:01 +00001314
Paul Bakkerc70b9822013-04-07 22:00:46 +02001315 return( 0 );
Paul Bakker27d66162010-03-17 06:56:01 +00001316}
1317
Paul Bakkerd98030e2009-05-02 15:13:40 +00001318/*
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001319 * Parse and fill a single X.509 certificate in DER format
Paul Bakker5121ce52009-01-03 21:22:43 +00001320 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02001321static int x509parse_crt_der_core( x509_cert *crt, const unsigned char *buf,
1322 size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001323{
Paul Bakker23986e52011-04-24 08:57:21 +00001324 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001325 size_t len;
Paul Bakkerb00ca422012-09-25 12:10:00 +00001326 unsigned char *p, *end, *crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001327
Paul Bakker320a4b52009-03-28 18:52:39 +00001328 /*
1329 * Check for valid input
1330 */
1331 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001332 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker320a4b52009-03-28 18:52:39 +00001333
Paul Bakker6e339b52013-07-03 13:37:05 +02001334 p = (unsigned char *) polarssl_malloc( len = buflen );
Paul Bakker96743fc2011-02-12 14:30:57 +00001335
1336 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001337 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001338
1339 memcpy( p, buf, buflen );
1340
1341 buflen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001342
1343 crt->raw.p = p;
1344 crt->raw.len = len;
1345 end = p + len;
1346
1347 /*
1348 * Certificate ::= SEQUENCE {
1349 * tbsCertificate TBSCertificate,
1350 * signatureAlgorithm AlgorithmIdentifier,
1351 * signatureValue BIT STRING }
1352 */
1353 if( ( ret = asn1_get_tag( &p, end, &len,
1354 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1355 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001356 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001357 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001358 }
1359
Paul Bakkerb00ca422012-09-25 12:10:00 +00001360 if( len > (size_t) ( end - p ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001361 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001362 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001363 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001364 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001365 }
Paul Bakkerb00ca422012-09-25 12:10:00 +00001366 crt_end = p + len;
Paul Bakker42c65812013-06-24 19:21:59 +02001367
Paul Bakker5121ce52009-01-03 21:22:43 +00001368 /*
1369 * TBSCertificate ::= SEQUENCE {
1370 */
1371 crt->tbs.p = p;
1372
1373 if( ( ret = asn1_get_tag( &p, end, &len,
1374 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1375 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001376 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001377 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001378 }
1379
1380 end = p + len;
1381 crt->tbs.len = end - crt->tbs.p;
1382
1383 /*
1384 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1385 *
1386 * CertificateSerialNumber ::= INTEGER
1387 *
1388 * signature AlgorithmIdentifier
1389 */
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +02001390 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1391 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1392 ( ret = x509_get_alg( &p, end, &crt->sig_oid1, NULL ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001393 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001394 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001395 return( ret );
1396 }
1397
1398 crt->version++;
1399
1400 if( crt->version > 3 )
1401 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001402 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001403 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001404 }
1405
Paul Bakkerc70b9822013-04-07 22:00:46 +02001406 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_md,
1407 &crt->sig_pk ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001408 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001409 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001410 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001411 }
1412
1413 /*
1414 * issuer Name
1415 */
1416 crt->issuer_raw.p = p;
1417
1418 if( ( ret = asn1_get_tag( &p, end, &len,
1419 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1420 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001421 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001422 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001423 }
1424
1425 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1426 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001427 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001428 return( ret );
1429 }
1430
1431 crt->issuer_raw.len = p - crt->issuer_raw.p;
1432
1433 /*
1434 * Validity ::= SEQUENCE {
1435 * notBefore Time,
1436 * notAfter Time }
1437 *
1438 */
1439 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1440 &crt->valid_to ) ) != 0 )
1441 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001442 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001443 return( ret );
1444 }
1445
1446 /*
1447 * subject Name
1448 */
1449 crt->subject_raw.p = p;
1450
1451 if( ( ret = asn1_get_tag( &p, end, &len,
1452 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1453 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001454 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001455 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001456 }
1457
Paul Bakkercefb3962012-06-27 11:51:09 +00001458 if( len && ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001459 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001460 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001461 return( ret );
1462 }
1463
1464 crt->subject_raw.len = p - crt->subject_raw.p;
1465
1466 /*
Manuel Pégourié-Gonnard20c12f62013-07-09 12:13:24 +02001467 * SubjectPublicKeyInfo
Paul Bakker5121ce52009-01-03 21:22:43 +00001468 */
Manuel Pégourié-Gonnard094ad9e2013-07-09 12:32:51 +02001469 if( ( ret = x509_get_pubkey_rsa( &p, end, &crt->rsa ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001470 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001471 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001472 return( ret );
1473 }
1474
Paul Bakker5121ce52009-01-03 21:22:43 +00001475 /*
1476 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1477 * -- If present, version shall be v2 or v3
1478 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1479 * -- If present, version shall be v2 or v3
1480 * extensions [3] EXPLICIT Extensions OPTIONAL
1481 * -- If present, version shall be v3
1482 */
1483 if( crt->version == 2 || crt->version == 3 )
1484 {
1485 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1486 if( ret != 0 )
1487 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001488 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001489 return( ret );
1490 }
1491 }
1492
1493 if( crt->version == 2 || crt->version == 3 )
1494 {
1495 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1496 if( ret != 0 )
1497 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001498 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001499 return( ret );
1500 }
1501 }
1502
1503 if( crt->version == 3 )
1504 {
Paul Bakker74111d32011-01-15 16:57:55 +00001505 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001506 if( ret != 0 )
1507 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001508 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001509 return( ret );
1510 }
1511 }
1512
1513 if( p != end )
1514 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001515 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001516 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001517 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001518 }
1519
Paul Bakkerb00ca422012-09-25 12:10:00 +00001520 end = crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001521
1522 /*
Manuel Pégourié-Gonnard20c12f62013-07-09 12:13:24 +02001523 * }
1524 * -- end of TBSCertificate
1525 *
Paul Bakker5121ce52009-01-03 21:22:43 +00001526 * signatureAlgorithm AlgorithmIdentifier,
1527 * signatureValue BIT STRING
1528 */
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +02001529 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2, NULL ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001530 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001531 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001532 return( ret );
1533 }
1534
Paul Bakker535e97d2012-08-23 10:49:55 +00001535 if( crt->sig_oid1.len != crt->sig_oid2.len ||
1536 memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001537 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001538 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001539 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001540 }
1541
1542 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1543 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001544 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001545 return( ret );
1546 }
1547
1548 if( p != end )
1549 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001550 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001551 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001552 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001553 }
1554
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001555 return( 0 );
1556}
1557
1558/*
Paul Bakker42c65812013-06-24 19:21:59 +02001559 * Parse one X.509 certificate in DER format from a buffer and add them to a
1560 * chained list
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001561 */
Paul Bakker42c65812013-06-24 19:21:59 +02001562int x509parse_crt_der( x509_cert *chain, const unsigned char *buf, size_t buflen )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001563{
Paul Bakker42c65812013-06-24 19:21:59 +02001564 int ret;
1565 x509_cert *crt = chain, *prev = NULL;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001566
1567 /*
1568 * Check for valid input
1569 */
1570 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001571 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001572
1573 while( crt->version != 0 && crt->next != NULL )
1574 {
1575 prev = crt;
1576 crt = crt->next;
1577 }
1578
1579 /*
1580 * Add new certificate on the end of the chain if needed.
1581 */
1582 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001583 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001584 crt->next = (x509_cert *) polarssl_malloc( sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001585
Paul Bakker7d06ad22009-05-02 15:53:56 +00001586 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001587 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker320a4b52009-03-28 18:52:39 +00001588
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001589 prev = crt;
Paul Bakker7d06ad22009-05-02 15:53:56 +00001590 crt = crt->next;
1591 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001592 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001593
Paul Bakker42c65812013-06-24 19:21:59 +02001594 if( ( ret = x509parse_crt_der_core( crt, buf, buflen ) ) != 0 )
1595 {
1596 if( prev )
1597 prev->next = NULL;
1598
1599 if( crt != chain )
Paul Bakker6e339b52013-07-03 13:37:05 +02001600 polarssl_free( crt );
Paul Bakker42c65812013-06-24 19:21:59 +02001601
1602 return( ret );
1603 }
1604
1605 return( 0 );
1606}
1607
1608/*
1609 * Parse one or more PEM certificates from a buffer and add them to the chained list
1610 */
1611int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
1612{
1613 int ret, success = 0, first_error = 0, total_failed = 0;
1614 int buf_format = X509_FORMAT_DER;
1615
1616 /*
1617 * Check for valid input
1618 */
1619 if( chain == NULL || buf == NULL )
1620 return( POLARSSL_ERR_X509_INVALID_INPUT );
1621
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001622 /*
1623 * Determine buffer content. Buffer contains either one DER certificate or
1624 * one or more PEM certificates.
1625 */
1626#if defined(POLARSSL_PEM_C)
Paul Bakker3c2122f2013-06-24 19:03:14 +02001627 if( strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001628 buf_format = X509_FORMAT_PEM;
1629#endif
1630
1631 if( buf_format == X509_FORMAT_DER )
Paul Bakker42c65812013-06-24 19:21:59 +02001632 return x509parse_crt_der( chain, buf, buflen );
1633
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001634#if defined(POLARSSL_PEM_C)
1635 if( buf_format == X509_FORMAT_PEM )
1636 {
1637 pem_context pem;
1638
1639 while( buflen > 0 )
1640 {
1641 size_t use_len;
1642 pem_init( &pem );
1643
1644 ret = pem_read_buffer( &pem,
1645 "-----BEGIN CERTIFICATE-----",
1646 "-----END CERTIFICATE-----",
1647 buf, NULL, 0, &use_len );
1648
1649 if( ret == 0 )
1650 {
1651 /*
1652 * Was PEM encoded
1653 */
1654 buflen -= use_len;
1655 buf += use_len;
1656 }
Paul Bakker5ed3b342013-06-24 19:05:46 +02001657 else if( ret == POLARSSL_ERR_PEM_BAD_INPUT_DATA )
1658 {
1659 return( ret );
1660 }
Paul Bakker00b28602013-06-24 13:02:41 +02001661 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001662 {
1663 pem_free( &pem );
1664
Paul Bakker5ed3b342013-06-24 19:05:46 +02001665 /*
1666 * PEM header and footer were found
1667 */
1668 buflen -= use_len;
1669 buf += use_len;
1670
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001671 if( first_error == 0 )
1672 first_error = ret;
1673
1674 continue;
1675 }
1676 else
1677 break;
1678
Paul Bakker42c65812013-06-24 19:21:59 +02001679 ret = x509parse_crt_der( chain, pem.buf, pem.buflen );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001680
1681 pem_free( &pem );
1682
1683 if( ret != 0 )
1684 {
1685 /*
Paul Bakker42c65812013-06-24 19:21:59 +02001686 * Quit parsing on a memory error
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001687 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001688 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001689 return( ret );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001690
1691 if( first_error == 0 )
1692 first_error = ret;
1693
Paul Bakker42c65812013-06-24 19:21:59 +02001694 total_failed++;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001695 continue;
1696 }
1697
1698 success = 1;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001699 }
1700 }
1701#endif
1702
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001703 if( success )
Paul Bakker69e095c2011-12-10 21:55:01 +00001704 return( total_failed );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001705 else if( first_error )
1706 return( first_error );
1707 else
1708 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001709}
1710
1711/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001712 * Parse one or more CRLs and add them to the chained list
1713 */
Paul Bakker23986e52011-04-24 08:57:21 +00001714int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001715{
Paul Bakker23986e52011-04-24 08:57:21 +00001716 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001717 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001718 unsigned char *p, *end;
1719 x509_crl *crl;
Paul Bakker96743fc2011-02-12 14:30:57 +00001720#if defined(POLARSSL_PEM_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00001721 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001722 pem_context pem;
1723#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001724
1725 crl = chain;
1726
1727 /*
1728 * Check for valid input
1729 */
1730 if( crl == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001731 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001732
1733 while( crl->version != 0 && crl->next != NULL )
1734 crl = crl->next;
1735
1736 /*
1737 * Add new CRL on the end of the chain if needed.
1738 */
1739 if ( crl->version != 0 && crl->next == NULL)
1740 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001741 crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001742
Paul Bakker7d06ad22009-05-02 15:53:56 +00001743 if( crl->next == NULL )
1744 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001745 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001746 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001747 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001748
Paul Bakker7d06ad22009-05-02 15:53:56 +00001749 crl = crl->next;
1750 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001751 }
1752
Paul Bakker96743fc2011-02-12 14:30:57 +00001753#if defined(POLARSSL_PEM_C)
1754 pem_init( &pem );
1755 ret = pem_read_buffer( &pem,
1756 "-----BEGIN X509 CRL-----",
1757 "-----END X509 CRL-----",
1758 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001759
Paul Bakker96743fc2011-02-12 14:30:57 +00001760 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001761 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001762 /*
1763 * Was PEM encoded
1764 */
1765 buflen -= use_len;
1766 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001767
1768 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001769 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001770 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001771 p = pem.buf;
1772 pem.buf = NULL;
1773 len = pem.buflen;
1774 pem_free( &pem );
1775 }
Paul Bakker00b28602013-06-24 13:02:41 +02001776 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker96743fc2011-02-12 14:30:57 +00001777 {
1778 pem_free( &pem );
1779 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001780 }
1781 else
1782 {
1783 /*
1784 * nope, copy the raw DER data
1785 */
Paul Bakker6e339b52013-07-03 13:37:05 +02001786 p = (unsigned char *) polarssl_malloc( len = buflen );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001787
1788 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001789 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001790
1791 memcpy( p, buf, buflen );
1792
1793 buflen = 0;
1794 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001795#else
Paul Bakker6e339b52013-07-03 13:37:05 +02001796 p = (unsigned char *) polarssl_malloc( len = buflen );
Paul Bakker96743fc2011-02-12 14:30:57 +00001797
1798 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001799 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001800
1801 memcpy( p, buf, buflen );
1802
1803 buflen = 0;
1804#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001805
1806 crl->raw.p = p;
1807 crl->raw.len = len;
1808 end = p + len;
1809
1810 /*
1811 * CertificateList ::= SEQUENCE {
1812 * tbsCertList TBSCertList,
1813 * signatureAlgorithm AlgorithmIdentifier,
1814 * signatureValue BIT STRING }
1815 */
1816 if( ( ret = asn1_get_tag( &p, end, &len,
1817 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1818 {
1819 x509_crl_free( crl );
1820 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1821 }
1822
Paul Bakker23986e52011-04-24 08:57:21 +00001823 if( len != (size_t) ( end - p ) )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001824 {
1825 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001826 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001827 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1828 }
1829
1830 /*
1831 * TBSCertList ::= SEQUENCE {
1832 */
1833 crl->tbs.p = p;
1834
1835 if( ( ret = asn1_get_tag( &p, end, &len,
1836 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1837 {
1838 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001839 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001840 }
1841
1842 end = p + len;
1843 crl->tbs.len = end - crl->tbs.p;
1844
1845 /*
1846 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1847 * -- if present, MUST be v2
1848 *
1849 * signature AlgorithmIdentifier
1850 */
Paul Bakker3329d1f2011-10-12 09:55:01 +00001851 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +02001852 ( ret = x509_get_alg( &p, end, &crl->sig_oid1, NULL ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001853 {
1854 x509_crl_free( crl );
1855 return( ret );
1856 }
1857
1858 crl->version++;
1859
1860 if( crl->version > 2 )
1861 {
1862 x509_crl_free( crl );
1863 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1864 }
1865
Paul Bakkerc70b9822013-04-07 22:00:46 +02001866 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_md,
1867 &crl->sig_pk ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001868 {
1869 x509_crl_free( crl );
1870 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1871 }
1872
1873 /*
1874 * issuer Name
1875 */
1876 crl->issuer_raw.p = p;
1877
1878 if( ( ret = asn1_get_tag( &p, end, &len,
1879 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1880 {
1881 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001882 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001883 }
1884
1885 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1886 {
1887 x509_crl_free( crl );
1888 return( ret );
1889 }
1890
1891 crl->issuer_raw.len = p - crl->issuer_raw.p;
1892
1893 /*
1894 * thisUpdate Time
1895 * nextUpdate Time OPTIONAL
1896 */
Paul Bakker91200182010-02-18 21:26:15 +00001897 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001898 {
1899 x509_crl_free( crl );
1900 return( ret );
1901 }
1902
Paul Bakker91200182010-02-18 21:26:15 +00001903 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001904 {
Paul Bakker9d781402011-05-09 16:17:09 +00001905 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001906 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker9d781402011-05-09 16:17:09 +00001907 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001908 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001909 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001910 x509_crl_free( crl );
1911 return( ret );
1912 }
1913 }
1914
1915 /*
1916 * revokedCertificates SEQUENCE OF SEQUENCE {
1917 * userCertificate CertificateSerialNumber,
1918 * revocationDate Time,
1919 * crlEntryExtensions Extensions OPTIONAL
1920 * -- if present, MUST be v2
1921 * } OPTIONAL
1922 */
1923 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1924 {
1925 x509_crl_free( crl );
1926 return( ret );
1927 }
1928
1929 /*
1930 * crlExtensions EXPLICIT Extensions OPTIONAL
1931 * -- if present, MUST be v2
1932 */
1933 if( crl->version == 2 )
1934 {
1935 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1936
1937 if( ret != 0 )
1938 {
1939 x509_crl_free( crl );
1940 return( ret );
1941 }
1942 }
1943
1944 if( p != end )
1945 {
1946 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001947 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001948 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1949 }
1950
1951 end = crl->raw.p + crl->raw.len;
1952
1953 /*
1954 * signatureAlgorithm AlgorithmIdentifier,
1955 * signatureValue BIT STRING
1956 */
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +02001957 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2, NULL ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001958 {
1959 x509_crl_free( crl );
1960 return( ret );
1961 }
1962
Paul Bakker535e97d2012-08-23 10:49:55 +00001963 if( crl->sig_oid1.len != crl->sig_oid2.len ||
1964 memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001965 {
1966 x509_crl_free( crl );
1967 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1968 }
1969
1970 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1971 {
1972 x509_crl_free( crl );
1973 return( ret );
1974 }
1975
1976 if( p != end )
1977 {
1978 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001979 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001980 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1981 }
1982
1983 if( buflen > 0 )
1984 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001985 crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001986
Paul Bakker7d06ad22009-05-02 15:53:56 +00001987 if( crl->next == NULL )
1988 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001989 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001990 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001991 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001992
Paul Bakker7d06ad22009-05-02 15:53:56 +00001993 crl = crl->next;
1994 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001995
1996 return( x509parse_crl( crl, buf, buflen ) );
1997 }
1998
1999 return( 0 );
2000}
2001
Paul Bakker335db3f2011-04-25 15:28:35 +00002002#if defined(POLARSSL_FS_IO)
Paul Bakkerd98030e2009-05-02 15:13:40 +00002003/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00002004 * Load all data from a file into a given buffer.
2005 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02002006static int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00002007{
Paul Bakkerd98030e2009-05-02 15:13:40 +00002008 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00002009
Paul Bakkerd98030e2009-05-02 15:13:40 +00002010 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00002011 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker2b245eb2009-04-19 18:44:26 +00002012
Paul Bakkerd98030e2009-05-02 15:13:40 +00002013 fseek( f, 0, SEEK_END );
2014 *n = (size_t) ftell( f );
2015 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00002016
Paul Bakker6e339b52013-07-03 13:37:05 +02002017 if( ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
Paul Bakkerf6a19bd2013-05-14 13:26:51 +02002018 {
2019 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +00002020 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerf6a19bd2013-05-14 13:26:51 +02002021 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00002022
Paul Bakkerd98030e2009-05-02 15:13:40 +00002023 if( fread( *buf, 1, *n, f ) != *n )
2024 {
2025 fclose( f );
Paul Bakker6e339b52013-07-03 13:37:05 +02002026 polarssl_free( *buf );
Paul Bakker69e095c2011-12-10 21:55:01 +00002027 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002028 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00002029
Paul Bakkerd98030e2009-05-02 15:13:40 +00002030 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00002031
Paul Bakkerd98030e2009-05-02 15:13:40 +00002032 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00002033
Paul Bakkerd98030e2009-05-02 15:13:40 +00002034 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00002035}
2036
2037/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002038 * Load one or more certificates and add them to the chained list
2039 */
Paul Bakker69e095c2011-12-10 21:55:01 +00002040int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00002041{
2042 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002043 size_t n;
2044 unsigned char *buf;
2045
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02002046 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00002047 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002048
Paul Bakker69e095c2011-12-10 21:55:01 +00002049 ret = x509parse_crt( chain, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002050
2051 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02002052 polarssl_free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00002053
2054 return( ret );
2055}
2056
Paul Bakker8d914582012-06-04 12:46:42 +00002057int x509parse_crtpath( x509_cert *chain, const char *path )
2058{
2059 int ret = 0;
2060#if defined(_WIN32)
Paul Bakker3338b792012-10-01 21:13:10 +00002061 int w_ret;
2062 WCHAR szDir[MAX_PATH];
2063 char filename[MAX_PATH];
2064 char *p;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002065 int len = strlen( path );
Paul Bakker3338b792012-10-01 21:13:10 +00002066
Paul Bakker97872ac2012-11-02 12:53:26 +00002067 WIN32_FIND_DATAW file_data;
Paul Bakker8d914582012-06-04 12:46:42 +00002068 HANDLE hFind;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002069
2070 if( len > MAX_PATH - 3 )
2071 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker8d914582012-06-04 12:46:42 +00002072
Paul Bakker3338b792012-10-01 21:13:10 +00002073 memset( szDir, 0, sizeof(szDir) );
2074 memset( filename, 0, MAX_PATH );
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002075 memcpy( filename, path, len );
2076 filename[len++] = '\\';
2077 p = filename + len;
2078 filename[len++] = '*';
Paul Bakker3338b792012-10-01 21:13:10 +00002079
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002080 w_ret = MultiByteToWideChar( CP_ACP, 0, path, len, szDir, MAX_PATH - 3 );
Paul Bakker8d914582012-06-04 12:46:42 +00002081
Paul Bakker97872ac2012-11-02 12:53:26 +00002082 hFind = FindFirstFileW( szDir, &file_data );
Paul Bakker8d914582012-06-04 12:46:42 +00002083 if (hFind == INVALID_HANDLE_VALUE)
2084 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
2085
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002086 len = MAX_PATH - len;
Paul Bakker8d914582012-06-04 12:46:42 +00002087 do
2088 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002089 memset( p, 0, len );
Paul Bakker3338b792012-10-01 21:13:10 +00002090
Paul Bakkere4791f32012-06-04 21:29:15 +00002091 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
Paul Bakker8d914582012-06-04 12:46:42 +00002092 continue;
2093
Paul Bakker3338b792012-10-01 21:13:10 +00002094 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
2095 lstrlenW(file_data.cFileName),
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002096 p, len - 1,
2097 NULL, NULL );
Paul Bakker8d914582012-06-04 12:46:42 +00002098
Paul Bakker3338b792012-10-01 21:13:10 +00002099 w_ret = x509parse_crtfile( chain, filename );
2100 if( w_ret < 0 )
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002101 ret++;
2102 else
2103 ret += w_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00002104 }
Paul Bakker97872ac2012-11-02 12:53:26 +00002105 while( FindNextFileW( hFind, &file_data ) != 0 );
Paul Bakker8d914582012-06-04 12:46:42 +00002106
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002107 if (GetLastError() != ERROR_NO_MORE_FILES)
2108 ret = POLARSSL_ERR_X509_FILE_IO_ERROR;
Paul Bakker8d914582012-06-04 12:46:42 +00002109
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002110cleanup:
Paul Bakker8d914582012-06-04 12:46:42 +00002111 FindClose( hFind );
2112#else
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002113 int t_ret, i;
2114 struct stat sb;
2115 struct dirent entry, *result = NULL;
Paul Bakker8d914582012-06-04 12:46:42 +00002116 char entry_name[255];
2117 DIR *dir = opendir( path );
2118
2119 if( dir == NULL)
2120 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
2121
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002122 while( ( t_ret = readdir_r( dir, &entry, &result ) ) == 0 )
Paul Bakker8d914582012-06-04 12:46:42 +00002123 {
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002124 if( result == NULL )
2125 break;
2126
2127 snprintf( entry_name, sizeof(entry_name), "%s/%s", path, entry.d_name );
2128
2129 i = stat( entry_name, &sb );
2130
2131 if( i == -1 )
2132 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
2133
2134 if( !S_ISREG( sb.st_mode ) )
Paul Bakker8d914582012-06-04 12:46:42 +00002135 continue;
2136
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002137 // Ignore parse errors
2138 //
Paul Bakker8d914582012-06-04 12:46:42 +00002139 t_ret = x509parse_crtfile( chain, entry_name );
2140 if( t_ret < 0 )
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002141 ret++;
2142 else
2143 ret += t_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00002144 }
2145 closedir( dir );
2146#endif
2147
2148 return( ret );
2149}
2150
Paul Bakkerd98030e2009-05-02 15:13:40 +00002151/*
2152 * Load one or more CRLs and add them to the chained list
2153 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002154int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002155{
2156 int ret;
2157 size_t n;
2158 unsigned char *buf;
2159
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02002160 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00002161 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002162
Paul Bakker27fdf462011-06-09 13:55:13 +00002163 ret = x509parse_crl( chain, buf, n );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002164
2165 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02002166 polarssl_free( buf );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002167
2168 return( ret );
2169}
2170
Paul Bakker5121ce52009-01-03 21:22:43 +00002171/*
Paul Bakker335db3f2011-04-25 15:28:35 +00002172 * Load and parse a private RSA key
2173 */
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002174int x509parse_keyfile_rsa( rsa_context *rsa, const char *path, const char *pwd )
Paul Bakker335db3f2011-04-25 15:28:35 +00002175{
2176 int ret;
2177 size_t n;
2178 unsigned char *buf;
2179
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02002180 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00002181 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002182
2183 if( pwd == NULL )
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002184 ret = x509parse_key_rsa( rsa, buf, n, NULL, 0 );
Paul Bakker335db3f2011-04-25 15:28:35 +00002185 else
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002186 ret = x509parse_key_rsa( rsa, buf, n,
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02002187 (const unsigned char *) pwd, strlen( pwd ) );
Paul Bakker335db3f2011-04-25 15:28:35 +00002188
2189 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02002190 polarssl_free( buf );
Paul Bakker335db3f2011-04-25 15:28:35 +00002191
2192 return( ret );
2193}
2194
2195/*
2196 * Load and parse a public RSA key
2197 */
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002198int x509parse_public_keyfile_rsa( rsa_context *rsa, const char *path )
Paul Bakker335db3f2011-04-25 15:28:35 +00002199{
2200 int ret;
2201 size_t n;
2202 unsigned char *buf;
2203
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02002204 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00002205 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002206
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002207 ret = x509parse_public_key_rsa( rsa, buf, n );
Paul Bakker335db3f2011-04-25 15:28:35 +00002208
2209 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02002210 polarssl_free( buf );
Paul Bakker335db3f2011-04-25 15:28:35 +00002211
2212 return( ret );
2213}
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002214
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002215/*
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002216 * Load and parse a private key
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002217 */
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002218int x509parse_keyfile( pk_context *ctx,
2219 const char *path, const char *pwd )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002220{
2221 int ret;
2222 size_t n;
2223 unsigned char *buf;
2224
2225 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2226 return( ret );
2227
2228 if( pwd == NULL )
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002229 ret = x509parse_key( ctx, buf, n, NULL, 0 );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002230 else
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002231 ret = x509parse_key( ctx, buf, n,
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002232 (const unsigned char *) pwd, strlen( pwd ) );
2233
2234 memset( buf, 0, n + 1 );
2235 free( buf );
2236
2237 return( ret );
2238}
2239
2240/*
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002241 * Load and parse a public key
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002242 */
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002243int x509parse_public_keyfile( pk_context *ctx, const char *path )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002244{
2245 int ret;
2246 size_t n;
2247 unsigned char *buf;
2248
2249 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2250 return( ret );
2251
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002252 ret = x509parse_public_key( ctx, buf, n );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002253
2254 memset( buf, 0, n + 1 );
2255 free( buf );
2256
2257 return( ret );
2258}
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002259
Paul Bakker335db3f2011-04-25 15:28:35 +00002260#endif /* POLARSSL_FS_IO */
2261
2262/*
Paul Bakkere2f50402013-06-24 19:00:59 +02002263 * Parse a PKCS#1 encoded private RSA key
Paul Bakker5121ce52009-01-03 21:22:43 +00002264 */
Paul Bakkere2f50402013-06-24 19:00:59 +02002265static int x509parse_key_pkcs1_der( rsa_context *rsa,
2266 const unsigned char *key,
2267 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +00002268{
Paul Bakker23986e52011-04-24 08:57:21 +00002269 int ret;
2270 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00002271 unsigned char *p, *end;
Paul Bakkered56b222011-07-13 11:26:43 +00002272
Paul Bakker96743fc2011-02-12 14:30:57 +00002273 p = (unsigned char *) key;
Paul Bakker96743fc2011-02-12 14:30:57 +00002274 end = p + keylen;
2275
Paul Bakker5121ce52009-01-03 21:22:43 +00002276 /*
Paul Bakkere2f50402013-06-24 19:00:59 +02002277 * This function parses the RSAPrivateKey (PKCS#1)
Paul Bakkered56b222011-07-13 11:26:43 +00002278 *
Paul Bakker5121ce52009-01-03 21:22:43 +00002279 * RSAPrivateKey ::= SEQUENCE {
2280 * version Version,
2281 * modulus INTEGER, -- n
2282 * publicExponent INTEGER, -- e
2283 * privateExponent INTEGER, -- d
2284 * prime1 INTEGER, -- p
2285 * prime2 INTEGER, -- q
2286 * exponent1 INTEGER, -- d mod (p-1)
2287 * exponent2 INTEGER, -- d mod (q-1)
2288 * coefficient INTEGER, -- (inverse of q) mod p
2289 * otherPrimeInfos OtherPrimeInfos OPTIONAL
2290 * }
2291 */
2292 if( ( ret = asn1_get_tag( &p, end, &len,
2293 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2294 {
Paul Bakker9d781402011-05-09 16:17:09 +00002295 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002296 }
2297
2298 end = p + len;
2299
2300 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2301 {
Paul Bakker9d781402011-05-09 16:17:09 +00002302 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002303 }
2304
2305 if( rsa->ver != 0 )
2306 {
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002307 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00002308 }
2309
2310 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
2311 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
2312 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
2313 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
2314 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
2315 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
2316 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
2317 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
2318 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002319 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002320 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002321 }
2322
2323 rsa->len = mpi_size( &rsa->N );
2324
2325 if( p != end )
2326 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002327 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002328 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00002329 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002330 }
2331
2332 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2333 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002334 rsa_free( rsa );
2335 return( ret );
2336 }
2337
Paul Bakkere2f50402013-06-24 19:00:59 +02002338 return( 0 );
2339}
2340
2341/*
2342 * Parse an unencrypted PKCS#8 encoded private RSA key
2343 */
2344static int x509parse_key_pkcs8_unencrypted_der(
2345 rsa_context *rsa,
2346 const unsigned char *key,
2347 size_t keylen )
2348{
2349 int ret;
2350 size_t len;
2351 unsigned char *p, *end;
2352 x509_buf pk_alg_oid;
2353 pk_type_t pk_alg = POLARSSL_PK_NONE;
2354
2355 p = (unsigned char *) key;
2356 end = p + keylen;
2357
2358 /*
2359 * This function parses the PrivatKeyInfo object (PKCS#8)
2360 *
2361 * PrivateKeyInfo ::= SEQUENCE {
2362 * version Version,
2363 * algorithm AlgorithmIdentifier,
2364 * PrivateKey BIT STRING
2365 * }
2366 *
2367 * AlgorithmIdentifier ::= SEQUENCE {
2368 * algorithm OBJECT IDENTIFIER,
2369 * parameters ANY DEFINED BY algorithm OPTIONAL
2370 * }
2371 *
2372 * The PrivateKey BIT STRING is a PKCS#1 RSAPrivateKey
2373 */
2374 if( ( ret = asn1_get_tag( &p, end, &len,
2375 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2376 {
2377 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2378 }
2379
2380 end = p + len;
2381
2382 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2383 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2384
2385 if( rsa->ver != 0 )
2386 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2387
Paul Bakkerf8d018a2013-06-29 12:16:17 +02002388 if( ( ret = asn1_get_alg_null( &p, end, &pk_alg_oid ) ) != 0 )
Paul Bakkere2f50402013-06-24 19:00:59 +02002389 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2390
2391 /*
2392 * only RSA keys handled at this time
2393 */
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002394 if( oid_get_pk_alg( &pk_alg_oid, &pk_alg ) != 0 )
Manuel Pégourié-Gonnard80300ad2013-07-04 11:57:13 +02002395 {
Paul Bakkere2f50402013-06-24 19:00:59 +02002396 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
Manuel Pégourié-Gonnard80300ad2013-07-04 11:57:13 +02002397 }
Paul Bakkere2f50402013-06-24 19:00:59 +02002398
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002399 if (pk_alg != POLARSSL_PK_RSA )
2400 return( POLARSSL_ERR_X509_CERT_INVALID_ALG );
2401
Paul Bakkere2f50402013-06-24 19:00:59 +02002402 /*
2403 * Get the OCTET STRING and parse the PKCS#1 format inside
2404 */
2405 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2406 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2407
2408 if( ( end - p ) < 1 )
2409 {
2410 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
2411 POLARSSL_ERR_ASN1_OUT_OF_DATA );
2412 }
2413
2414 end = p + len;
2415
2416 if( ( ret = x509parse_key_pkcs1_der( rsa, p, end - p ) ) != 0 )
2417 return( ret );
2418
2419 return( 0 );
2420}
2421
2422/*
Manuel Pégourié-Gonnarda5d99742013-07-04 11:08:31 +02002423 * Decrypt the content of a PKCS#8 EncryptedPrivateKeyInfo
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002424 */
Manuel Pégourié-Gonnarda5d99742013-07-04 11:08:31 +02002425static int x509parse_pkcs8_decrypt( unsigned char *buf, size_t buflen,
2426 size_t *used_len,
2427 const unsigned char *key, size_t keylen,
2428 const unsigned char *pwd, size_t pwdlen )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002429{
2430 int ret;
2431 size_t len;
Paul Bakkerf8d018a2013-06-29 12:16:17 +02002432 unsigned char *p, *end;
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002433 x509_buf pbe_alg_oid, pbe_params;
Paul Bakker7749a222013-06-28 17:28:20 +02002434#if defined(POLARSSL_PKCS12_C)
2435 cipher_type_t cipher_alg;
2436 md_type_t md_alg;
2437#endif
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002438
Manuel Pégourié-Gonnarda5d99742013-07-04 11:08:31 +02002439 memset(buf, 0, buflen);
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002440
2441 p = (unsigned char *) key;
2442 end = p + keylen;
2443
Paul Bakker28144de2013-06-24 19:28:55 +02002444 if( pwdlen == 0 )
2445 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
2446
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002447 /*
2448 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
2449 *
2450 * EncryptedPrivateKeyInfo ::= SEQUENCE {
2451 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
2452 * encryptedData EncryptedData
2453 * }
2454 *
2455 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
2456 *
2457 * EncryptedData ::= OCTET STRING
2458 *
2459 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
2460 */
2461 if( ( ret = asn1_get_tag( &p, end, &len,
2462 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2463 {
2464 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2465 }
2466
2467 end = p + len;
2468
Paul Bakkerf8d018a2013-06-29 12:16:17 +02002469 if( ( ret = asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002470 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002471
2472 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2473 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2474
Manuel Pégourié-Gonnarda5d99742013-07-04 11:08:31 +02002475 if( len > buflen )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002476 return( POLARSSL_ERR_X509_INVALID_INPUT );
2477
2478 /*
2479 * Decrypt EncryptedData with appropriate PDE
2480 */
Paul Bakker38b50d72013-06-24 19:33:27 +02002481#if defined(POLARSSL_PKCS12_C)
Paul Bakker7749a222013-06-28 17:28:20 +02002482 if( oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002483 {
Paul Bakker38b50d72013-06-24 19:33:27 +02002484 if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
Paul Bakker7749a222013-06-28 17:28:20 +02002485 cipher_alg, md_alg,
Paul Bakker38b50d72013-06-24 19:33:27 +02002486 pwd, pwdlen, p, len, buf ) ) != 0 )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002487 {
Paul Bakker38b50d72013-06-24 19:33:27 +02002488 if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH )
2489 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2490
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002491 return( ret );
2492 }
2493 }
2494 else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) )
2495 {
2496 if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params,
2497 PKCS12_PBE_DECRYPT,
2498 pwd, pwdlen,
2499 p, len, buf ) ) != 0 )
2500 {
2501 return( ret );
2502 }
Paul Bakker38b50d72013-06-24 19:33:27 +02002503
2504 // Best guess for password mismatch when using RC4. If first tag is
2505 // not ASN1_CONSTRUCTED | ASN1_SEQUENCE
2506 //
2507 if( *buf != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
2508 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002509 }
Paul Bakker38b50d72013-06-24 19:33:27 +02002510 else
2511#endif /* POLARSSL_PKCS12_C */
Paul Bakker28144de2013-06-24 19:28:55 +02002512#if defined(POLARSSL_PKCS5_C)
Paul Bakker38b50d72013-06-24 19:33:27 +02002513 if( OID_CMP( OID_PKCS5_PBES2, &pbe_alg_oid ) )
Paul Bakker28144de2013-06-24 19:28:55 +02002514 {
2515 if( ( ret = pkcs5_pbes2( &pbe_params, PKCS5_DECRYPT, pwd, pwdlen,
2516 p, len, buf ) ) != 0 )
2517 {
2518 if( ret == POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH )
2519 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2520
2521 return( ret );
2522 }
2523 }
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002524 else
Paul Bakker38b50d72013-06-24 19:33:27 +02002525#endif /* POLARSSL_PKCS5_C */
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002526 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
2527
Manuel Pégourié-Gonnarda5d99742013-07-04 11:08:31 +02002528 *used_len = len;
2529 return( 0 );
2530}
2531
2532/*
2533 * Parse an encrypted PKCS#8 encoded private RSA key
2534 */
2535static int x509parse_key_pkcs8_encrypted_der(
2536 rsa_context *rsa,
2537 const unsigned char *key, size_t keylen,
2538 const unsigned char *pwd, size_t pwdlen )
2539{
2540 int ret;
2541 unsigned char buf[2048];
2542 size_t len = 0;
2543
2544 if( ( ret = x509parse_pkcs8_decrypt( buf, sizeof( buf ), &len,
2545 key, keylen, pwd, pwdlen ) ) != 0 )
2546 {
2547 return( ret );
2548 }
2549
2550 return( x509parse_key_pkcs8_unencrypted_der( rsa, buf, len ) );
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002551}
2552
2553/*
Paul Bakkere2f50402013-06-24 19:00:59 +02002554 * Parse a private RSA key
2555 */
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002556int x509parse_key_rsa( rsa_context *rsa,
2557 const unsigned char *key, size_t keylen,
2558 const unsigned char *pwd, size_t pwdlen )
Paul Bakkere2f50402013-06-24 19:00:59 +02002559{
2560 int ret;
2561
Paul Bakker96743fc2011-02-12 14:30:57 +00002562#if defined(POLARSSL_PEM_C)
Paul Bakkere2f50402013-06-24 19:00:59 +02002563 size_t len;
2564 pem_context pem;
2565
2566 pem_init( &pem );
2567 ret = pem_read_buffer( &pem,
2568 "-----BEGIN RSA PRIVATE KEY-----",
2569 "-----END RSA PRIVATE KEY-----",
2570 key, pwd, pwdlen, &len );
2571 if( ret == 0 )
2572 {
2573 if( ( ret = x509parse_key_pkcs1_der( rsa, pem.buf, pem.buflen ) ) != 0 )
2574 {
2575 rsa_free( rsa );
2576 }
2577
2578 pem_free( &pem );
2579 return( ret );
2580 }
Paul Bakkera4232a72013-06-24 19:32:25 +02002581 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
2582 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2583 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
2584 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
Paul Bakkere2f50402013-06-24 19:00:59 +02002585 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkere2f50402013-06-24 19:00:59 +02002586 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002587
2588 ret = pem_read_buffer( &pem,
2589 "-----BEGIN PRIVATE KEY-----",
2590 "-----END PRIVATE KEY-----",
2591 key, NULL, 0, &len );
2592 if( ret == 0 )
2593 {
2594 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa,
2595 pem.buf, pem.buflen ) ) != 0 )
2596 {
2597 rsa_free( rsa );
2598 }
2599
2600 pem_free( &pem );
2601 return( ret );
2602 }
2603 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkere2f50402013-06-24 19:00:59 +02002604 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002605
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002606 ret = pem_read_buffer( &pem,
2607 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
2608 "-----END ENCRYPTED PRIVATE KEY-----",
2609 key, NULL, 0, &len );
2610 if( ret == 0 )
2611 {
2612 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa,
2613 pem.buf, pem.buflen,
2614 pwd, pwdlen ) ) != 0 )
2615 {
2616 rsa_free( rsa );
2617 }
2618
2619 pem_free( &pem );
2620 return( ret );
2621 }
2622 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002623 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002624#else
2625 ((void) pwd);
2626 ((void) pwdlen);
2627#endif /* POLARSSL_PEM_C */
2628
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002629 /*
2630 * At this point we only know it's not a PEM formatted key. Could be any
2631 * of the known DER encoded private key formats
2632 *
2633 * We try the different DER format parsers to see if one passes without
2634 * error
2635 */
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002636 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa, key, keylen,
2637 pwd, pwdlen ) ) == 0 )
Paul Bakkere2f50402013-06-24 19:00:59 +02002638 {
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002639 return( 0 );
Paul Bakkere2f50402013-06-24 19:00:59 +02002640 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002641
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002642 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002643
2644 if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH )
2645 {
2646 return( ret );
2647 }
2648
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002649 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa, key, keylen ) ) == 0 )
2650 return( 0 );
2651
2652 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002653
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002654 if( ( ret = x509parse_key_pkcs1_der( rsa, key, keylen ) ) == 0 )
2655 return( 0 );
2656
2657 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002658
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002659 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00002660}
2661
2662/*
Paul Bakker53019ae2011-03-25 13:58:48 +00002663 * Parse a public RSA key
2664 */
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002665int x509parse_public_key_rsa( rsa_context *rsa,
2666 const unsigned char *key, size_t keylen )
Paul Bakker53019ae2011-03-25 13:58:48 +00002667{
Paul Bakker23986e52011-04-24 08:57:21 +00002668 int ret;
2669 size_t len;
Paul Bakker53019ae2011-03-25 13:58:48 +00002670 unsigned char *p, *end;
Paul Bakker53019ae2011-03-25 13:58:48 +00002671#if defined(POLARSSL_PEM_C)
2672 pem_context pem;
2673
2674 pem_init( &pem );
2675 ret = pem_read_buffer( &pem,
2676 "-----BEGIN PUBLIC KEY-----",
2677 "-----END PUBLIC KEY-----",
2678 key, NULL, 0, &len );
2679
2680 if( ret == 0 )
2681 {
2682 /*
2683 * Was PEM encoded
2684 */
2685 keylen = pem.buflen;
2686 }
Paul Bakker00b28602013-06-24 13:02:41 +02002687 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker53019ae2011-03-25 13:58:48 +00002688 {
2689 pem_free( &pem );
2690 return( ret );
2691 }
2692
2693 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2694#else
2695 p = (unsigned char *) key;
2696#endif
2697 end = p + keylen;
2698
Manuel Pégourié-Gonnard094ad9e2013-07-09 12:32:51 +02002699 if( ( ret = x509_get_pubkey_rsa( &p, end, rsa ) ) != 0 )
Paul Bakker53019ae2011-03-25 13:58:48 +00002700 {
2701#if defined(POLARSSL_PEM_C)
2702 pem_free( &pem );
2703#endif
2704 rsa_free( rsa );
2705 return( ret );
2706 }
2707
Paul Bakker53019ae2011-03-25 13:58:48 +00002708#if defined(POLARSSL_PEM_C)
2709 pem_free( &pem );
2710#endif
2711
2712 return( 0 );
2713}
2714
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002715#if defined(POLARSSL_ECP_C)
2716/*
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002717 * Parse a SEC1 encoded private EC key
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002718 */
2719static int x509parse_key_sec1_der( ecp_keypair *eck,
2720 const unsigned char *key,
2721 size_t keylen )
2722{
2723 int ret;
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002724 int version;
2725 size_t len;
2726 ecp_group_id grp_id;
2727 unsigned char *p = (unsigned char *) key;
2728 unsigned char *end = p + keylen;
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002729
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002730 /*
2731 * RFC 5915, orf SEC1 Appendix C.4
2732 *
2733 * ECPrivateKey ::= SEQUENCE {
2734 * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
2735 * privateKey OCTET STRING,
2736 * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
2737 * publicKey [1] BIT STRING OPTIONAL
2738 * }
2739 */
2740 if( ( ret = asn1_get_tag( &p, end, &len,
2741 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2742 {
2743 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2744 }
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002745
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002746 end = p + len;
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002747
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002748 if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 )
2749 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002750
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002751 if( version != 1 )
2752 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION );
2753
2754 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2755 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2756
2757 if( ( ret = mpi_read_binary( &eck->d, p, len ) ) != 0 )
2758 {
2759 ecp_keypair_free( eck );
2760 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2761 }
2762
2763 p += len;
2764
2765 /*
2766 * Is 'parameters' present?
2767 */
2768 if( ( ret = asn1_get_tag( &p, end, &len,
2769 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) == 0 )
2770 {
2771 if( ( ret = x509_get_ecparams( &p, p + len, &grp_id) ) != 0 )
2772 return( ret );
2773
Manuel Pégourié-Gonnardd4ec21d2013-07-04 12:04:57 +02002774 /*
2775 * If we're wrapped in a bigger structure (eg PKCS#8), grp may have been
2776 * defined externally. In this case, make sure both definitions match.
2777 */
2778 if( eck->grp.id != 0 )
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002779 {
Manuel Pégourié-Gonnardd4ec21d2013-07-04 12:04:57 +02002780 if( eck->grp.id != grp_id )
2781 {
2782 ecp_keypair_free( eck );
2783 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2784 }
2785 }
2786 else
2787 {
2788 if( ( ret = ecp_use_known_dp( &eck->grp, grp_id ) ) != 0 )
2789 {
2790 ecp_keypair_free( eck );
2791 return( ret );
2792 }
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002793 }
2794 }
2795 else if ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
2796 {
2797 ecp_keypair_free( eck );
2798 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2799 }
2800
2801 /*
2802 * Is 'publickey' present?
2803 */
2804 if( ( ret = asn1_get_tag( &p, end, &len,
2805 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 )
2806 {
2807 if( ( ret = x509_get_subpubkey_ec( &p, p + len, &eck->grp, &eck->Q ) )
2808 != 0 )
2809 {
2810 ecp_keypair_free( eck );
2811 return( ret );
2812 }
2813
2814 if( ( ret = ecp_check_pubkey( &eck->grp, &eck->Q ) ) != 0 )
2815 {
2816 ecp_keypair_free( eck );
2817 return( ret );
2818 }
2819 }
2820 else if ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
2821 {
2822 ecp_keypair_free( eck );
2823 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2824 }
2825
Manuel Pégourié-Gonnardde44a4a2013-07-09 16:05:52 +02002826 if( ( ret = ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 )
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002827 {
2828 ecp_keypair_free( eck );
2829 return( ret );
2830 }
2831
2832 return 0;
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002833}
2834
2835/*
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002836 * Parse an unencrypted PKCS#8 encoded private EC key
2837 */
2838static int x509parse_key_pkcs8_unencrypted_der_ec(
2839 ecp_keypair *eck,
2840 const unsigned char* key,
2841 size_t keylen )
2842{
2843 int ret, version;
2844 size_t len;
Manuel Pégourié-Gonnard0a64e8f2013-07-08 18:26:18 +02002845 x509_buf alg_params;
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002846 ecp_group_id grp_id;
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002847 unsigned char *p = (unsigned char *) key;
2848 unsigned char *end = p + keylen;
2849 pk_type_t pk_alg = POLARSSL_PK_NONE;
2850
2851 /*
2852 * This function parses the PrivatKeyInfo object (PKCS#8 v1.2 = RFC 5208)
2853 *
2854 * PrivateKeyInfo ::= SEQUENCE {
2855 * version Version,
2856 * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
2857 * privateKey PrivateKey,
2858 * attributes [0] IMPLICIT Attributes OPTIONAL }
2859 *
2860 * Version ::= INTEGER
2861 * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
2862 * PrivateKey ::= OCTET STRING
2863 *
2864 * The PrivateKey OCTET STRING is a SEC1 ECPrivateKey
2865 */
2866
2867 if( ( ret = asn1_get_tag( &p, end, &len,
2868 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2869 {
2870 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2871 }
2872
2873 end = p + len;
2874
2875 if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 )
2876 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2877
2878 if( version != 0 )
2879 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2880
Manuel Pégourié-Gonnard0a64e8f2013-07-08 18:26:18 +02002881 if( ( ret = x509_get_algid( &p, end, &pk_alg, &alg_params ) ) != 0 )
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002882 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2883
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002884 if( pk_alg != POLARSSL_PK_ECKEY && pk_alg != POLARSSL_PK_ECKEY_DH )
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002885 return( POLARSSL_ERR_X509_CERT_INVALID_ALG );
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002886
2887 if( pk_alg == POLARSSL_PK_ECKEY_DH )
2888 eck->alg = POLARSSL_ECP_KEY_ALG_ECDH;
2889
Manuel Pégourié-Gonnard0a64e8f2013-07-08 18:26:18 +02002890 if( ( ret = x509_ecparams_get_grp_id( &alg_params, &grp_id ) ) != 0 )
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002891 {
2892 ecp_keypair_free( eck );
2893 return( ret );
2894 }
2895
2896 if( ( ret = ecp_use_known_dp( &eck->grp, grp_id ) ) != 0 )
2897 {
2898 ecp_keypair_free( eck );
2899 return( ret );
2900 }
2901
2902 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2903 {
2904 ecp_keypair_free( eck );
2905 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2906 }
2907
2908 if( ( ret = x509parse_key_sec1_der( eck, p, len ) ) != 0 )
2909 {
2910 ecp_keypair_free( eck );
2911 return( ret );
2912 }
2913
Manuel Pégourié-Gonnardde44a4a2013-07-09 16:05:52 +02002914 if( ( ret = ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 )
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002915 {
2916 ecp_keypair_free( eck );
2917 return( ret );
2918 }
2919
2920 return 0;
2921}
2922
2923/*
2924 * Parse an encrypted PKCS#8 encoded private EC key
2925 */
2926static int x509parse_key_pkcs8_encrypted_der_ec(
2927 ecp_keypair *eck,
Manuel Pégourié-Gonnard9c1cf452013-07-04 11:20:24 +02002928 const unsigned char *key, size_t keylen,
2929 const unsigned char *pwd, size_t pwdlen )
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002930{
2931 int ret;
Manuel Pégourié-Gonnard9c1cf452013-07-04 11:20:24 +02002932 unsigned char buf[2048];
2933 size_t len = 0;
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002934
Manuel Pégourié-Gonnard9c1cf452013-07-04 11:20:24 +02002935 if( ( ret = x509parse_pkcs8_decrypt( buf, sizeof( buf ), &len,
2936 key, keylen, pwd, pwdlen ) ) != 0 )
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002937 {
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002938 return( ret );
2939 }
2940
Manuel Pégourié-Gonnard9c1cf452013-07-04 11:20:24 +02002941 return( x509parse_key_pkcs8_unencrypted_der_ec( eck, buf, len ) );
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002942}
2943
2944/*
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002945 * Parse a private EC key
2946 */
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002947static int x509parse_key_ec( ecp_keypair *eck,
2948 const unsigned char *key, size_t keylen,
2949 const unsigned char *pwd, size_t pwdlen )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002950{
2951 int ret;
2952
2953#if defined(POLARSSL_PEM_C)
2954 size_t len;
2955 pem_context pem;
2956
2957 pem_init( &pem );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002958 ret = pem_read_buffer( &pem,
2959 "-----BEGIN EC PRIVATE KEY-----",
2960 "-----END EC PRIVATE KEY-----",
2961 key, pwd, pwdlen, &len );
2962 if( ret == 0 )
2963 {
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002964 if( ( ret = x509parse_key_sec1_der( eck, pem.buf, pem.buflen ) ) != 0 )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002965 {
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002966 ecp_keypair_free( eck );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002967 }
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002968
2969 pem_free( &pem );
2970 return( ret );
2971 }
2972 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
2973 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2974 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
2975 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
2976 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2977 return( ret );
2978
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002979 ret = pem_read_buffer( &pem,
2980 "-----BEGIN PRIVATE KEY-----",
2981 "-----END PRIVATE KEY-----",
2982 key, NULL, 0, &len );
2983 if( ret == 0 )
2984 {
2985 if( ( ret = x509parse_key_pkcs8_unencrypted_der_ec( eck,
2986 pem.buf, pem.buflen ) ) != 0 )
2987 {
2988 ecp_keypair_free( eck );
2989 }
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002990
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002991 pem_free( &pem );
2992 return( ret );
2993 }
2994 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2995 return( ret );
2996
2997 ret = pem_read_buffer( &pem,
2998 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
2999 "-----END ENCRYPTED PRIVATE KEY-----",
3000 key, NULL, 0, &len );
3001 if( ret == 0 )
3002 {
3003 if( ( ret = x509parse_key_pkcs8_encrypted_der_ec( eck,
3004 pem.buf, pem.buflen,
3005 pwd, pwdlen ) ) != 0 )
3006 {
3007 ecp_keypair_free( eck );
3008 }
3009
3010 pem_free( &pem );
3011 return( ret );
3012 }
3013 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
3014 return( ret );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003015#else
3016 ((void) pwd);
3017 ((void) pwdlen);
3018#endif /* POLARSSL_PEM_C */
3019
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02003020 /*
3021 * At this point we only know it's not a PEM formatted key. Could be any
3022 * of the known DER encoded private key formats
3023 *
3024 * We try the different DER format parsers to see if one passes without
3025 * error
3026 */
3027 if( ( ret = x509parse_key_pkcs8_encrypted_der_ec( eck, key, keylen,
3028 pwd, pwdlen ) ) == 0 )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003029 {
3030 return( 0 );
3031 }
3032
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02003033 ecp_keypair_free( eck );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003034
3035 if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH )
3036 {
3037 return( ret );
3038 }
3039
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02003040 if( ( ret = x509parse_key_pkcs8_unencrypted_der_ec( eck,
3041 key, keylen ) ) == 0 )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003042 return( 0 );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003043
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02003044 ecp_keypair_free( eck );
3045
3046 if( ( ret = x509parse_key_sec1_der( eck, key, keylen ) ) == 0 )
3047 return( 0 );
3048
3049 ecp_keypair_free( eck );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003050
3051 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
3052}
3053
3054/*
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +02003055 * Parse a public EC key in RFC 5480 format, der-encoded
3056 */
3057static int x509parse_public_key_ec_der( ecp_keypair *key,
3058 const unsigned char *buf, size_t len )
3059{
3060 int ret;
3061 ecp_group_id grp_id;
Manuel Pégourié-Gonnard0a64e8f2013-07-08 18:26:18 +02003062 x509_buf alg_params;
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +02003063 pk_type_t alg = POLARSSL_PK_NONE;
3064 unsigned char *p = (unsigned char *) buf;
3065 unsigned char *end = p + len;
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +02003066 /*
3067 * SubjectPublicKeyInfo ::= SEQUENCE {
3068 * algorithm AlgorithmIdentifier,
3069 * subjectPublicKey BIT STRING
3070 * }
3071 * -- algorithm parameters are ECParameters
3072 * -- subjectPublicKey is an ECPoint
3073 */
3074 if( ( ret = asn1_get_tag( &p, end, &len,
3075 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
3076 {
3077 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
3078 }
3079
Manuel Pégourié-Gonnard0a64e8f2013-07-08 18:26:18 +02003080 if( ( ret = x509_get_algid( &p, end, &alg, &alg_params ) ) != 0 )
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +02003081 return( ret );
3082
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +02003083 if( alg != POLARSSL_PK_ECKEY && alg != POLARSSL_PK_ECKEY_DH )
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02003084 return( POLARSSL_ERR_X509_CERT_INVALID_ALG );
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +02003085
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02003086 if( alg == POLARSSL_PK_ECKEY_DH )
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +02003087 key->alg = POLARSSL_ECP_KEY_ALG_ECDH;
3088
Manuel Pégourié-Gonnard0a64e8f2013-07-08 18:26:18 +02003089 if( ( ret = x509_ecparams_get_grp_id( &alg_params, &grp_id ) ) != 0 )
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +02003090 return( ret );
3091
3092 if( ( ret = ecp_use_known_dp( &key->grp, grp_id ) ) != 0 )
3093 return( ret );
3094
3095 if( ( ret = x509_get_subpubkey_ec( &p, end, &key->grp, &key->Q ) ) != 0 )
3096 {
3097 return( ret );
3098 }
3099
3100 return( 0 );
3101}
3102
3103/*
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003104 * Parse a public EC key
3105 */
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02003106static int x509parse_public_key_ec( ecp_keypair *eckey,
3107 const unsigned char *key, size_t keylen )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003108{
3109 int ret;
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003110#if defined(POLARSSL_PEM_C)
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +02003111 size_t len;
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003112 pem_context pem;
3113
3114 pem_init( &pem );
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +02003115 ret = pem_read_buffer( &pem,
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003116 "-----BEGIN PUBLIC KEY-----",
3117 "-----END PUBLIC KEY-----",
3118 key, NULL, 0, &len );
3119
3120 if( ret == 0 )
3121 {
3122 /*
3123 * Was PEM encoded
3124 */
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +02003125 key = pem.buf;
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003126 keylen = pem.buflen;
3127 }
3128 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
3129 {
3130 pem_free( &pem );
3131 return( ret );
3132 }
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003133#endif
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003134
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +02003135 if( ( ret = x509parse_public_key_ec_der ( eckey, key, keylen ) ) != 0 ||
3136 ( ret = ecp_check_pubkey( &eckey->grp, &eckey->Q ) ) != 0 )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003137 {
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003138 ecp_keypair_free( eckey );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003139 }
3140
3141#if defined(POLARSSL_PEM_C)
3142 pem_free( &pem );
3143#endif
3144
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +02003145 return( ret );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003146}
3147#endif /* defined(POLARSSL_ECP_C) */
3148
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02003149/*
3150 * Parse a private key
3151 */
3152int x509parse_key( pk_context *ctx,
3153 const unsigned char *key, size_t keylen,
3154 const unsigned char *pwd, size_t pwdlen )
3155{
3156 int ret;
3157
3158 if ( ( ret = pk_set_type( ctx, POLARSSL_PK_RSA ) ) != 0 )
3159 return( ret );
3160
3161 if( ( ret = x509parse_key_rsa( ctx->data, key, keylen, pwd, pwdlen ) )
3162 == 0 )
3163 {
3164 return( 0 );
3165 }
3166
Manuel Pégourié-Gonnard374e4b82013-07-09 10:21:34 +02003167 pk_free( ctx );
3168
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02003169 if ( ( ret = pk_set_type( ctx, POLARSSL_PK_ECKEY ) ) != 0 )
3170 return( ret );
3171
3172 if( ( ret = x509parse_key_ec( ctx->data, key, keylen, pwd, pwdlen ) ) == 0 )
3173 {
3174 return( 0 );
3175 }
3176
Manuel Pégourié-Gonnard374e4b82013-07-09 10:21:34 +02003177 pk_free( ctx );
3178
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02003179 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
3180}
3181
3182/*
3183 * Parse a public key
3184 */
3185int x509parse_public_key( pk_context *ctx,
3186 const unsigned char *key, size_t keylen )
3187{
3188 int ret;
3189
3190 if ( ( ret = pk_set_type( ctx, POLARSSL_PK_RSA ) ) != 0 )
3191 return( ret );
3192
3193 if( ( ret = x509parse_public_key_rsa( ctx->data, key, keylen ) ) == 0 )
3194 return( 0 );
3195
Manuel Pégourié-Gonnard374e4b82013-07-09 10:21:34 +02003196 pk_free( ctx );
3197
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02003198 if ( ( ret = pk_set_type( ctx, POLARSSL_PK_ECKEY ) ) != 0 )
3199 return( ret );
3200
3201 if( ( ret = x509parse_public_key_ec( ctx->data, key, keylen ) ) == 0 )
3202 return( 0 );
3203
Manuel Pégourié-Gonnard374e4b82013-07-09 10:21:34 +02003204 pk_free( ctx );
3205
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02003206 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
3207}
3208
Paul Bakkereaa89f82011-04-04 21:36:15 +00003209#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00003210/*
Paul Bakker1b57b062011-01-06 15:48:19 +00003211 * Parse DHM parameters
3212 */
Paul Bakker23986e52011-04-24 08:57:21 +00003213int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
Paul Bakker1b57b062011-01-06 15:48:19 +00003214{
Paul Bakker23986e52011-04-24 08:57:21 +00003215 int ret;
3216 size_t len;
Paul Bakker1b57b062011-01-06 15:48:19 +00003217 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00003218#if defined(POLARSSL_PEM_C)
3219 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00003220
Paul Bakker96743fc2011-02-12 14:30:57 +00003221 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00003222
Paul Bakker96743fc2011-02-12 14:30:57 +00003223 ret = pem_read_buffer( &pem,
3224 "-----BEGIN DH PARAMETERS-----",
3225 "-----END DH PARAMETERS-----",
3226 dhmin, NULL, 0, &dhminlen );
3227
3228 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003229 {
Paul Bakker96743fc2011-02-12 14:30:57 +00003230 /*
3231 * Was PEM encoded
3232 */
3233 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00003234 }
Paul Bakker00b28602013-06-24 13:02:41 +02003235 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00003236 {
Paul Bakker96743fc2011-02-12 14:30:57 +00003237 pem_free( &pem );
3238 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00003239 }
3240
Paul Bakker96743fc2011-02-12 14:30:57 +00003241 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
3242#else
3243 p = (unsigned char *) dhmin;
3244#endif
3245 end = p + dhminlen;
3246
Paul Bakker1b57b062011-01-06 15:48:19 +00003247 memset( dhm, 0, sizeof( dhm_context ) );
3248
Paul Bakker1b57b062011-01-06 15:48:19 +00003249 /*
3250 * DHParams ::= SEQUENCE {
3251 * prime INTEGER, -- P
3252 * generator INTEGER, -- g
3253 * }
3254 */
3255 if( ( ret = asn1_get_tag( &p, end, &len,
3256 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
3257 {
Paul Bakker96743fc2011-02-12 14:30:57 +00003258#if defined(POLARSSL_PEM_C)
3259 pem_free( &pem );
3260#endif
Paul Bakker9d781402011-05-09 16:17:09 +00003261 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00003262 }
3263
3264 end = p + len;
3265
3266 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
3267 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
3268 {
Paul Bakker96743fc2011-02-12 14:30:57 +00003269#if defined(POLARSSL_PEM_C)
3270 pem_free( &pem );
3271#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00003272 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00003273 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00003274 }
3275
3276 if( p != end )
3277 {
Paul Bakker96743fc2011-02-12 14:30:57 +00003278#if defined(POLARSSL_PEM_C)
3279 pem_free( &pem );
3280#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00003281 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00003282 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker1b57b062011-01-06 15:48:19 +00003283 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
3284 }
3285
Paul Bakker96743fc2011-02-12 14:30:57 +00003286#if defined(POLARSSL_PEM_C)
3287 pem_free( &pem );
3288#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00003289
3290 return( 0 );
3291}
3292
Paul Bakker335db3f2011-04-25 15:28:35 +00003293#if defined(POLARSSL_FS_IO)
Paul Bakker1b57b062011-01-06 15:48:19 +00003294/*
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02003295 * Load and parse DHM parameters
Paul Bakker1b57b062011-01-06 15:48:19 +00003296 */
3297int x509parse_dhmfile( dhm_context *dhm, const char *path )
3298{
3299 int ret;
3300 size_t n;
3301 unsigned char *buf;
3302
Paul Bakker69e095c2011-12-10 21:55:01 +00003303 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
3304 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00003305
Paul Bakker27fdf462011-06-09 13:55:13 +00003306 ret = x509parse_dhm( dhm, buf, n );
Paul Bakker1b57b062011-01-06 15:48:19 +00003307
3308 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02003309 polarssl_free( buf );
Paul Bakker1b57b062011-01-06 15:48:19 +00003310
3311 return( ret );
3312}
Paul Bakker335db3f2011-04-25 15:28:35 +00003313#endif /* POLARSSL_FS_IO */
Paul Bakkereaa89f82011-04-04 21:36:15 +00003314#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00003315
Paul Bakker5121ce52009-01-03 21:22:43 +00003316#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00003317#include <stdarg.h>
3318
3319#if !defined vsnprintf
3320#define vsnprintf _vsnprintf
3321#endif // vsnprintf
3322
3323/*
3324 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
3325 * Result value is not size of buffer needed, but -1 if no fit is possible.
3326 *
3327 * This fuction tries to 'fix' this by at least suggesting enlarging the
3328 * size by 20.
3329 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02003330static int compat_snprintf(char *str, size_t size, const char *format, ...)
Paul Bakkerd98030e2009-05-02 15:13:40 +00003331{
3332 va_list ap;
3333 int res = -1;
3334
3335 va_start( ap, format );
3336
3337 res = vsnprintf( str, size, format, ap );
3338
3339 va_end( ap );
3340
3341 // No quick fix possible
3342 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00003343 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003344
3345 return res;
3346}
3347
3348#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00003349#endif
3350
Paul Bakkerd98030e2009-05-02 15:13:40 +00003351#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
3352
3353#define SAFE_SNPRINTF() \
3354{ \
3355 if( ret == -1 ) \
3356 return( -1 ); \
3357 \
Paul Bakker23986e52011-04-24 08:57:21 +00003358 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00003359 p[n - 1] = '\0'; \
3360 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
3361 } \
3362 \
Paul Bakker23986e52011-04-24 08:57:21 +00003363 n -= (unsigned int) ret; \
3364 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00003365}
3366
Paul Bakker5121ce52009-01-03 21:22:43 +00003367/*
3368 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00003369 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00003370 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003371int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00003372{
Paul Bakker23986e52011-04-24 08:57:21 +00003373 int ret;
3374 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00003375 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00003376 const x509_name *name;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003377 const char *short_name = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003378 char s[128], *p;
3379
3380 memset( s, 0, sizeof( s ) );
3381
3382 name = dn;
3383 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003384 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00003385
3386 while( name != NULL )
3387 {
Paul Bakkercefb3962012-06-27 11:51:09 +00003388 if( !name->oid.p )
3389 {
3390 name = name->next;
3391 continue;
3392 }
3393
Paul Bakker74111d32011-01-15 16:57:55 +00003394 if( name != dn )
3395 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00003396 ret = snprintf( p, n, ", " );
3397 SAFE_SNPRINTF();
3398 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003399
Paul Bakkerc70b9822013-04-07 22:00:46 +02003400 ret = oid_get_attr_short_name( &name->oid, &short_name );
Paul Bakker5121ce52009-01-03 21:22:43 +00003401
Paul Bakkerc70b9822013-04-07 22:00:46 +02003402 if( ret == 0 )
3403 ret = snprintf( p, n, "%s=", short_name );
Paul Bakker5121ce52009-01-03 21:22:43 +00003404 else
Paul Bakkerd98030e2009-05-02 15:13:40 +00003405 ret = snprintf( p, n, "\?\?=" );
Paul Bakkerc70b9822013-04-07 22:00:46 +02003406 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003407
3408 for( i = 0; i < name->val.len; i++ )
3409 {
Paul Bakker27fdf462011-06-09 13:55:13 +00003410 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003411 break;
3412
3413 c = name->val.p[i];
3414 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
3415 s[i] = '?';
3416 else s[i] = c;
3417 }
3418 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00003419 ret = snprintf( p, n, "%s", s );
Paul Bakkerc70b9822013-04-07 22:00:46 +02003420 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003421 name = name->next;
3422 }
3423
Paul Bakker23986e52011-04-24 08:57:21 +00003424 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003425}
3426
3427/*
Paul Bakkerdd476992011-01-16 21:34:59 +00003428 * Store the serial in printable form into buf; no more
3429 * than size characters will be written
3430 */
3431int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
3432{
Paul Bakker23986e52011-04-24 08:57:21 +00003433 int ret;
3434 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00003435 char *p;
3436
3437 p = buf;
3438 n = size;
3439
3440 nr = ( serial->len <= 32 )
Paul Bakker03c7c252011-11-25 12:37:37 +00003441 ? serial->len : 28;
Paul Bakkerdd476992011-01-16 21:34:59 +00003442
3443 for( i = 0; i < nr; i++ )
3444 {
Paul Bakker93048802011-12-05 14:38:06 +00003445 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003446 continue;
3447
Paul Bakkerdd476992011-01-16 21:34:59 +00003448 ret = snprintf( p, n, "%02X%s",
3449 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
3450 SAFE_SNPRINTF();
3451 }
3452
Paul Bakker03c7c252011-11-25 12:37:37 +00003453 if( nr != serial->len )
3454 {
3455 ret = snprintf( p, n, "...." );
3456 SAFE_SNPRINTF();
3457 }
3458
Paul Bakker23986e52011-04-24 08:57:21 +00003459 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00003460}
3461
3462/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00003463 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00003464 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003465int x509parse_cert_info( char *buf, size_t size, const char *prefix,
3466 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00003467{
Paul Bakker23986e52011-04-24 08:57:21 +00003468 int ret;
3469 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003470 char *p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003471 const char *desc = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003472
3473 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003474 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00003475
Paul Bakkerd98030e2009-05-02 15:13:40 +00003476 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00003477 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003478 SAFE_SNPRINTF();
3479 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00003480 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003481 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003482
Paul Bakkerdd476992011-01-16 21:34:59 +00003483 ret = x509parse_serial_gets( p, n, &crt->serial);
3484 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003485
Paul Bakkerd98030e2009-05-02 15:13:40 +00003486 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
3487 SAFE_SNPRINTF();
3488 ret = x509parse_dn_gets( p, n, &crt->issuer );
3489 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003490
Paul Bakkerd98030e2009-05-02 15:13:40 +00003491 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
3492 SAFE_SNPRINTF();
3493 ret = x509parse_dn_gets( p, n, &crt->subject );
3494 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003495
Paul Bakkerd98030e2009-05-02 15:13:40 +00003496 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00003497 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3498 crt->valid_from.year, crt->valid_from.mon,
3499 crt->valid_from.day, crt->valid_from.hour,
3500 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003501 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003502
Paul Bakkerd98030e2009-05-02 15:13:40 +00003503 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00003504 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3505 crt->valid_to.year, crt->valid_to.mon,
3506 crt->valid_to.day, crt->valid_to.hour,
3507 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003508 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003509
Paul Bakkerc70b9822013-04-07 22:00:46 +02003510 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003511 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003512
Paul Bakkerc70b9822013-04-07 22:00:46 +02003513 ret = oid_get_sig_alg_desc( &crt->sig_oid1, &desc );
3514 if( ret != 0 )
3515 ret = snprintf( p, n, "???" );
3516 else
3517 ret = snprintf( p, n, desc );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003518 SAFE_SNPRINTF();
3519
3520 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
Paul Bakker5c2364c2012-10-01 14:41:15 +00003521 (int) crt->rsa.N.n * (int) sizeof( t_uint ) * 8 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003522 SAFE_SNPRINTF();
3523
Paul Bakker23986e52011-04-24 08:57:21 +00003524 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003525}
3526
Paul Bakker74111d32011-01-15 16:57:55 +00003527/*
3528 * Return an informational string describing the given OID
3529 */
3530const char *x509_oid_get_description( x509_buf *oid )
3531{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003532 const char *desc = NULL;
3533 int ret;
Paul Bakker74111d32011-01-15 16:57:55 +00003534
Paul Bakkerc70b9822013-04-07 22:00:46 +02003535 ret = oid_get_extended_key_usage( oid, &desc );
Paul Bakker74111d32011-01-15 16:57:55 +00003536
Paul Bakkerc70b9822013-04-07 22:00:46 +02003537 if( ret != 0 )
3538 return( NULL );
Paul Bakker74111d32011-01-15 16:57:55 +00003539
Paul Bakkerc70b9822013-04-07 22:00:46 +02003540 return( desc );
Paul Bakker74111d32011-01-15 16:57:55 +00003541}
3542
3543/* Return the x.y.z.... style numeric string for the given OID */
3544int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
3545{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003546 return oid_get_numeric_string( buf, size, oid );
Paul Bakker74111d32011-01-15 16:57:55 +00003547}
3548
Paul Bakkerd98030e2009-05-02 15:13:40 +00003549/*
3550 * Return an informational string about the CRL.
3551 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003552int x509parse_crl_info( char *buf, size_t size, const char *prefix,
3553 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003554{
Paul Bakker23986e52011-04-24 08:57:21 +00003555 int ret;
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003556 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003557 char *p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003558 const char *desc;
Paul Bakkerff60ee62010-03-16 21:09:09 +00003559 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003560
3561 p = buf;
3562 n = size;
3563
3564 ret = snprintf( p, n, "%sCRL version : %d",
3565 prefix, crl->version );
3566 SAFE_SNPRINTF();
3567
3568 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
3569 SAFE_SNPRINTF();
3570 ret = x509parse_dn_gets( p, n, &crl->issuer );
3571 SAFE_SNPRINTF();
3572
3573 ret = snprintf( p, n, "\n%sthis update : " \
3574 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3575 crl->this_update.year, crl->this_update.mon,
3576 crl->this_update.day, crl->this_update.hour,
3577 crl->this_update.min, crl->this_update.sec );
3578 SAFE_SNPRINTF();
3579
3580 ret = snprintf( p, n, "\n%snext update : " \
3581 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3582 crl->next_update.year, crl->next_update.mon,
3583 crl->next_update.day, crl->next_update.hour,
3584 crl->next_update.min, crl->next_update.sec );
3585 SAFE_SNPRINTF();
3586
3587 entry = &crl->entry;
3588
3589 ret = snprintf( p, n, "\n%sRevoked certificates:",
3590 prefix );
3591 SAFE_SNPRINTF();
3592
Paul Bakker9be19372009-07-27 20:21:53 +00003593 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003594 {
3595 ret = snprintf( p, n, "\n%sserial number: ",
3596 prefix );
3597 SAFE_SNPRINTF();
3598
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003599 ret = x509parse_serial_gets( p, n, &entry->serial);
3600 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003601
Paul Bakkerd98030e2009-05-02 15:13:40 +00003602 ret = snprintf( p, n, " revocation date: " \
3603 "%04d-%02d-%02d %02d:%02d:%02d",
3604 entry->revocation_date.year, entry->revocation_date.mon,
3605 entry->revocation_date.day, entry->revocation_date.hour,
3606 entry->revocation_date.min, entry->revocation_date.sec );
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003607 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003608
3609 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003610 }
3611
Paul Bakkerc70b9822013-04-07 22:00:46 +02003612 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003613 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003614
Paul Bakkerc70b9822013-04-07 22:00:46 +02003615 ret = oid_get_sig_alg_desc( &crl->sig_oid1, &desc );
3616 if( ret != 0 )
3617 ret = snprintf( p, n, "???" );
3618 else
3619 ret = snprintf( p, n, desc );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003620 SAFE_SNPRINTF();
3621
Paul Bakker1e27bb22009-07-19 20:25:25 +00003622 ret = snprintf( p, n, "\n" );
3623 SAFE_SNPRINTF();
3624
Paul Bakker23986e52011-04-24 08:57:21 +00003625 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003626}
3627
3628/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00003629 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00003630 */
Paul Bakkerfa9b1002013-07-03 15:31:03 +02003631#if defined(POLARSSL_HAVE_TIME)
Paul Bakkerff60ee62010-03-16 21:09:09 +00003632int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00003633{
Paul Bakkercce9d772011-11-18 14:26:47 +00003634 int year, mon, day;
3635 int hour, min, sec;
3636
3637#if defined(_WIN32)
3638 SYSTEMTIME st;
3639
3640 GetLocalTime(&st);
3641
3642 year = st.wYear;
3643 mon = st.wMonth;
3644 day = st.wDay;
3645 hour = st.wHour;
3646 min = st.wMinute;
3647 sec = st.wSecond;
3648#else
Paul Bakker5121ce52009-01-03 21:22:43 +00003649 struct tm *lt;
3650 time_t tt;
3651
3652 tt = time( NULL );
3653 lt = localtime( &tt );
3654
Paul Bakkercce9d772011-11-18 14:26:47 +00003655 year = lt->tm_year + 1900;
3656 mon = lt->tm_mon + 1;
3657 day = lt->tm_mday;
3658 hour = lt->tm_hour;
3659 min = lt->tm_min;
3660 sec = lt->tm_sec;
3661#endif
3662
3663 if( year > to->year )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003664 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003665
Paul Bakkercce9d772011-11-18 14:26:47 +00003666 if( year == to->year &&
3667 mon > to->mon )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003668 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003669
Paul Bakkercce9d772011-11-18 14:26:47 +00003670 if( year == to->year &&
3671 mon == to->mon &&
3672 day > to->day )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003673 return( 1 );
3674
Paul Bakkercce9d772011-11-18 14:26:47 +00003675 if( year == to->year &&
3676 mon == to->mon &&
3677 day == to->day &&
3678 hour > to->hour )
Paul Bakkerb6194992011-01-16 21:40:22 +00003679 return( 1 );
3680
Paul Bakkercce9d772011-11-18 14:26:47 +00003681 if( year == to->year &&
3682 mon == to->mon &&
3683 day == to->day &&
3684 hour == to->hour &&
3685 min > to->min )
Paul Bakkerb6194992011-01-16 21:40:22 +00003686 return( 1 );
3687
Paul Bakkercce9d772011-11-18 14:26:47 +00003688 if( year == to->year &&
3689 mon == to->mon &&
3690 day == to->day &&
3691 hour == to->hour &&
3692 min == to->min &&
3693 sec > to->sec )
Paul Bakkerb6194992011-01-16 21:40:22 +00003694 return( 1 );
3695
Paul Bakker40ea7de2009-05-03 10:18:48 +00003696 return( 0 );
3697}
Paul Bakkerfa9b1002013-07-03 15:31:03 +02003698#else /* POLARSSL_HAVE_TIME */
3699int x509parse_time_expired( const x509_time *to )
3700{
3701 ((void) to);
3702 return( 0 );
3703}
3704#endif /* POLARSSL_HAVE_TIME */
Paul Bakker40ea7de2009-05-03 10:18:48 +00003705
3706/*
3707 * Return 1 if the certificate is revoked, or 0 otherwise.
3708 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003709int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003710{
Paul Bakkerff60ee62010-03-16 21:09:09 +00003711 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00003712
3713 while( cur != NULL && cur->serial.len != 0 )
3714 {
Paul Bakkera056efc2011-01-16 21:38:35 +00003715 if( crt->serial.len == cur->serial.len &&
3716 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003717 {
3718 if( x509parse_time_expired( &cur->revocation_date ) )
3719 return( 1 );
3720 }
3721
3722 cur = cur->next;
3723 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003724
3725 return( 0 );
3726}
3727
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003728/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00003729 * Check that the given certificate is valid accoring to the CRL.
3730 */
3731static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
3732 x509_crl *crl_list)
3733{
3734 int flags = 0;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003735 unsigned char hash[POLARSSL_MD_MAX_SIZE];
3736 const md_info_t *md_info;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003737
Paul Bakker915275b2012-09-28 07:10:55 +00003738 if( ca == NULL )
3739 return( flags );
3740
Paul Bakker76fd75a2011-01-16 21:12:10 +00003741 /*
3742 * TODO: What happens if no CRL is present?
3743 * Suggestion: Revocation state should be unknown if no CRL is present.
3744 * For backwards compatibility this is not yet implemented.
3745 */
3746
Paul Bakker915275b2012-09-28 07:10:55 +00003747 while( crl_list != NULL )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003748 {
Paul Bakker915275b2012-09-28 07:10:55 +00003749 if( crl_list->version == 0 ||
3750 crl_list->issuer_raw.len != ca->subject_raw.len ||
Paul Bakker76fd75a2011-01-16 21:12:10 +00003751 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
3752 crl_list->issuer_raw.len ) != 0 )
3753 {
3754 crl_list = crl_list->next;
3755 continue;
3756 }
3757
3758 /*
3759 * Check if CRL is correctly signed by the trusted CA
3760 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02003761 md_info = md_info_from_type( crl_list->sig_md );
3762 if( md_info == NULL )
3763 {
3764 /*
3765 * Cannot check 'unknown' hash
3766 */
3767 flags |= BADCRL_NOT_TRUSTED;
3768 break;
3769 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00003770
Paul Bakkerc70b9822013-04-07 22:00:46 +02003771 md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
Paul Bakker76fd75a2011-01-16 21:12:10 +00003772
Paul Bakkerc70b9822013-04-07 22:00:46 +02003773 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, crl_list->sig_md,
Paul Bakker76fd75a2011-01-16 21:12:10 +00003774 0, hash, crl_list->sig.p ) == 0 )
3775 {
3776 /*
3777 * CRL is not trusted
3778 */
3779 flags |= BADCRL_NOT_TRUSTED;
3780 break;
3781 }
3782
3783 /*
3784 * Check for validity of CRL (Do not drop out)
3785 */
3786 if( x509parse_time_expired( &crl_list->next_update ) )
3787 flags |= BADCRL_EXPIRED;
3788
3789 /*
3790 * Check if certificate is revoked
3791 */
3792 if( x509parse_revoked(crt, crl_list) )
3793 {
3794 flags |= BADCERT_REVOKED;
3795 break;
3796 }
3797
3798 crl_list = crl_list->next;
3799 }
3800 return flags;
3801}
3802
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02003803static int x509_wildcard_verify( const char *cn, x509_buf *name )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003804{
3805 size_t i;
3806 size_t cn_idx = 0;
3807
Paul Bakker57b12982012-02-11 17:38:38 +00003808 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003809 return( 0 );
3810
3811 for( i = 0; i < strlen( cn ); ++i )
3812 {
3813 if( cn[i] == '.' )
3814 {
3815 cn_idx = i;
3816 break;
3817 }
3818 }
3819
3820 if( cn_idx == 0 )
3821 return( 0 );
3822
Paul Bakker535e97d2012-08-23 10:49:55 +00003823 if( strlen( cn ) - cn_idx == name->len - 1 &&
3824 memcmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003825 {
3826 return( 1 );
3827 }
3828
3829 return( 0 );
3830}
3831
Paul Bakker915275b2012-09-28 07:10:55 +00003832static int x509parse_verify_top(
3833 x509_cert *child, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003834 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003835 int (*f_vrfy)(void *, x509_cert *, int, int *),
3836 void *p_vrfy )
3837{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003838 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003839 int ca_flags = 0, check_path_cnt = path_cnt + 1;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003840 unsigned char hash[POLARSSL_MD_MAX_SIZE];
3841 const md_info_t *md_info;
Paul Bakker915275b2012-09-28 07:10:55 +00003842
3843 if( x509parse_time_expired( &child->valid_to ) )
3844 *flags |= BADCERT_EXPIRED;
3845
3846 /*
3847 * Child is the top of the chain. Check against the trust_ca list.
3848 */
3849 *flags |= BADCERT_NOT_TRUSTED;
3850
3851 while( trust_ca != NULL )
3852 {
3853 if( trust_ca->version == 0 ||
3854 child->issuer_raw.len != trust_ca->subject_raw.len ||
3855 memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
3856 child->issuer_raw.len ) != 0 )
3857 {
3858 trust_ca = trust_ca->next;
3859 continue;
3860 }
3861
Paul Bakker9a736322012-11-14 12:39:52 +00003862 /*
3863 * Reduce path_len to check against if top of the chain is
3864 * the same as the trusted CA
3865 */
3866 if( child->subject_raw.len == trust_ca->subject_raw.len &&
3867 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3868 child->issuer_raw.len ) == 0 )
3869 {
3870 check_path_cnt--;
3871 }
3872
Paul Bakker915275b2012-09-28 07:10:55 +00003873 if( trust_ca->max_pathlen > 0 &&
Paul Bakker9a736322012-11-14 12:39:52 +00003874 trust_ca->max_pathlen < check_path_cnt )
Paul Bakker915275b2012-09-28 07:10:55 +00003875 {
3876 trust_ca = trust_ca->next;
3877 continue;
3878 }
3879
Paul Bakkerc70b9822013-04-07 22:00:46 +02003880 md_info = md_info_from_type( child->sig_md );
3881 if( md_info == NULL )
3882 {
3883 /*
3884 * Cannot check 'unknown' hash
3885 */
3886 continue;
3887 }
Paul Bakker915275b2012-09-28 07:10:55 +00003888
Paul Bakkerc70b9822013-04-07 22:00:46 +02003889 md( md_info, child->tbs.p, child->tbs.len, hash );
Paul Bakker915275b2012-09-28 07:10:55 +00003890
Paul Bakkerc70b9822013-04-07 22:00:46 +02003891 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, child->sig_md,
Paul Bakker915275b2012-09-28 07:10:55 +00003892 0, hash, child->sig.p ) != 0 )
3893 {
3894 trust_ca = trust_ca->next;
3895 continue;
3896 }
3897
3898 /*
3899 * Top of chain is signed by a trusted CA
3900 */
3901 *flags &= ~BADCERT_NOT_TRUSTED;
3902 break;
3903 }
3904
Paul Bakker9a736322012-11-14 12:39:52 +00003905 /*
Paul Bakker3497d8c2012-11-24 11:53:17 +01003906 * If top of chain is not the same as the trusted CA send a verify request
3907 * to the callback for any issues with validity and CRL presence for the
3908 * trusted CA certificate.
Paul Bakker9a736322012-11-14 12:39:52 +00003909 */
3910 if( trust_ca != NULL &&
3911 ( child->subject_raw.len != trust_ca->subject_raw.len ||
3912 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3913 child->issuer_raw.len ) != 0 ) )
Paul Bakker915275b2012-09-28 07:10:55 +00003914 {
3915 /* Check trusted CA's CRL for then chain's top crt */
3916 *flags |= x509parse_verifycrl( child, trust_ca, ca_crl );
3917
3918 if( x509parse_time_expired( &trust_ca->valid_to ) )
3919 ca_flags |= BADCERT_EXPIRED;
3920
Paul Bakker915275b2012-09-28 07:10:55 +00003921 if( NULL != f_vrfy )
3922 {
Paul Bakker9a736322012-11-14 12:39:52 +00003923 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003924 return( ret );
3925 }
3926 }
3927
3928 /* Call callback on top cert */
3929 if( NULL != f_vrfy )
3930 {
Paul Bakker9a736322012-11-14 12:39:52 +00003931 if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003932 return( ret );
3933 }
3934
Paul Bakker915275b2012-09-28 07:10:55 +00003935 *flags |= ca_flags;
3936
3937 return( 0 );
3938}
3939
3940static int x509parse_verify_child(
3941 x509_cert *child, x509_cert *parent, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003942 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003943 int (*f_vrfy)(void *, x509_cert *, int, int *),
3944 void *p_vrfy )
3945{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003946 int ret;
Paul Bakker915275b2012-09-28 07:10:55 +00003947 int parent_flags = 0;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003948 unsigned char hash[POLARSSL_MD_MAX_SIZE];
Paul Bakker915275b2012-09-28 07:10:55 +00003949 x509_cert *grandparent;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003950 const md_info_t *md_info;
Paul Bakker915275b2012-09-28 07:10:55 +00003951
3952 if( x509parse_time_expired( &child->valid_to ) )
3953 *flags |= BADCERT_EXPIRED;
3954
Paul Bakkerc70b9822013-04-07 22:00:46 +02003955 md_info = md_info_from_type( child->sig_md );
3956 if( md_info == NULL )
3957 {
3958 /*
3959 * Cannot check 'unknown' hash
3960 */
Paul Bakker915275b2012-09-28 07:10:55 +00003961 *flags |= BADCERT_NOT_TRUSTED;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003962 }
3963 else
3964 {
3965 md( md_info, child->tbs.p, child->tbs.len, hash );
3966
3967 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, child->sig_md, 0, hash,
3968 child->sig.p ) != 0 )
3969 *flags |= BADCERT_NOT_TRUSTED;
3970 }
3971
Paul Bakker915275b2012-09-28 07:10:55 +00003972 /* Check trusted CA's CRL for the given crt */
3973 *flags |= x509parse_verifycrl(child, parent, ca_crl);
3974
3975 grandparent = parent->next;
3976
3977 while( grandparent != NULL )
3978 {
3979 if( grandparent->version == 0 ||
3980 grandparent->ca_istrue == 0 ||
3981 parent->issuer_raw.len != grandparent->subject_raw.len ||
3982 memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
3983 parent->issuer_raw.len ) != 0 )
3984 {
3985 grandparent = grandparent->next;
3986 continue;
3987 }
3988 break;
3989 }
3990
Paul Bakker915275b2012-09-28 07:10:55 +00003991 if( grandparent != NULL )
3992 {
3993 /*
3994 * Part of the chain
3995 */
Paul Bakker9a736322012-11-14 12:39:52 +00003996 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 +00003997 if( ret != 0 )
3998 return( ret );
3999 }
4000 else
4001 {
Paul Bakker9a736322012-11-14 12:39:52 +00004002 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 +00004003 if( ret != 0 )
4004 return( ret );
4005 }
4006
4007 /* child is verified to be a child of the parent, call verify callback */
4008 if( NULL != f_vrfy )
Paul Bakker9a736322012-11-14 12:39:52 +00004009 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00004010 return( ret );
Paul Bakker915275b2012-09-28 07:10:55 +00004011
4012 *flags |= parent_flags;
4013
4014 return( 0 );
4015}
4016
Paul Bakker76fd75a2011-01-16 21:12:10 +00004017/*
Paul Bakker5121ce52009-01-03 21:22:43 +00004018 * Verify the certificate validity
4019 */
4020int x509parse_verify( x509_cert *crt,
4021 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00004022 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00004023 const char *cn, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00004024 int (*f_vrfy)(void *, x509_cert *, int, int *),
Paul Bakkerb63b0af2011-01-13 17:54:59 +00004025 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00004026{
Paul Bakker23986e52011-04-24 08:57:21 +00004027 size_t cn_len;
Paul Bakker915275b2012-09-28 07:10:55 +00004028 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00004029 int pathlen = 0;
Paul Bakker76fd75a2011-01-16 21:12:10 +00004030 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00004031 x509_name *name;
Paul Bakkera8cd2392012-02-11 16:09:32 +00004032 x509_sequence *cur = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00004033
Paul Bakker40ea7de2009-05-03 10:18:48 +00004034 *flags = 0;
4035
Paul Bakker5121ce52009-01-03 21:22:43 +00004036 if( cn != NULL )
4037 {
4038 name = &crt->subject;
4039 cn_len = strlen( cn );
4040
Paul Bakker4d2c1242012-05-10 14:12:46 +00004041 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
Paul Bakker5121ce52009-01-03 21:22:43 +00004042 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00004043 cur = &crt->subject_alt_names;
4044
4045 while( cur != NULL )
Paul Bakkera8cd2392012-02-11 16:09:32 +00004046 {
Paul Bakker535e97d2012-08-23 10:49:55 +00004047 if( cur->buf.len == cn_len &&
4048 memcmp( cn, cur->buf.p, cn_len ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00004049 break;
4050
Paul Bakker535e97d2012-08-23 10:49:55 +00004051 if( cur->buf.len > 2 &&
4052 memcmp( cur->buf.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00004053 x509_wildcard_verify( cn, &cur->buf ) )
Paul Bakkera8cd2392012-02-11 16:09:32 +00004054 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00004055
Paul Bakker4d2c1242012-05-10 14:12:46 +00004056 cur = cur->next;
Paul Bakkera8cd2392012-02-11 16:09:32 +00004057 }
4058
4059 if( cur == NULL )
4060 *flags |= BADCERT_CN_MISMATCH;
4061 }
Paul Bakker4d2c1242012-05-10 14:12:46 +00004062 else
4063 {
4064 while( name != NULL )
4065 {
Paul Bakkerc70b9822013-04-07 22:00:46 +02004066 if( OID_CMP( OID_AT_CN, &name->oid ) )
Paul Bakker4d2c1242012-05-10 14:12:46 +00004067 {
Paul Bakker535e97d2012-08-23 10:49:55 +00004068 if( name->val.len == cn_len &&
4069 memcmp( name->val.p, cn, cn_len ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00004070 break;
4071
Paul Bakker535e97d2012-08-23 10:49:55 +00004072 if( name->val.len > 2 &&
4073 memcmp( name->val.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00004074 x509_wildcard_verify( cn, &name->val ) )
4075 break;
4076 }
4077
4078 name = name->next;
4079 }
4080
4081 if( name == NULL )
4082 *flags |= BADCERT_CN_MISMATCH;
4083 }
Paul Bakker5121ce52009-01-03 21:22:43 +00004084 }
4085
Paul Bakker5121ce52009-01-03 21:22:43 +00004086 /*
Paul Bakker915275b2012-09-28 07:10:55 +00004087 * Iterate upwards in the given cert chain, to find our crt parent.
4088 * Ignore any upper cert with CA != TRUE.
Paul Bakker5121ce52009-01-03 21:22:43 +00004089 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00004090 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00004091
Paul Bakker76fd75a2011-01-16 21:12:10 +00004092 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00004093 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00004094 if( parent->ca_istrue == 0 ||
4095 crt->issuer_raw.len != parent->subject_raw.len ||
4096 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00004097 crt->issuer_raw.len ) != 0 )
4098 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00004099 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00004100 continue;
4101 }
Paul Bakker915275b2012-09-28 07:10:55 +00004102 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00004103 }
4104
Paul Bakker915275b2012-09-28 07:10:55 +00004105 if( parent != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00004106 {
Paul Bakker915275b2012-09-28 07:10:55 +00004107 /*
4108 * Part of the chain
4109 */
Paul Bakker9a736322012-11-14 12:39:52 +00004110 ret = x509parse_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00004111 if( ret != 0 )
4112 return( ret );
4113 }
4114 else
Paul Bakker74111d32011-01-15 16:57:55 +00004115 {
Paul Bakker9a736322012-11-14 12:39:52 +00004116 ret = x509parse_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00004117 if( ret != 0 )
4118 return( ret );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00004119 }
Paul Bakker915275b2012-09-28 07:10:55 +00004120
4121 if( *flags != 0 )
Paul Bakker76fd75a2011-01-16 21:12:10 +00004122 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00004123
Paul Bakker5121ce52009-01-03 21:22:43 +00004124 return( 0 );
4125}
4126
4127/*
4128 * Unallocate all certificate data
4129 */
4130void x509_free( x509_cert *crt )
4131{
4132 x509_cert *cert_cur = crt;
4133 x509_cert *cert_prv;
4134 x509_name *name_cur;
4135 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00004136 x509_sequence *seq_cur;
4137 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00004138
4139 if( crt == NULL )
4140 return;
4141
4142 do
4143 {
4144 rsa_free( &cert_cur->rsa );
4145
4146 name_cur = cert_cur->issuer.next;
4147 while( name_cur != NULL )
4148 {
4149 name_prv = name_cur;
4150 name_cur = name_cur->next;
4151 memset( name_prv, 0, sizeof( x509_name ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02004152 polarssl_free( name_prv );
Paul Bakker5121ce52009-01-03 21:22:43 +00004153 }
4154
4155 name_cur = cert_cur->subject.next;
4156 while( name_cur != NULL )
4157 {
4158 name_prv = name_cur;
4159 name_cur = name_cur->next;
4160 memset( name_prv, 0, sizeof( x509_name ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02004161 polarssl_free( name_prv );
Paul Bakker5121ce52009-01-03 21:22:43 +00004162 }
4163
Paul Bakker74111d32011-01-15 16:57:55 +00004164 seq_cur = cert_cur->ext_key_usage.next;
4165 while( seq_cur != NULL )
4166 {
4167 seq_prv = seq_cur;
4168 seq_cur = seq_cur->next;
4169 memset( seq_prv, 0, sizeof( x509_sequence ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02004170 polarssl_free( seq_prv );
Paul Bakker74111d32011-01-15 16:57:55 +00004171 }
4172
Paul Bakker8afa70d2012-02-11 18:42:45 +00004173 seq_cur = cert_cur->subject_alt_names.next;
4174 while( seq_cur != NULL )
4175 {
4176 seq_prv = seq_cur;
4177 seq_cur = seq_cur->next;
4178 memset( seq_prv, 0, sizeof( x509_sequence ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02004179 polarssl_free( seq_prv );
Paul Bakker8afa70d2012-02-11 18:42:45 +00004180 }
4181
Paul Bakker5121ce52009-01-03 21:22:43 +00004182 if( cert_cur->raw.p != NULL )
4183 {
4184 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
Paul Bakker6e339b52013-07-03 13:37:05 +02004185 polarssl_free( cert_cur->raw.p );
Paul Bakker5121ce52009-01-03 21:22:43 +00004186 }
4187
4188 cert_cur = cert_cur->next;
4189 }
4190 while( cert_cur != NULL );
4191
4192 cert_cur = crt;
4193 do
4194 {
4195 cert_prv = cert_cur;
4196 cert_cur = cert_cur->next;
4197
4198 memset( cert_prv, 0, sizeof( x509_cert ) );
4199 if( cert_prv != crt )
Paul Bakker6e339b52013-07-03 13:37:05 +02004200 polarssl_free( cert_prv );
Paul Bakker5121ce52009-01-03 21:22:43 +00004201 }
4202 while( cert_cur != NULL );
4203}
4204
Paul Bakkerd98030e2009-05-02 15:13:40 +00004205/*
4206 * Unallocate all CRL data
4207 */
4208void x509_crl_free( x509_crl *crl )
4209{
4210 x509_crl *crl_cur = crl;
4211 x509_crl *crl_prv;
4212 x509_name *name_cur;
4213 x509_name *name_prv;
4214 x509_crl_entry *entry_cur;
4215 x509_crl_entry *entry_prv;
4216
4217 if( crl == NULL )
4218 return;
4219
4220 do
4221 {
4222 name_cur = crl_cur->issuer.next;
4223 while( name_cur != NULL )
4224 {
4225 name_prv = name_cur;
4226 name_cur = name_cur->next;
4227 memset( name_prv, 0, sizeof( x509_name ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02004228 polarssl_free( name_prv );
Paul Bakkerd98030e2009-05-02 15:13:40 +00004229 }
4230
4231 entry_cur = crl_cur->entry.next;
4232 while( entry_cur != NULL )
4233 {
4234 entry_prv = entry_cur;
4235 entry_cur = entry_cur->next;
4236 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02004237 polarssl_free( entry_prv );
Paul Bakkerd98030e2009-05-02 15:13:40 +00004238 }
4239
4240 if( crl_cur->raw.p != NULL )
4241 {
4242 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
Paul Bakker6e339b52013-07-03 13:37:05 +02004243 polarssl_free( crl_cur->raw.p );
Paul Bakkerd98030e2009-05-02 15:13:40 +00004244 }
4245
4246 crl_cur = crl_cur->next;
4247 }
4248 while( crl_cur != NULL );
4249
4250 crl_cur = crl;
4251 do
4252 {
4253 crl_prv = crl_cur;
4254 crl_cur = crl_cur->next;
4255
4256 memset( crl_prv, 0, sizeof( x509_crl ) );
4257 if( crl_prv != crl )
Paul Bakker6e339b52013-07-03 13:37:05 +02004258 polarssl_free( crl_prv );
Paul Bakkerd98030e2009-05-02 15:13:40 +00004259 }
4260 while( crl_cur != NULL );
4261}
4262
Paul Bakker40e46942009-01-03 21:51:57 +00004263#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00004264
Paul Bakker40e46942009-01-03 21:51:57 +00004265#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00004266
4267/*
4268 * Checkup routine
4269 */
4270int x509_self_test( int verbose )
4271{
Paul Bakker5690efc2011-05-26 13:16:06 +00004272#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00004273 int ret;
4274 int flags;
4275 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00004276 x509_cert cacert;
4277 x509_cert clicert;
4278 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00004279#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00004280 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00004281#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00004282
4283 if( verbose != 0 )
4284 printf( " X.509 certificate load: " );
4285
4286 memset( &clicert, 0, sizeof( x509_cert ) );
4287
Paul Bakker3c2122f2013-06-24 19:03:14 +02004288 ret = x509parse_crt( &clicert, (const unsigned char *) test_cli_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00004289 strlen( test_cli_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00004290 if( ret != 0 )
4291 {
4292 if( verbose != 0 )
4293 printf( "failed\n" );
4294
4295 return( ret );
4296 }
4297
4298 memset( &cacert, 0, sizeof( x509_cert ) );
4299
Paul Bakker3c2122f2013-06-24 19:03:14 +02004300 ret = x509parse_crt( &cacert, (const unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00004301 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00004302 if( ret != 0 )
4303 {
4304 if( verbose != 0 )
4305 printf( "failed\n" );
4306
4307 return( ret );
4308 }
4309
4310 if( verbose != 0 )
4311 printf( "passed\n X.509 private key load: " );
4312
4313 i = strlen( test_ca_key );
4314 j = strlen( test_ca_pwd );
4315
Paul Bakker66b78b22011-03-25 14:22:50 +00004316 rsa_init( &rsa, RSA_PKCS_V15, 0 );
4317
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02004318 if( ( ret = x509parse_key_rsa( &rsa,
Paul Bakker3c2122f2013-06-24 19:03:14 +02004319 (const unsigned char *) test_ca_key, i,
4320 (const unsigned char *) test_ca_pwd, j ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00004321 {
4322 if( verbose != 0 )
4323 printf( "failed\n" );
4324
4325 return( ret );
4326 }
4327
4328 if( verbose != 0 )
4329 printf( "passed\n X.509 signature verify: ");
4330
Paul Bakker23986e52011-04-24 08:57:21 +00004331 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00004332 if( ret != 0 )
4333 {
Paul Bakker23986e52011-04-24 08:57:21 +00004334 printf("%02x", flags);
Paul Bakker5121ce52009-01-03 21:22:43 +00004335 if( verbose != 0 )
4336 printf( "failed\n" );
4337
4338 return( ret );
4339 }
4340
Paul Bakker5690efc2011-05-26 13:16:06 +00004341#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00004342 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00004343 printf( "passed\n X.509 DHM parameter load: " );
4344
4345 i = strlen( test_dhm_params );
4346 j = strlen( test_ca_pwd );
4347
Paul Bakker3c2122f2013-06-24 19:03:14 +02004348 if( ( ret = x509parse_dhm( &dhm, (const unsigned char *) test_dhm_params, i ) ) != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00004349 {
4350 if( verbose != 0 )
4351 printf( "failed\n" );
4352
4353 return( ret );
4354 }
4355
4356 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00004357 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00004358#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00004359
4360 x509_free( &cacert );
4361 x509_free( &clicert );
4362 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00004363#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00004364 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00004365#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00004366
4367 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00004368#else
4369 ((void) verbose);
4370 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
4371#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00004372}
4373
4374#endif
4375
4376#endif