blob: 179ff959d7ef9ec01fbf72651f8dcd1ecb758497 [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
163/*
164 * AlgorithmIdentifier ::= SEQUENCE {
165 * algorithm OBJECT IDENTIFIER,
166 * parameters ANY DEFINED BY algorithm OPTIONAL }
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +0200167 *
168 * If params_end is NULL, then parameters must be absent or ANS.1 NULL
Paul Bakker5121ce52009-01-03 21:22:43 +0000169 */
170static int x509_get_alg( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000171 const unsigned char *end,
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +0200172 x509_buf *alg, const unsigned char **params_end )
Paul Bakker5121ce52009-01-03 21:22:43 +0000173{
Paul Bakker23986e52011-04-24 08:57:21 +0000174 int ret;
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +0200175 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000176
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +0200177 if( params_end == NULL ) {
178 if( ( ret = asn1_get_alg_null( p, end, alg ) ) != 0 )
179 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
180
181 return( 0 );
182 }
183
184 /* TODO: use asn1_get_alg */
185 if( ( ret = asn1_get_tag( p, end, &len,
186 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
187 {
188 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
189 }
190
191 end = *p + len;
192 alg->tag = **p;
193
194 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000195 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000196
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +0200197 alg->p = *p;
198 *p += alg->len;
199
200 *params_end = end;
Paul Bakker5121ce52009-01-03 21:22:43 +0000201 return( 0 );
202}
203
Manuel Pégourié-Gonnardf838eed2013-07-02 14:56:43 +0200204/* Get an EC group id from an ECParameters buffer
205 *
206 * ECParameters ::= CHOICE {
207 * namedCurve OBJECT IDENTIFIER
208 * -- implicitCurve NULL
209 * -- specifiedCurve SpecifiedECDomain
210 * }
211 */
212static int x509_get_ecparams( unsigned char **p, const unsigned char *end,
213 ecp_group_id *grp_id )
214{
215 int ret;
216 x509_buf curve;
217
218 curve.tag = **p;
219
220 if( ( ret = asn1_get_tag( p, end, &curve.len, ASN1_OID ) ) != 0 )
221 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
222
223 curve.p = *p;
224 *p += curve.len;
225
226 if( *p != end )
227 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
228 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
229
230 if( ( ret = oid_get_ec_grp( &curve, grp_id ) ) != 0 )
231 return( POLARSSL_ERR_X509_UNKNOWN_NAMED_CURVE );
232
233 return( 0 );
234}
235
Paul Bakker5121ce52009-01-03 21:22:43 +0000236/*
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +0200237 * subjectPublicKey BIT STRING
238 * -- which, in our case, contains
239 * ECPoint ::= octet string (not ASN.1)
240 */
241static int x509_get_subpubkey_ec( unsigned char **p, const unsigned char *end,
242 const ecp_group *grp, ecp_point *pt )
243{
244 int ret;
245 size_t len;
246
247 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
248 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
249
250 if( *p + len != end )
251 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
252 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
253
254 /*
255 * First byte in the content of BIT STRING is the nummber of padding bit.
256 * Here it is always 0 since ECPoint is an octet string, so skip it.
257 */
258 ++*p;
259 --len;
260
261 if( ( ret = ecp_point_read_binary( grp, pt,
262 (const unsigned char *) *p, len ) ) != 0 )
263 {
264 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
265 }
266
267 return( 0 );
268}
269
270/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000271 * AttributeTypeAndValue ::= SEQUENCE {
272 * type AttributeType,
273 * value AttributeValue }
274 *
275 * AttributeType ::= OBJECT IDENTIFIER
276 *
277 * AttributeValue ::= ANY DEFINED BY AttributeType
278 */
Paul Bakker400ff6f2011-02-20 10:40:16 +0000279static int x509_get_attr_type_value( unsigned char **p,
280 const unsigned char *end,
281 x509_name *cur )
Paul Bakker5121ce52009-01-03 21:22:43 +0000282{
Paul Bakker23986e52011-04-24 08:57:21 +0000283 int ret;
284 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000285 x509_buf *oid;
286 x509_buf *val;
287
288 if( ( ret = asn1_get_tag( p, end, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000289 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000290 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000291
Paul Bakker5121ce52009-01-03 21:22:43 +0000292 oid = &cur->oid;
293 oid->tag = **p;
294
295 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000296 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000297
298 oid->p = *p;
299 *p += oid->len;
300
301 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000302 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000303 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000304
305 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
306 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
307 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker9d781402011-05-09 16:17:09 +0000308 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000309 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000310
311 val = &cur->val;
312 val->tag = *(*p)++;
313
314 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000315 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000316
317 val->p = *p;
318 *p += val->len;
319
320 cur->next = NULL;
321
Paul Bakker400ff6f2011-02-20 10:40:16 +0000322 return( 0 );
323}
324
325/*
326 * RelativeDistinguishedName ::=
327 * SET OF AttributeTypeAndValue
328 *
329 * AttributeTypeAndValue ::= SEQUENCE {
330 * type AttributeType,
331 * value AttributeValue }
332 *
333 * AttributeType ::= OBJECT IDENTIFIER
334 *
335 * AttributeValue ::= ANY DEFINED BY AttributeType
336 */
337static int x509_get_name( unsigned char **p,
338 const unsigned char *end,
339 x509_name *cur )
340{
Paul Bakker23986e52011-04-24 08:57:21 +0000341 int ret;
342 size_t len;
Paul Bakker400ff6f2011-02-20 10:40:16 +0000343 const unsigned char *end2;
344 x509_name *use;
345
346 if( ( ret = asn1_get_tag( p, end, &len,
347 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000348 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000349
350 end2 = end;
351 end = *p + len;
352 use = cur;
353
354 do
355 {
356 if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
357 return( ret );
358
359 if( *p != end )
360 {
Paul Bakker6e339b52013-07-03 13:37:05 +0200361 use->next = (x509_name *) polarssl_malloc(
Paul Bakker400ff6f2011-02-20 10:40:16 +0000362 sizeof( x509_name ) );
363
364 if( use->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000365 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000366
367 memset( use->next, 0, sizeof( x509_name ) );
368
369 use = use->next;
370 }
371 }
372 while( *p != end );
Paul Bakker5121ce52009-01-03 21:22:43 +0000373
374 /*
375 * recurse until end of SEQUENCE is reached
376 */
377 if( *p == end2 )
378 return( 0 );
379
Paul Bakker6e339b52013-07-03 13:37:05 +0200380 cur->next = (x509_name *) polarssl_malloc(
Paul Bakker5121ce52009-01-03 21:22:43 +0000381 sizeof( x509_name ) );
382
383 if( cur->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000384 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000385
Paul Bakker430ffbe2012-05-01 08:14:20 +0000386 memset( cur->next, 0, sizeof( x509_name ) );
387
Paul Bakker5121ce52009-01-03 21:22:43 +0000388 return( x509_get_name( p, end2, cur->next ) );
389}
390
391/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000392 * Time ::= CHOICE {
393 * utcTime UTCTime,
394 * generalTime GeneralizedTime }
395 */
Paul Bakker91200182010-02-18 21:26:15 +0000396static int x509_get_time( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000397 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000398 x509_time *time )
399{
Paul Bakker23986e52011-04-24 08:57:21 +0000400 int ret;
401 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000402 char date[64];
Paul Bakker91200182010-02-18 21:26:15 +0000403 unsigned char tag;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000404
Paul Bakker91200182010-02-18 21:26:15 +0000405 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000406 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
407 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000408
Paul Bakker91200182010-02-18 21:26:15 +0000409 tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000410
Paul Bakker91200182010-02-18 21:26:15 +0000411 if ( tag == ASN1_UTC_TIME )
412 {
413 (*p)++;
414 ret = asn1_get_len( p, end, &len );
415
416 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000417 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000418
Paul Bakker91200182010-02-18 21:26:15 +0000419 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000420 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
421 len : sizeof( date ) - 1 );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000422
Paul Bakker91200182010-02-18 21:26:15 +0000423 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
424 &time->year, &time->mon, &time->day,
425 &time->hour, &time->min, &time->sec ) < 5 )
426 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000427
Paul Bakker400ff6f2011-02-20 10:40:16 +0000428 time->year += 100 * ( time->year < 50 );
Paul Bakker91200182010-02-18 21:26:15 +0000429 time->year += 1900;
430
431 *p += len;
432
433 return( 0 );
434 }
435 else if ( tag == ASN1_GENERALIZED_TIME )
436 {
437 (*p)++;
438 ret = asn1_get_len( p, end, &len );
439
440 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000441 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker91200182010-02-18 21:26:15 +0000442
443 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000444 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
445 len : sizeof( date ) - 1 );
Paul Bakker91200182010-02-18 21:26:15 +0000446
447 if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
448 &time->year, &time->mon, &time->day,
449 &time->hour, &time->min, &time->sec ) < 5 )
450 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
451
452 *p += len;
453
454 return( 0 );
455 }
456 else
Paul Bakker9d781402011-05-09 16:17:09 +0000457 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000458}
459
460
461/*
462 * Validity ::= SEQUENCE {
463 * notBefore Time,
464 * notAfter Time }
465 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000466static int x509_get_dates( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000467 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000468 x509_time *from,
469 x509_time *to )
470{
Paul Bakker23986e52011-04-24 08:57:21 +0000471 int ret;
472 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000473
474 if( ( ret = asn1_get_tag( p, end, &len,
475 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000476 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000477
478 end = *p + len;
479
Paul Bakker91200182010-02-18 21:26:15 +0000480 if( ( ret = x509_get_time( p, end, from ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000481 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000482
Paul Bakker91200182010-02-18 21:26:15 +0000483 if( ( ret = x509_get_time( p, end, to ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000484 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000485
486 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000487 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker40e46942009-01-03 21:51:57 +0000488 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000489
490 return( 0 );
491}
492
493/*
494 * SubjectPublicKeyInfo ::= SEQUENCE {
495 * algorithm AlgorithmIdentifier,
496 * subjectPublicKey BIT STRING }
497 */
498static int x509_get_pubkey( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000499 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000500 x509_buf *pk_alg_oid,
501 mpi *N, mpi *E )
502{
Paul Bakkerc70b9822013-04-07 22:00:46 +0200503 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000504 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000505 unsigned char *end2;
Paul Bakkerc70b9822013-04-07 22:00:46 +0200506 pk_type_t pk_alg = POLARSSL_PK_NONE;
Paul Bakker5121ce52009-01-03 21:22:43 +0000507
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200508 if( ( ret = asn1_get_alg_null( p, end, pk_alg_oid ) ) != 0 )
509 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000510
511 /*
512 * only RSA public keys handled at this time
513 */
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +0200514 if( oid_get_pk_alg( pk_alg_oid, &pk_alg ) != 0 )
Manuel Pégourié-Gonnard80300ad2013-07-04 11:57:13 +0200515 {
Paul Bakkered56b222011-07-13 11:26:43 +0000516 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
Manuel Pégourié-Gonnard80300ad2013-07-04 11:57:13 +0200517 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000518
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +0200519 if (pk_alg != POLARSSL_PK_RSA )
520 return( POLARSSL_ERR_X509_CERT_INVALID_ALG );
521
Paul Bakker5121ce52009-01-03 21:22:43 +0000522 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000523 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000524
525 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000526 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000527 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000528
529 end2 = *p + len;
530
531 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000532 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000533
534 /*
535 * RSAPublicKey ::= SEQUENCE {
536 * modulus INTEGER, -- n
537 * publicExponent INTEGER -- e
538 * }
539 */
540 if( ( ret = asn1_get_tag( p, end2, &len,
541 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000542 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000543
544 if( *p + len != end2 )
Paul Bakker9d781402011-05-09 16:17:09 +0000545 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000546 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000547
548 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
549 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000550 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000551
552 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000553 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000554 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000555
556 return( 0 );
557}
558
559static int x509_get_sig( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000560 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000561 x509_buf *sig )
562{
Paul Bakker23986e52011-04-24 08:57:21 +0000563 int ret;
564 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000565
Paul Bakker8afa70d2012-02-11 18:42:45 +0000566 if( ( end - *p ) < 1 )
567 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE +
568 POLARSSL_ERR_ASN1_OUT_OF_DATA );
569
Paul Bakker5121ce52009-01-03 21:22:43 +0000570 sig->tag = **p;
571
572 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000573 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000574
Paul Bakker74111d32011-01-15 16:57:55 +0000575
Paul Bakker5121ce52009-01-03 21:22:43 +0000576 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000577 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000578
579 sig->len = len;
580 sig->p = *p;
581
582 *p += len;
583
584 return( 0 );
585}
586
587/*
588 * X.509 v2/v3 unique identifier (not parsed)
589 */
590static int x509_get_uid( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000591 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000592 x509_buf *uid, int n )
593{
594 int ret;
595
596 if( *p == end )
597 return( 0 );
598
599 uid->tag = **p;
600
601 if( ( ret = asn1_get_tag( p, end, &uid->len,
602 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
603 {
Paul Bakker40e46942009-01-03 21:51:57 +0000604 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000605 return( 0 );
606
607 return( ret );
608 }
609
610 uid->p = *p;
611 *p += uid->len;
612
613 return( 0 );
614}
615
616/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000617 * X.509 Extensions (No parsing of extensions, pointer should
618 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000619 */
620static int x509_get_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000621 const unsigned char *end,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000622 x509_buf *ext, int tag )
Paul Bakker5121ce52009-01-03 21:22:43 +0000623{
Paul Bakker23986e52011-04-24 08:57:21 +0000624 int ret;
625 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000626
627 if( *p == end )
628 return( 0 );
629
630 ext->tag = **p;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000631
Paul Bakker5121ce52009-01-03 21:22:43 +0000632 if( ( ret = asn1_get_tag( p, end, &ext->len,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000633 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000634 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000635
636 ext->p = *p;
637 end = *p + ext->len;
638
639 /*
640 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
641 *
642 * Extension ::= SEQUENCE {
643 * extnID OBJECT IDENTIFIER,
644 * critical BOOLEAN DEFAULT FALSE,
645 * extnValue OCTET STRING }
646 */
647 if( ( ret = asn1_get_tag( p, end, &len,
648 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000649 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000650
651 if( end != *p + len )
Paul Bakker9d781402011-05-09 16:17:09 +0000652 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +0000653 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000654
Paul Bakkerd98030e2009-05-02 15:13:40 +0000655 return( 0 );
656}
657
658/*
659 * X.509 CRL v2 extensions (no extensions parsed yet.)
660 */
661static int x509_get_crl_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000662 const unsigned char *end,
663 x509_buf *ext )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000664{
Paul Bakker23986e52011-04-24 08:57:21 +0000665 int ret;
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000666 size_t len = 0;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000667
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000668 /* Get explicit tag */
669 if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000670 {
671 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
672 return( 0 );
673
674 return( ret );
675 }
676
677 while( *p < end )
678 {
679 if( ( ret = asn1_get_tag( p, end, &len,
680 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000681 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000682
683 *p += len;
684 }
685
686 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000687 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerd98030e2009-05-02 15:13:40 +0000688 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
689
690 return( 0 );
691}
692
Paul Bakkerb5a11ab2011-10-12 09:58:41 +0000693/*
694 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
695 */
696static int x509_get_crl_entry_ext( unsigned char **p,
697 const unsigned char *end,
698 x509_buf *ext )
699{
700 int ret;
701 size_t len = 0;
702
703 /* OPTIONAL */
704 if (end <= *p)
705 return( 0 );
706
707 ext->tag = **p;
708 ext->p = *p;
709
710 /*
711 * Get CRL-entry extension sequence header
712 * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
713 */
714 if( ( ret = asn1_get_tag( p, end, &ext->len,
715 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
716 {
717 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
718 {
719 ext->p = NULL;
720 return( 0 );
721 }
722 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
723 }
724
725 end = *p + ext->len;
726
727 if( end != *p + ext->len )
728 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
729 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
730
731 while( *p < end )
732 {
733 if( ( ret = asn1_get_tag( p, end, &len,
734 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
735 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
736
737 *p += len;
738 }
739
740 if( *p != end )
741 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
742 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
743
744 return( 0 );
745}
746
Paul Bakker74111d32011-01-15 16:57:55 +0000747static int x509_get_basic_constraints( unsigned char **p,
748 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000749 int *ca_istrue,
750 int *max_pathlen )
751{
Paul Bakker23986e52011-04-24 08:57:21 +0000752 int ret;
753 size_t len;
Paul Bakker74111d32011-01-15 16:57:55 +0000754
755 /*
756 * BasicConstraints ::= SEQUENCE {
757 * cA BOOLEAN DEFAULT FALSE,
758 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
759 */
Paul Bakker3cccddb2011-01-16 21:46:31 +0000760 *ca_istrue = 0; /* DEFAULT FALSE */
Paul Bakker74111d32011-01-15 16:57:55 +0000761 *max_pathlen = 0; /* endless */
762
763 if( ( ret = asn1_get_tag( p, end, &len,
764 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000765 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000766
767 if( *p == end )
768 return 0;
769
Paul Bakker3cccddb2011-01-16 21:46:31 +0000770 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000771 {
772 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker3cccddb2011-01-16 21:46:31 +0000773 ret = asn1_get_int( p, end, ca_istrue );
Paul Bakker74111d32011-01-15 16:57:55 +0000774
775 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000776 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000777
Paul Bakker3cccddb2011-01-16 21:46:31 +0000778 if( *ca_istrue != 0 )
779 *ca_istrue = 1;
Paul Bakker74111d32011-01-15 16:57:55 +0000780 }
781
782 if( *p == end )
783 return 0;
784
785 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000786 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000787
788 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000789 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000790 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
791
792 (*max_pathlen)++;
793
Paul Bakker74111d32011-01-15 16:57:55 +0000794 return 0;
795}
796
797static int x509_get_ns_cert_type( unsigned char **p,
798 const unsigned char *end,
799 unsigned char *ns_cert_type)
800{
801 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000802 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000803
804 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000805 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000806
807 if( bs.len != 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000808 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000809 POLARSSL_ERR_ASN1_INVALID_LENGTH );
810
811 /* Get actual bitstring */
812 *ns_cert_type = *bs.p;
813 return 0;
814}
815
816static int x509_get_key_usage( unsigned char **p,
817 const unsigned char *end,
818 unsigned char *key_usage)
819{
820 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000821 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000822
823 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000824 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000825
Paul Bakker94a67962012-08-23 13:03:52 +0000826 if( bs.len < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000827 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000828 POLARSSL_ERR_ASN1_INVALID_LENGTH );
829
830 /* Get actual bitstring */
831 *key_usage = *bs.p;
832 return 0;
833}
834
Paul Bakkerd98030e2009-05-02 15:13:40 +0000835/*
Paul Bakker74111d32011-01-15 16:57:55 +0000836 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
837 *
838 * KeyPurposeId ::= OBJECT IDENTIFIER
839 */
840static int x509_get_ext_key_usage( unsigned char **p,
841 const unsigned char *end,
842 x509_sequence *ext_key_usage)
843{
844 int ret;
845
846 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000847 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000848
849 /* Sequence length must be >= 1 */
850 if( ext_key_usage->buf.p == NULL )
Paul Bakker9d781402011-05-09 16:17:09 +0000851 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000852 POLARSSL_ERR_ASN1_INVALID_LENGTH );
853
854 return 0;
855}
856
857/*
Paul Bakkera8cd2392012-02-11 16:09:32 +0000858 * SubjectAltName ::= GeneralNames
859 *
860 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
861 *
862 * GeneralName ::= CHOICE {
863 * otherName [0] OtherName,
864 * rfc822Name [1] IA5String,
865 * dNSName [2] IA5String,
866 * x400Address [3] ORAddress,
867 * directoryName [4] Name,
868 * ediPartyName [5] EDIPartyName,
869 * uniformResourceIdentifier [6] IA5String,
870 * iPAddress [7] OCTET STRING,
871 * registeredID [8] OBJECT IDENTIFIER }
872 *
873 * OtherName ::= SEQUENCE {
874 * type-id OBJECT IDENTIFIER,
875 * value [0] EXPLICIT ANY DEFINED BY type-id }
876 *
877 * EDIPartyName ::= SEQUENCE {
878 * nameAssigner [0] DirectoryString OPTIONAL,
879 * partyName [1] DirectoryString }
880 *
881 * NOTE: PolarSSL only parses and uses dNSName at this point.
882 */
883static int x509_get_subject_alt_name( unsigned char **p,
884 const unsigned char *end,
885 x509_sequence *subject_alt_name )
886{
887 int ret;
888 size_t len, tag_len;
889 asn1_buf *buf;
890 unsigned char tag;
891 asn1_sequence *cur = subject_alt_name;
892
893 /* Get main sequence tag */
894 if( ( ret = asn1_get_tag( p, end, &len,
895 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
896 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
897
898 if( *p + len != end )
899 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
900 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
901
902 while( *p < end )
903 {
904 if( ( end - *p ) < 1 )
905 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
906 POLARSSL_ERR_ASN1_OUT_OF_DATA );
907
908 tag = **p;
909 (*p)++;
910 if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 )
911 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
912
913 if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC )
914 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
915 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
916
917 if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) )
918 {
919 *p += tag_len;
920 continue;
921 }
922
923 buf = &(cur->buf);
924 buf->tag = tag;
925 buf->p = *p;
926 buf->len = tag_len;
927 *p += buf->len;
928
929 /* Allocate and assign next pointer */
930 if (*p < end)
931 {
Paul Bakker6e339b52013-07-03 13:37:05 +0200932 cur->next = (asn1_sequence *) polarssl_malloc(
Paul Bakkera8cd2392012-02-11 16:09:32 +0000933 sizeof( asn1_sequence ) );
934
935 if( cur->next == NULL )
936 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
937 POLARSSL_ERR_ASN1_MALLOC_FAILED );
938
Paul Bakker535e97d2012-08-23 10:49:55 +0000939 memset( cur->next, 0, sizeof( asn1_sequence ) );
Paul Bakkera8cd2392012-02-11 16:09:32 +0000940 cur = cur->next;
941 }
942 }
943
944 /* Set final sequence entry's next pointer to NULL */
945 cur->next = NULL;
946
947 if( *p != end )
948 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
949 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
950
951 return( 0 );
952}
953
954/*
Paul Bakker74111d32011-01-15 16:57:55 +0000955 * X.509 v3 extensions
956 *
957 * TODO: Perform all of the basic constraints tests required by the RFC
958 * TODO: Set values for undetected extensions to a sane default?
959 *
Paul Bakkerd98030e2009-05-02 15:13:40 +0000960 */
961static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000962 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000963 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000964{
Paul Bakker23986e52011-04-24 08:57:21 +0000965 int ret;
966 size_t len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000967 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000968
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000969 if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000970 {
971 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
972 return( 0 );
973
974 return( ret );
975 }
976
Paul Bakker5121ce52009-01-03 21:22:43 +0000977 while( *p < end )
978 {
Paul Bakker74111d32011-01-15 16:57:55 +0000979 /*
980 * Extension ::= SEQUENCE {
981 * extnID OBJECT IDENTIFIER,
982 * critical BOOLEAN DEFAULT FALSE,
983 * extnValue OCTET STRING }
984 */
985 x509_buf extn_oid = {0, 0, NULL};
986 int is_critical = 0; /* DEFAULT FALSE */
Paul Bakkerc70b9822013-04-07 22:00:46 +0200987 int ext_type = 0;
Paul Bakker74111d32011-01-15 16:57:55 +0000988
Paul Bakker5121ce52009-01-03 21:22:43 +0000989 if( ( ret = asn1_get_tag( p, end, &len,
990 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000991 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000992
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000993 end_ext_data = *p + len;
994
Paul Bakker74111d32011-01-15 16:57:55 +0000995 /* Get extension ID */
996 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000997
Paul Bakker74111d32011-01-15 16:57:55 +0000998 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000999 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001000
Paul Bakker74111d32011-01-15 16:57:55 +00001001 extn_oid.p = *p;
1002 *p += extn_oid.len;
1003
1004 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +00001005 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +00001006 POLARSSL_ERR_ASN1_OUT_OF_DATA );
1007
1008 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001009 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +00001010 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
Paul Bakker9d781402011-05-09 16:17:09 +00001011 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001012
Paul Bakker74111d32011-01-15 16:57:55 +00001013 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001014 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +00001015 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +00001016 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001017
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001018 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +00001019
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001020 if( end_ext_octet != end_ext_data )
Paul Bakker9d781402011-05-09 16:17:09 +00001021 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001022 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001023
Paul Bakker74111d32011-01-15 16:57:55 +00001024 /*
1025 * Detect supported extensions
1026 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02001027 ret = oid_get_x509_ext_type( &extn_oid, &ext_type );
1028
1029 if( ret != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +00001030 {
1031 /* No parser found, skip extension */
1032 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +00001033
Paul Bakker5c721f92011-07-27 16:51:09 +00001034#if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
Paul Bakker74111d32011-01-15 16:57:55 +00001035 if( is_critical )
1036 {
1037 /* Data is marked as critical: fail */
Paul Bakker9d781402011-05-09 16:17:09 +00001038 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +00001039 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
1040 }
Paul Bakker5c721f92011-07-27 16:51:09 +00001041#endif
Paul Bakkerc70b9822013-04-07 22:00:46 +02001042 continue;
1043 }
1044
1045 crt->ext_types |= ext_type;
1046
1047 switch( ext_type )
1048 {
1049 case EXT_BASIC_CONSTRAINTS:
1050 /* Parse basic constraints */
1051 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
1052 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
1053 return ( ret );
1054 break;
1055
1056 case EXT_KEY_USAGE:
1057 /* Parse key usage */
1058 if( ( ret = x509_get_key_usage( p, end_ext_octet,
1059 &crt->key_usage ) ) != 0 )
1060 return ( ret );
1061 break;
1062
1063 case EXT_EXTENDED_KEY_USAGE:
1064 /* Parse extended key usage */
1065 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
1066 &crt->ext_key_usage ) ) != 0 )
1067 return ( ret );
1068 break;
1069
1070 case EXT_SUBJECT_ALT_NAME:
1071 /* Parse subject alt name */
1072 if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
1073 &crt->subject_alt_names ) ) != 0 )
1074 return ( ret );
1075 break;
1076
1077 case EXT_NS_CERT_TYPE:
1078 /* Parse netscape certificate type */
1079 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
1080 &crt->ns_cert_type ) ) != 0 )
1081 return ( ret );
1082 break;
1083
1084 default:
1085 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker74111d32011-01-15 16:57:55 +00001086 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001087 }
1088
1089 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +00001090 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +00001091 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001092
Paul Bakker5121ce52009-01-03 21:22:43 +00001093 return( 0 );
1094}
1095
1096/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001097 * X.509 CRL Entries
1098 */
1099static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001100 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001101 x509_crl_entry *entry )
1102{
Paul Bakker23986e52011-04-24 08:57:21 +00001103 int ret;
1104 size_t entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001105 x509_crl_entry *cur_entry = entry;
1106
1107 if( *p == end )
1108 return( 0 );
1109
Paul Bakker9be19372009-07-27 20:21:53 +00001110 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001111 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1112 {
1113 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
1114 return( 0 );
1115
1116 return( ret );
1117 }
1118
Paul Bakker9be19372009-07-27 20:21:53 +00001119 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001120
1121 while( *p < end )
1122 {
Paul Bakker23986e52011-04-24 08:57:21 +00001123 size_t len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001124 const unsigned char *end2;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001125
1126 if( ( ret = asn1_get_tag( p, end, &len2,
1127 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1128 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001129 return( ret );
1130 }
1131
Paul Bakker9be19372009-07-27 20:21:53 +00001132 cur_entry->raw.tag = **p;
1133 cur_entry->raw.p = *p;
1134 cur_entry->raw.len = len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001135 end2 = *p + len2;
Paul Bakker9be19372009-07-27 20:21:53 +00001136
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001137 if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001138 return( ret );
1139
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001140 if( ( ret = x509_get_time( p, end2, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001141 return( ret );
1142
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001143 if( ( ret = x509_get_crl_entry_ext( p, end2, &cur_entry->entry_ext ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001144 return( ret );
1145
Paul Bakker74111d32011-01-15 16:57:55 +00001146 if ( *p < end )
1147 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001148 cur_entry->next = polarssl_malloc( sizeof( x509_crl_entry ) );
Paul Bakkerb15b8512012-01-13 13:44:06 +00001149
1150 if( cur_entry->next == NULL )
1151 return( POLARSSL_ERR_X509_MALLOC_FAILED );
1152
Paul Bakkerd98030e2009-05-02 15:13:40 +00001153 cur_entry = cur_entry->next;
1154 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
1155 }
1156 }
1157
1158 return( 0 );
1159}
1160
Paul Bakkerc70b9822013-04-07 22:00:46 +02001161static int x509_get_sig_alg( const x509_buf *sig_oid, md_type_t *md_alg,
1162 pk_type_t *pk_alg )
Paul Bakker27d66162010-03-17 06:56:01 +00001163{
Paul Bakkerc70b9822013-04-07 22:00:46 +02001164 int ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg );
Paul Bakker27d66162010-03-17 06:56:01 +00001165
Paul Bakkerc70b9822013-04-07 22:00:46 +02001166 if( ret != 0 )
1167 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG + ret );
Paul Bakker27d66162010-03-17 06:56:01 +00001168
Paul Bakkerc70b9822013-04-07 22:00:46 +02001169 return( 0 );
Paul Bakker27d66162010-03-17 06:56:01 +00001170}
1171
Paul Bakkerd98030e2009-05-02 15:13:40 +00001172/*
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001173 * Parse and fill a single X.509 certificate in DER format
Paul Bakker5121ce52009-01-03 21:22:43 +00001174 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02001175static int x509parse_crt_der_core( x509_cert *crt, const unsigned char *buf,
1176 size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001177{
Paul Bakker23986e52011-04-24 08:57:21 +00001178 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001179 size_t len;
Paul Bakkerb00ca422012-09-25 12:10:00 +00001180 unsigned char *p, *end, *crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001181
Paul Bakker320a4b52009-03-28 18:52:39 +00001182 /*
1183 * Check for valid input
1184 */
1185 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001186 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker320a4b52009-03-28 18:52:39 +00001187
Paul Bakker6e339b52013-07-03 13:37:05 +02001188 p = (unsigned char *) polarssl_malloc( len = buflen );
Paul Bakker96743fc2011-02-12 14:30:57 +00001189
1190 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001191 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001192
1193 memcpy( p, buf, buflen );
1194
1195 buflen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001196
1197 crt->raw.p = p;
1198 crt->raw.len = len;
1199 end = p + len;
1200
1201 /*
1202 * Certificate ::= SEQUENCE {
1203 * tbsCertificate TBSCertificate,
1204 * signatureAlgorithm AlgorithmIdentifier,
1205 * signatureValue BIT STRING }
1206 */
1207 if( ( ret = asn1_get_tag( &p, end, &len,
1208 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1209 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001210 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001211 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001212 }
1213
Paul Bakkerb00ca422012-09-25 12:10:00 +00001214 if( len > (size_t) ( end - p ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001215 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001216 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001217 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001218 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001219 }
Paul Bakkerb00ca422012-09-25 12:10:00 +00001220 crt_end = p + len;
Paul Bakker42c65812013-06-24 19:21:59 +02001221
Paul Bakker5121ce52009-01-03 21:22:43 +00001222 /*
1223 * TBSCertificate ::= SEQUENCE {
1224 */
1225 crt->tbs.p = p;
1226
1227 if( ( ret = asn1_get_tag( &p, end, &len,
1228 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1229 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001230 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001231 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001232 }
1233
1234 end = p + len;
1235 crt->tbs.len = end - crt->tbs.p;
1236
1237 /*
1238 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1239 *
1240 * CertificateSerialNumber ::= INTEGER
1241 *
1242 * signature AlgorithmIdentifier
1243 */
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +02001244 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1245 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1246 ( ret = x509_get_alg( &p, end, &crt->sig_oid1, NULL ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001247 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001248 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001249 return( ret );
1250 }
1251
1252 crt->version++;
1253
1254 if( crt->version > 3 )
1255 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001256 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001257 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001258 }
1259
Paul Bakkerc70b9822013-04-07 22:00:46 +02001260 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_md,
1261 &crt->sig_pk ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001262 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001263 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001264 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001265 }
1266
1267 /*
1268 * issuer Name
1269 */
1270 crt->issuer_raw.p = p;
1271
1272 if( ( ret = asn1_get_tag( &p, end, &len,
1273 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1274 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001275 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001276 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001277 }
1278
1279 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1280 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001281 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001282 return( ret );
1283 }
1284
1285 crt->issuer_raw.len = p - crt->issuer_raw.p;
1286
1287 /*
1288 * Validity ::= SEQUENCE {
1289 * notBefore Time,
1290 * notAfter Time }
1291 *
1292 */
1293 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1294 &crt->valid_to ) ) != 0 )
1295 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001296 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001297 return( ret );
1298 }
1299
1300 /*
1301 * subject Name
1302 */
1303 crt->subject_raw.p = p;
1304
1305 if( ( ret = asn1_get_tag( &p, end, &len,
1306 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1307 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001308 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001309 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001310 }
1311
Paul Bakkercefb3962012-06-27 11:51:09 +00001312 if( len && ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001313 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001314 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001315 return( ret );
1316 }
1317
1318 crt->subject_raw.len = p - crt->subject_raw.p;
1319
1320 /*
1321 * SubjectPublicKeyInfo ::= SEQUENCE
1322 * algorithm AlgorithmIdentifier,
1323 * subjectPublicKey BIT STRING }
1324 */
1325 if( ( ret = asn1_get_tag( &p, end, &len,
1326 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1327 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001328 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001329 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001330 }
1331
1332 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1333 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1334 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001335 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001336 return( ret );
1337 }
1338
1339 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1340 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001341 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001342 return( ret );
1343 }
1344
1345 crt->rsa.len = mpi_size( &crt->rsa.N );
1346
1347 /*
1348 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1349 * -- If present, version shall be v2 or v3
1350 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1351 * -- If present, version shall be v2 or v3
1352 * extensions [3] EXPLICIT Extensions OPTIONAL
1353 * -- If present, version shall be v3
1354 */
1355 if( crt->version == 2 || crt->version == 3 )
1356 {
1357 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1358 if( ret != 0 )
1359 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001360 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001361 return( ret );
1362 }
1363 }
1364
1365 if( crt->version == 2 || crt->version == 3 )
1366 {
1367 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1368 if( ret != 0 )
1369 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001370 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001371 return( ret );
1372 }
1373 }
1374
1375 if( crt->version == 3 )
1376 {
Paul Bakker74111d32011-01-15 16:57:55 +00001377 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001378 if( ret != 0 )
1379 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001380 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001381 return( ret );
1382 }
1383 }
1384
1385 if( p != end )
1386 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001387 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001388 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001389 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001390 }
1391
Paul Bakkerb00ca422012-09-25 12:10:00 +00001392 end = crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001393
1394 /*
1395 * signatureAlgorithm AlgorithmIdentifier,
1396 * signatureValue BIT STRING
1397 */
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +02001398 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2, NULL ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001399 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001400 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001401 return( ret );
1402 }
1403
Paul Bakker535e97d2012-08-23 10:49:55 +00001404 if( crt->sig_oid1.len != crt->sig_oid2.len ||
1405 memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001406 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001407 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001408 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001409 }
1410
1411 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1412 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001413 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001414 return( ret );
1415 }
1416
1417 if( p != end )
1418 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001419 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001420 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001421 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001422 }
1423
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001424 return( 0 );
1425}
1426
1427/*
Paul Bakker42c65812013-06-24 19:21:59 +02001428 * Parse one X.509 certificate in DER format from a buffer and add them to a
1429 * chained list
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001430 */
Paul Bakker42c65812013-06-24 19:21:59 +02001431int x509parse_crt_der( x509_cert *chain, const unsigned char *buf, size_t buflen )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001432{
Paul Bakker42c65812013-06-24 19:21:59 +02001433 int ret;
1434 x509_cert *crt = chain, *prev = NULL;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001435
1436 /*
1437 * Check for valid input
1438 */
1439 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001440 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001441
1442 while( crt->version != 0 && crt->next != NULL )
1443 {
1444 prev = crt;
1445 crt = crt->next;
1446 }
1447
1448 /*
1449 * Add new certificate on the end of the chain if needed.
1450 */
1451 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001452 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001453 crt->next = (x509_cert *) polarssl_malloc( sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001454
Paul Bakker7d06ad22009-05-02 15:53:56 +00001455 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001456 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker320a4b52009-03-28 18:52:39 +00001457
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001458 prev = crt;
Paul Bakker7d06ad22009-05-02 15:53:56 +00001459 crt = crt->next;
1460 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001461 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001462
Paul Bakker42c65812013-06-24 19:21:59 +02001463 if( ( ret = x509parse_crt_der_core( crt, buf, buflen ) ) != 0 )
1464 {
1465 if( prev )
1466 prev->next = NULL;
1467
1468 if( crt != chain )
Paul Bakker6e339b52013-07-03 13:37:05 +02001469 polarssl_free( crt );
Paul Bakker42c65812013-06-24 19:21:59 +02001470
1471 return( ret );
1472 }
1473
1474 return( 0 );
1475}
1476
1477/*
1478 * Parse one or more PEM certificates from a buffer and add them to the chained list
1479 */
1480int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
1481{
1482 int ret, success = 0, first_error = 0, total_failed = 0;
1483 int buf_format = X509_FORMAT_DER;
1484
1485 /*
1486 * Check for valid input
1487 */
1488 if( chain == NULL || buf == NULL )
1489 return( POLARSSL_ERR_X509_INVALID_INPUT );
1490
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001491 /*
1492 * Determine buffer content. Buffer contains either one DER certificate or
1493 * one or more PEM certificates.
1494 */
1495#if defined(POLARSSL_PEM_C)
Paul Bakker3c2122f2013-06-24 19:03:14 +02001496 if( strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001497 buf_format = X509_FORMAT_PEM;
1498#endif
1499
1500 if( buf_format == X509_FORMAT_DER )
Paul Bakker42c65812013-06-24 19:21:59 +02001501 return x509parse_crt_der( chain, buf, buflen );
1502
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001503#if defined(POLARSSL_PEM_C)
1504 if( buf_format == X509_FORMAT_PEM )
1505 {
1506 pem_context pem;
1507
1508 while( buflen > 0 )
1509 {
1510 size_t use_len;
1511 pem_init( &pem );
1512
1513 ret = pem_read_buffer( &pem,
1514 "-----BEGIN CERTIFICATE-----",
1515 "-----END CERTIFICATE-----",
1516 buf, NULL, 0, &use_len );
1517
1518 if( ret == 0 )
1519 {
1520 /*
1521 * Was PEM encoded
1522 */
1523 buflen -= use_len;
1524 buf += use_len;
1525 }
Paul Bakker5ed3b342013-06-24 19:05:46 +02001526 else if( ret == POLARSSL_ERR_PEM_BAD_INPUT_DATA )
1527 {
1528 return( ret );
1529 }
Paul Bakker00b28602013-06-24 13:02:41 +02001530 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001531 {
1532 pem_free( &pem );
1533
Paul Bakker5ed3b342013-06-24 19:05:46 +02001534 /*
1535 * PEM header and footer were found
1536 */
1537 buflen -= use_len;
1538 buf += use_len;
1539
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001540 if( first_error == 0 )
1541 first_error = ret;
1542
1543 continue;
1544 }
1545 else
1546 break;
1547
Paul Bakker42c65812013-06-24 19:21:59 +02001548 ret = x509parse_crt_der( chain, pem.buf, pem.buflen );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001549
1550 pem_free( &pem );
1551
1552 if( ret != 0 )
1553 {
1554 /*
Paul Bakker42c65812013-06-24 19:21:59 +02001555 * Quit parsing on a memory error
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001556 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001557 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001558 return( ret );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001559
1560 if( first_error == 0 )
1561 first_error = ret;
1562
Paul Bakker42c65812013-06-24 19:21:59 +02001563 total_failed++;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001564 continue;
1565 }
1566
1567 success = 1;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001568 }
1569 }
1570#endif
1571
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001572 if( success )
Paul Bakker69e095c2011-12-10 21:55:01 +00001573 return( total_failed );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001574 else if( first_error )
1575 return( first_error );
1576 else
1577 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001578}
1579
1580/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001581 * Parse one or more CRLs and add them to the chained list
1582 */
Paul Bakker23986e52011-04-24 08:57:21 +00001583int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001584{
Paul Bakker23986e52011-04-24 08:57:21 +00001585 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001586 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001587 unsigned char *p, *end;
1588 x509_crl *crl;
Paul Bakker96743fc2011-02-12 14:30:57 +00001589#if defined(POLARSSL_PEM_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00001590 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001591 pem_context pem;
1592#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001593
1594 crl = chain;
1595
1596 /*
1597 * Check for valid input
1598 */
1599 if( crl == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001600 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001601
1602 while( crl->version != 0 && crl->next != NULL )
1603 crl = crl->next;
1604
1605 /*
1606 * Add new CRL on the end of the chain if needed.
1607 */
1608 if ( crl->version != 0 && crl->next == NULL)
1609 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001610 crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001611
Paul Bakker7d06ad22009-05-02 15:53:56 +00001612 if( crl->next == NULL )
1613 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001614 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001615 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001616 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001617
Paul Bakker7d06ad22009-05-02 15:53:56 +00001618 crl = crl->next;
1619 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001620 }
1621
Paul Bakker96743fc2011-02-12 14:30:57 +00001622#if defined(POLARSSL_PEM_C)
1623 pem_init( &pem );
1624 ret = pem_read_buffer( &pem,
1625 "-----BEGIN X509 CRL-----",
1626 "-----END X509 CRL-----",
1627 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001628
Paul Bakker96743fc2011-02-12 14:30:57 +00001629 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001630 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001631 /*
1632 * Was PEM encoded
1633 */
1634 buflen -= use_len;
1635 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001636
1637 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001638 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001639 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001640 p = pem.buf;
1641 pem.buf = NULL;
1642 len = pem.buflen;
1643 pem_free( &pem );
1644 }
Paul Bakker00b28602013-06-24 13:02:41 +02001645 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker96743fc2011-02-12 14:30:57 +00001646 {
1647 pem_free( &pem );
1648 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001649 }
1650 else
1651 {
1652 /*
1653 * nope, copy the raw DER data
1654 */
Paul Bakker6e339b52013-07-03 13:37:05 +02001655 p = (unsigned char *) polarssl_malloc( len = buflen );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001656
1657 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001658 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001659
1660 memcpy( p, buf, buflen );
1661
1662 buflen = 0;
1663 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001664#else
Paul Bakker6e339b52013-07-03 13:37:05 +02001665 p = (unsigned char *) polarssl_malloc( len = buflen );
Paul Bakker96743fc2011-02-12 14:30:57 +00001666
1667 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001668 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001669
1670 memcpy( p, buf, buflen );
1671
1672 buflen = 0;
1673#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001674
1675 crl->raw.p = p;
1676 crl->raw.len = len;
1677 end = p + len;
1678
1679 /*
1680 * CertificateList ::= SEQUENCE {
1681 * tbsCertList TBSCertList,
1682 * signatureAlgorithm AlgorithmIdentifier,
1683 * signatureValue BIT STRING }
1684 */
1685 if( ( ret = asn1_get_tag( &p, end, &len,
1686 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1687 {
1688 x509_crl_free( crl );
1689 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1690 }
1691
Paul Bakker23986e52011-04-24 08:57:21 +00001692 if( len != (size_t) ( end - p ) )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001693 {
1694 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001695 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001696 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1697 }
1698
1699 /*
1700 * TBSCertList ::= SEQUENCE {
1701 */
1702 crl->tbs.p = p;
1703
1704 if( ( ret = asn1_get_tag( &p, end, &len,
1705 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1706 {
1707 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001708 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001709 }
1710
1711 end = p + len;
1712 crl->tbs.len = end - crl->tbs.p;
1713
1714 /*
1715 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1716 * -- if present, MUST be v2
1717 *
1718 * signature AlgorithmIdentifier
1719 */
Paul Bakker3329d1f2011-10-12 09:55:01 +00001720 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +02001721 ( ret = x509_get_alg( &p, end, &crl->sig_oid1, NULL ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001722 {
1723 x509_crl_free( crl );
1724 return( ret );
1725 }
1726
1727 crl->version++;
1728
1729 if( crl->version > 2 )
1730 {
1731 x509_crl_free( crl );
1732 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1733 }
1734
Paul Bakkerc70b9822013-04-07 22:00:46 +02001735 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_md,
1736 &crl->sig_pk ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001737 {
1738 x509_crl_free( crl );
1739 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1740 }
1741
1742 /*
1743 * issuer Name
1744 */
1745 crl->issuer_raw.p = p;
1746
1747 if( ( ret = asn1_get_tag( &p, end, &len,
1748 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1749 {
1750 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001751 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001752 }
1753
1754 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1755 {
1756 x509_crl_free( crl );
1757 return( ret );
1758 }
1759
1760 crl->issuer_raw.len = p - crl->issuer_raw.p;
1761
1762 /*
1763 * thisUpdate Time
1764 * nextUpdate Time OPTIONAL
1765 */
Paul Bakker91200182010-02-18 21:26:15 +00001766 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001767 {
1768 x509_crl_free( crl );
1769 return( ret );
1770 }
1771
Paul Bakker91200182010-02-18 21:26:15 +00001772 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001773 {
Paul Bakker9d781402011-05-09 16:17:09 +00001774 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001775 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker9d781402011-05-09 16:17:09 +00001776 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001777 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001778 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001779 x509_crl_free( crl );
1780 return( ret );
1781 }
1782 }
1783
1784 /*
1785 * revokedCertificates SEQUENCE OF SEQUENCE {
1786 * userCertificate CertificateSerialNumber,
1787 * revocationDate Time,
1788 * crlEntryExtensions Extensions OPTIONAL
1789 * -- if present, MUST be v2
1790 * } OPTIONAL
1791 */
1792 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1793 {
1794 x509_crl_free( crl );
1795 return( ret );
1796 }
1797
1798 /*
1799 * crlExtensions EXPLICIT Extensions OPTIONAL
1800 * -- if present, MUST be v2
1801 */
1802 if( crl->version == 2 )
1803 {
1804 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1805
1806 if( ret != 0 )
1807 {
1808 x509_crl_free( crl );
1809 return( ret );
1810 }
1811 }
1812
1813 if( p != end )
1814 {
1815 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001816 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001817 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1818 }
1819
1820 end = crl->raw.p + crl->raw.len;
1821
1822 /*
1823 * signatureAlgorithm AlgorithmIdentifier,
1824 * signatureValue BIT STRING
1825 */
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +02001826 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2, NULL ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001827 {
1828 x509_crl_free( crl );
1829 return( ret );
1830 }
1831
Paul Bakker535e97d2012-08-23 10:49:55 +00001832 if( crl->sig_oid1.len != crl->sig_oid2.len ||
1833 memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001834 {
1835 x509_crl_free( crl );
1836 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1837 }
1838
1839 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1840 {
1841 x509_crl_free( crl );
1842 return( ret );
1843 }
1844
1845 if( p != end )
1846 {
1847 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001848 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001849 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1850 }
1851
1852 if( buflen > 0 )
1853 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001854 crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001855
Paul Bakker7d06ad22009-05-02 15:53:56 +00001856 if( crl->next == NULL )
1857 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001858 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001859 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001860 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001861
Paul Bakker7d06ad22009-05-02 15:53:56 +00001862 crl = crl->next;
1863 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001864
1865 return( x509parse_crl( crl, buf, buflen ) );
1866 }
1867
1868 return( 0 );
1869}
1870
Paul Bakker335db3f2011-04-25 15:28:35 +00001871#if defined(POLARSSL_FS_IO)
Paul Bakkerd98030e2009-05-02 15:13:40 +00001872/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001873 * Load all data from a file into a given buffer.
1874 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02001875static int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001876{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001877 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001878
Paul Bakkerd98030e2009-05-02 15:13:40 +00001879 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001880 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001881
Paul Bakkerd98030e2009-05-02 15:13:40 +00001882 fseek( f, 0, SEEK_END );
1883 *n = (size_t) ftell( f );
1884 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001885
Paul Bakker6e339b52013-07-03 13:37:05 +02001886 if( ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
Paul Bakkerf6a19bd2013-05-14 13:26:51 +02001887 {
1888 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +00001889 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerf6a19bd2013-05-14 13:26:51 +02001890 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001891
Paul Bakkerd98030e2009-05-02 15:13:40 +00001892 if( fread( *buf, 1, *n, f ) != *n )
1893 {
1894 fclose( f );
Paul Bakker6e339b52013-07-03 13:37:05 +02001895 polarssl_free( *buf );
Paul Bakker69e095c2011-12-10 21:55:01 +00001896 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001897 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001898
Paul Bakkerd98030e2009-05-02 15:13:40 +00001899 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001900
Paul Bakkerd98030e2009-05-02 15:13:40 +00001901 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001902
Paul Bakkerd98030e2009-05-02 15:13:40 +00001903 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001904}
1905
1906/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001907 * Load one or more certificates and add them to the chained list
1908 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001909int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001910{
1911 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001912 size_t n;
1913 unsigned char *buf;
1914
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02001915 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00001916 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001917
Paul Bakker69e095c2011-12-10 21:55:01 +00001918 ret = x509parse_crt( chain, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001919
1920 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02001921 polarssl_free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001922
1923 return( ret );
1924}
1925
Paul Bakker8d914582012-06-04 12:46:42 +00001926int x509parse_crtpath( x509_cert *chain, const char *path )
1927{
1928 int ret = 0;
1929#if defined(_WIN32)
Paul Bakker3338b792012-10-01 21:13:10 +00001930 int w_ret;
1931 WCHAR szDir[MAX_PATH];
1932 char filename[MAX_PATH];
1933 char *p;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001934 int len = strlen( path );
Paul Bakker3338b792012-10-01 21:13:10 +00001935
Paul Bakker97872ac2012-11-02 12:53:26 +00001936 WIN32_FIND_DATAW file_data;
Paul Bakker8d914582012-06-04 12:46:42 +00001937 HANDLE hFind;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001938
1939 if( len > MAX_PATH - 3 )
1940 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker8d914582012-06-04 12:46:42 +00001941
Paul Bakker3338b792012-10-01 21:13:10 +00001942 memset( szDir, 0, sizeof(szDir) );
1943 memset( filename, 0, MAX_PATH );
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001944 memcpy( filename, path, len );
1945 filename[len++] = '\\';
1946 p = filename + len;
1947 filename[len++] = '*';
Paul Bakker3338b792012-10-01 21:13:10 +00001948
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001949 w_ret = MultiByteToWideChar( CP_ACP, 0, path, len, szDir, MAX_PATH - 3 );
Paul Bakker8d914582012-06-04 12:46:42 +00001950
Paul Bakker97872ac2012-11-02 12:53:26 +00001951 hFind = FindFirstFileW( szDir, &file_data );
Paul Bakker8d914582012-06-04 12:46:42 +00001952 if (hFind == INVALID_HANDLE_VALUE)
1953 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1954
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001955 len = MAX_PATH - len;
Paul Bakker8d914582012-06-04 12:46:42 +00001956 do
1957 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001958 memset( p, 0, len );
Paul Bakker3338b792012-10-01 21:13:10 +00001959
Paul Bakkere4791f32012-06-04 21:29:15 +00001960 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
Paul Bakker8d914582012-06-04 12:46:42 +00001961 continue;
1962
Paul Bakker3338b792012-10-01 21:13:10 +00001963 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
1964 lstrlenW(file_data.cFileName),
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001965 p, len - 1,
1966 NULL, NULL );
Paul Bakker8d914582012-06-04 12:46:42 +00001967
Paul Bakker3338b792012-10-01 21:13:10 +00001968 w_ret = x509parse_crtfile( chain, filename );
1969 if( w_ret < 0 )
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001970 ret++;
1971 else
1972 ret += w_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001973 }
Paul Bakker97872ac2012-11-02 12:53:26 +00001974 while( FindNextFileW( hFind, &file_data ) != 0 );
Paul Bakker8d914582012-06-04 12:46:42 +00001975
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001976 if (GetLastError() != ERROR_NO_MORE_FILES)
1977 ret = POLARSSL_ERR_X509_FILE_IO_ERROR;
Paul Bakker8d914582012-06-04 12:46:42 +00001978
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001979cleanup:
Paul Bakker8d914582012-06-04 12:46:42 +00001980 FindClose( hFind );
1981#else
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001982 int t_ret, i;
1983 struct stat sb;
1984 struct dirent entry, *result = NULL;
Paul Bakker8d914582012-06-04 12:46:42 +00001985 char entry_name[255];
1986 DIR *dir = opendir( path );
1987
1988 if( dir == NULL)
1989 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1990
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001991 while( ( t_ret = readdir_r( dir, &entry, &result ) ) == 0 )
Paul Bakker8d914582012-06-04 12:46:42 +00001992 {
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001993 if( result == NULL )
1994 break;
1995
1996 snprintf( entry_name, sizeof(entry_name), "%s/%s", path, entry.d_name );
1997
1998 i = stat( entry_name, &sb );
1999
2000 if( i == -1 )
2001 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
2002
2003 if( !S_ISREG( sb.st_mode ) )
Paul Bakker8d914582012-06-04 12:46:42 +00002004 continue;
2005
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002006 // Ignore parse errors
2007 //
Paul Bakker8d914582012-06-04 12:46:42 +00002008 t_ret = x509parse_crtfile( chain, entry_name );
2009 if( t_ret < 0 )
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002010 ret++;
2011 else
2012 ret += t_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00002013 }
2014 closedir( dir );
2015#endif
2016
2017 return( ret );
2018}
2019
Paul Bakkerd98030e2009-05-02 15:13:40 +00002020/*
2021 * Load one or more CRLs and add them to the chained list
2022 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002023int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002024{
2025 int ret;
2026 size_t n;
2027 unsigned char *buf;
2028
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02002029 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00002030 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002031
Paul Bakker27fdf462011-06-09 13:55:13 +00002032 ret = x509parse_crl( chain, buf, n );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002033
2034 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02002035 polarssl_free( buf );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002036
2037 return( ret );
2038}
2039
Paul Bakker5121ce52009-01-03 21:22:43 +00002040/*
Paul Bakker335db3f2011-04-25 15:28:35 +00002041 * Load and parse a private RSA key
2042 */
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002043int x509parse_keyfile_rsa( rsa_context *rsa, const char *path, const char *pwd )
Paul Bakker335db3f2011-04-25 15:28:35 +00002044{
2045 int ret;
2046 size_t n;
2047 unsigned char *buf;
2048
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02002049 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00002050 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002051
2052 if( pwd == NULL )
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002053 ret = x509parse_key_rsa( rsa, buf, n, NULL, 0 );
Paul Bakker335db3f2011-04-25 15:28:35 +00002054 else
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002055 ret = x509parse_key_rsa( rsa, buf, n,
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02002056 (const unsigned char *) pwd, strlen( pwd ) );
Paul Bakker335db3f2011-04-25 15:28:35 +00002057
2058 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02002059 polarssl_free( buf );
Paul Bakker335db3f2011-04-25 15:28:35 +00002060
2061 return( ret );
2062}
2063
2064/*
2065 * Load and parse a public RSA key
2066 */
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002067int x509parse_public_keyfile_rsa( rsa_context *rsa, const char *path )
Paul Bakker335db3f2011-04-25 15:28:35 +00002068{
2069 int ret;
2070 size_t n;
2071 unsigned char *buf;
2072
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02002073 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00002074 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002075
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002076 ret = x509parse_public_key_rsa( rsa, buf, n );
Paul Bakker335db3f2011-04-25 15:28:35 +00002077
2078 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02002079 polarssl_free( buf );
Paul Bakker335db3f2011-04-25 15:28:35 +00002080
2081 return( ret );
2082}
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002083
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002084/*
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002085 * Load and parse a private key
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002086 */
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002087int x509parse_keyfile( pk_context *ctx,
2088 const char *path, const char *pwd )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002089{
2090 int ret;
2091 size_t n;
2092 unsigned char *buf;
2093
2094 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2095 return( ret );
2096
2097 if( pwd == NULL )
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002098 ret = x509parse_key( ctx, buf, n, NULL, 0 );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002099 else
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002100 ret = x509parse_key( ctx, buf, n,
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002101 (const unsigned char *) pwd, strlen( pwd ) );
2102
2103 memset( buf, 0, n + 1 );
2104 free( buf );
2105
2106 return( ret );
2107}
2108
2109/*
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002110 * Load and parse a public key
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002111 */
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002112int x509parse_public_keyfile( pk_context *ctx, const char *path )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002113{
2114 int ret;
2115 size_t n;
2116 unsigned char *buf;
2117
2118 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2119 return( ret );
2120
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002121 ret = x509parse_public_key( ctx, buf, n );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002122
2123 memset( buf, 0, n + 1 );
2124 free( buf );
2125
2126 return( ret );
2127}
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002128
Paul Bakker335db3f2011-04-25 15:28:35 +00002129#endif /* POLARSSL_FS_IO */
2130
2131/*
Paul Bakkere2f50402013-06-24 19:00:59 +02002132 * Parse a PKCS#1 encoded private RSA key
Paul Bakker5121ce52009-01-03 21:22:43 +00002133 */
Paul Bakkere2f50402013-06-24 19:00:59 +02002134static int x509parse_key_pkcs1_der( rsa_context *rsa,
2135 const unsigned char *key,
2136 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +00002137{
Paul Bakker23986e52011-04-24 08:57:21 +00002138 int ret;
2139 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00002140 unsigned char *p, *end;
Paul Bakkered56b222011-07-13 11:26:43 +00002141
Paul Bakker96743fc2011-02-12 14:30:57 +00002142 p = (unsigned char *) key;
Paul Bakker96743fc2011-02-12 14:30:57 +00002143 end = p + keylen;
2144
Paul Bakker5121ce52009-01-03 21:22:43 +00002145 /*
Paul Bakkere2f50402013-06-24 19:00:59 +02002146 * This function parses the RSAPrivateKey (PKCS#1)
Paul Bakkered56b222011-07-13 11:26:43 +00002147 *
Paul Bakker5121ce52009-01-03 21:22:43 +00002148 * RSAPrivateKey ::= SEQUENCE {
2149 * version Version,
2150 * modulus INTEGER, -- n
2151 * publicExponent INTEGER, -- e
2152 * privateExponent INTEGER, -- d
2153 * prime1 INTEGER, -- p
2154 * prime2 INTEGER, -- q
2155 * exponent1 INTEGER, -- d mod (p-1)
2156 * exponent2 INTEGER, -- d mod (q-1)
2157 * coefficient INTEGER, -- (inverse of q) mod p
2158 * otherPrimeInfos OtherPrimeInfos OPTIONAL
2159 * }
2160 */
2161 if( ( ret = asn1_get_tag( &p, end, &len,
2162 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2163 {
Paul Bakker9d781402011-05-09 16:17:09 +00002164 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002165 }
2166
2167 end = p + len;
2168
2169 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2170 {
Paul Bakker9d781402011-05-09 16:17:09 +00002171 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002172 }
2173
2174 if( rsa->ver != 0 )
2175 {
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002176 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00002177 }
2178
2179 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
2180 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
2181 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
2182 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
2183 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
2184 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
2185 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
2186 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
2187 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002188 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002189 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002190 }
2191
2192 rsa->len = mpi_size( &rsa->N );
2193
2194 if( p != end )
2195 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002196 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002197 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00002198 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002199 }
2200
2201 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2202 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002203 rsa_free( rsa );
2204 return( ret );
2205 }
2206
Paul Bakkere2f50402013-06-24 19:00:59 +02002207 return( 0 );
2208}
2209
2210/*
2211 * Parse an unencrypted PKCS#8 encoded private RSA key
2212 */
2213static int x509parse_key_pkcs8_unencrypted_der(
2214 rsa_context *rsa,
2215 const unsigned char *key,
2216 size_t keylen )
2217{
2218 int ret;
2219 size_t len;
2220 unsigned char *p, *end;
2221 x509_buf pk_alg_oid;
2222 pk_type_t pk_alg = POLARSSL_PK_NONE;
2223
2224 p = (unsigned char *) key;
2225 end = p + keylen;
2226
2227 /*
2228 * This function parses the PrivatKeyInfo object (PKCS#8)
2229 *
2230 * PrivateKeyInfo ::= SEQUENCE {
2231 * version Version,
2232 * algorithm AlgorithmIdentifier,
2233 * PrivateKey BIT STRING
2234 * }
2235 *
2236 * AlgorithmIdentifier ::= SEQUENCE {
2237 * algorithm OBJECT IDENTIFIER,
2238 * parameters ANY DEFINED BY algorithm OPTIONAL
2239 * }
2240 *
2241 * The PrivateKey BIT STRING is a PKCS#1 RSAPrivateKey
2242 */
2243 if( ( ret = asn1_get_tag( &p, end, &len,
2244 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2245 {
2246 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2247 }
2248
2249 end = p + len;
2250
2251 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2252 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2253
2254 if( rsa->ver != 0 )
2255 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2256
Paul Bakkerf8d018a2013-06-29 12:16:17 +02002257 if( ( ret = asn1_get_alg_null( &p, end, &pk_alg_oid ) ) != 0 )
Paul Bakkere2f50402013-06-24 19:00:59 +02002258 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2259
2260 /*
2261 * only RSA keys handled at this time
2262 */
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002263 if( oid_get_pk_alg( &pk_alg_oid, &pk_alg ) != 0 )
Manuel Pégourié-Gonnard80300ad2013-07-04 11:57:13 +02002264 {
Paul Bakkere2f50402013-06-24 19:00:59 +02002265 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
Manuel Pégourié-Gonnard80300ad2013-07-04 11:57:13 +02002266 }
Paul Bakkere2f50402013-06-24 19:00:59 +02002267
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002268 if (pk_alg != POLARSSL_PK_RSA )
2269 return( POLARSSL_ERR_X509_CERT_INVALID_ALG );
2270
Paul Bakkere2f50402013-06-24 19:00:59 +02002271 /*
2272 * Get the OCTET STRING and parse the PKCS#1 format inside
2273 */
2274 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2275 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2276
2277 if( ( end - p ) < 1 )
2278 {
2279 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
2280 POLARSSL_ERR_ASN1_OUT_OF_DATA );
2281 }
2282
2283 end = p + len;
2284
2285 if( ( ret = x509parse_key_pkcs1_der( rsa, p, end - p ) ) != 0 )
2286 return( ret );
2287
2288 return( 0 );
2289}
2290
2291/*
Manuel Pégourié-Gonnarda5d99742013-07-04 11:08:31 +02002292 * Decrypt the content of a PKCS#8 EncryptedPrivateKeyInfo
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002293 */
Manuel Pégourié-Gonnarda5d99742013-07-04 11:08:31 +02002294static int x509parse_pkcs8_decrypt( unsigned char *buf, size_t buflen,
2295 size_t *used_len,
2296 const unsigned char *key, size_t keylen,
2297 const unsigned char *pwd, size_t pwdlen )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002298{
2299 int ret;
2300 size_t len;
Paul Bakkerf8d018a2013-06-29 12:16:17 +02002301 unsigned char *p, *end;
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002302 x509_buf pbe_alg_oid, pbe_params;
Paul Bakker7749a222013-06-28 17:28:20 +02002303#if defined(POLARSSL_PKCS12_C)
2304 cipher_type_t cipher_alg;
2305 md_type_t md_alg;
2306#endif
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002307
Manuel Pégourié-Gonnarda5d99742013-07-04 11:08:31 +02002308 memset(buf, 0, buflen);
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002309
2310 p = (unsigned char *) key;
2311 end = p + keylen;
2312
Paul Bakker28144de2013-06-24 19:28:55 +02002313 if( pwdlen == 0 )
2314 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
2315
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002316 /*
2317 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
2318 *
2319 * EncryptedPrivateKeyInfo ::= SEQUENCE {
2320 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
2321 * encryptedData EncryptedData
2322 * }
2323 *
2324 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
2325 *
2326 * EncryptedData ::= OCTET STRING
2327 *
2328 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
2329 */
2330 if( ( ret = asn1_get_tag( &p, end, &len,
2331 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2332 {
2333 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2334 }
2335
2336 end = p + len;
2337
Paul Bakkerf8d018a2013-06-29 12:16:17 +02002338 if( ( ret = asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002339 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002340
2341 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2342 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2343
Manuel Pégourié-Gonnarda5d99742013-07-04 11:08:31 +02002344 if( len > buflen )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002345 return( POLARSSL_ERR_X509_INVALID_INPUT );
2346
2347 /*
2348 * Decrypt EncryptedData with appropriate PDE
2349 */
Paul Bakker38b50d72013-06-24 19:33:27 +02002350#if defined(POLARSSL_PKCS12_C)
Paul Bakker7749a222013-06-28 17:28:20 +02002351 if( oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002352 {
Paul Bakker38b50d72013-06-24 19:33:27 +02002353 if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
Paul Bakker7749a222013-06-28 17:28:20 +02002354 cipher_alg, md_alg,
Paul Bakker38b50d72013-06-24 19:33:27 +02002355 pwd, pwdlen, p, len, buf ) ) != 0 )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002356 {
Paul Bakker38b50d72013-06-24 19:33:27 +02002357 if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH )
2358 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2359
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002360 return( ret );
2361 }
2362 }
2363 else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) )
2364 {
2365 if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params,
2366 PKCS12_PBE_DECRYPT,
2367 pwd, pwdlen,
2368 p, len, buf ) ) != 0 )
2369 {
2370 return( ret );
2371 }
Paul Bakker38b50d72013-06-24 19:33:27 +02002372
2373 // Best guess for password mismatch when using RC4. If first tag is
2374 // not ASN1_CONSTRUCTED | ASN1_SEQUENCE
2375 //
2376 if( *buf != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
2377 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002378 }
Paul Bakker38b50d72013-06-24 19:33:27 +02002379 else
2380#endif /* POLARSSL_PKCS12_C */
Paul Bakker28144de2013-06-24 19:28:55 +02002381#if defined(POLARSSL_PKCS5_C)
Paul Bakker38b50d72013-06-24 19:33:27 +02002382 if( OID_CMP( OID_PKCS5_PBES2, &pbe_alg_oid ) )
Paul Bakker28144de2013-06-24 19:28:55 +02002383 {
2384 if( ( ret = pkcs5_pbes2( &pbe_params, PKCS5_DECRYPT, pwd, pwdlen,
2385 p, len, buf ) ) != 0 )
2386 {
2387 if( ret == POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH )
2388 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2389
2390 return( ret );
2391 }
2392 }
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002393 else
Paul Bakker38b50d72013-06-24 19:33:27 +02002394#endif /* POLARSSL_PKCS5_C */
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002395 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
2396
Manuel Pégourié-Gonnarda5d99742013-07-04 11:08:31 +02002397 *used_len = len;
2398 return( 0 );
2399}
2400
2401/*
2402 * Parse an encrypted PKCS#8 encoded private RSA key
2403 */
2404static int x509parse_key_pkcs8_encrypted_der(
2405 rsa_context *rsa,
2406 const unsigned char *key, size_t keylen,
2407 const unsigned char *pwd, size_t pwdlen )
2408{
2409 int ret;
2410 unsigned char buf[2048];
2411 size_t len = 0;
2412
2413 if( ( ret = x509parse_pkcs8_decrypt( buf, sizeof( buf ), &len,
2414 key, keylen, pwd, pwdlen ) ) != 0 )
2415 {
2416 return( ret );
2417 }
2418
2419 return( x509parse_key_pkcs8_unencrypted_der( rsa, buf, len ) );
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002420}
2421
2422/*
Paul Bakkere2f50402013-06-24 19:00:59 +02002423 * Parse a private RSA key
2424 */
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002425int x509parse_key_rsa( rsa_context *rsa,
2426 const unsigned char *key, size_t keylen,
2427 const unsigned char *pwd, size_t pwdlen )
Paul Bakkere2f50402013-06-24 19:00:59 +02002428{
2429 int ret;
2430
Paul Bakker96743fc2011-02-12 14:30:57 +00002431#if defined(POLARSSL_PEM_C)
Paul Bakkere2f50402013-06-24 19:00:59 +02002432 size_t len;
2433 pem_context pem;
2434
2435 pem_init( &pem );
2436 ret = pem_read_buffer( &pem,
2437 "-----BEGIN RSA PRIVATE KEY-----",
2438 "-----END RSA PRIVATE KEY-----",
2439 key, pwd, pwdlen, &len );
2440 if( ret == 0 )
2441 {
2442 if( ( ret = x509parse_key_pkcs1_der( rsa, pem.buf, pem.buflen ) ) != 0 )
2443 {
2444 rsa_free( rsa );
2445 }
2446
2447 pem_free( &pem );
2448 return( ret );
2449 }
Paul Bakkera4232a72013-06-24 19:32:25 +02002450 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
2451 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2452 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
2453 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
Paul Bakkere2f50402013-06-24 19:00:59 +02002454 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkere2f50402013-06-24 19:00:59 +02002455 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002456
2457 ret = pem_read_buffer( &pem,
2458 "-----BEGIN PRIVATE KEY-----",
2459 "-----END PRIVATE KEY-----",
2460 key, NULL, 0, &len );
2461 if( ret == 0 )
2462 {
2463 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa,
2464 pem.buf, pem.buflen ) ) != 0 )
2465 {
2466 rsa_free( rsa );
2467 }
2468
2469 pem_free( &pem );
2470 return( ret );
2471 }
2472 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkere2f50402013-06-24 19:00:59 +02002473 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002474
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002475 ret = pem_read_buffer( &pem,
2476 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
2477 "-----END ENCRYPTED PRIVATE KEY-----",
2478 key, NULL, 0, &len );
2479 if( ret == 0 )
2480 {
2481 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa,
2482 pem.buf, pem.buflen,
2483 pwd, pwdlen ) ) != 0 )
2484 {
2485 rsa_free( rsa );
2486 }
2487
2488 pem_free( &pem );
2489 return( ret );
2490 }
2491 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002492 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002493#else
2494 ((void) pwd);
2495 ((void) pwdlen);
2496#endif /* POLARSSL_PEM_C */
2497
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002498 /*
2499 * At this point we only know it's not a PEM formatted key. Could be any
2500 * of the known DER encoded private key formats
2501 *
2502 * We try the different DER format parsers to see if one passes without
2503 * error
2504 */
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002505 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa, key, keylen,
2506 pwd, pwdlen ) ) == 0 )
Paul Bakkere2f50402013-06-24 19:00:59 +02002507 {
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002508 return( 0 );
Paul Bakkere2f50402013-06-24 19:00:59 +02002509 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002510
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002511 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002512
2513 if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH )
2514 {
2515 return( ret );
2516 }
2517
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002518 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa, key, keylen ) ) == 0 )
2519 return( 0 );
2520
2521 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002522
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002523 if( ( ret = x509parse_key_pkcs1_der( rsa, key, keylen ) ) == 0 )
2524 return( 0 );
2525
2526 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002527
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002528 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00002529}
2530
2531/*
Paul Bakker53019ae2011-03-25 13:58:48 +00002532 * Parse a public RSA key
2533 */
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002534int x509parse_public_key_rsa( rsa_context *rsa,
2535 const unsigned char *key, size_t keylen )
Paul Bakker53019ae2011-03-25 13:58:48 +00002536{
Paul Bakker23986e52011-04-24 08:57:21 +00002537 int ret;
2538 size_t len;
Paul Bakker53019ae2011-03-25 13:58:48 +00002539 unsigned char *p, *end;
2540 x509_buf alg_oid;
2541#if defined(POLARSSL_PEM_C)
2542 pem_context pem;
2543
2544 pem_init( &pem );
2545 ret = pem_read_buffer( &pem,
2546 "-----BEGIN PUBLIC KEY-----",
2547 "-----END PUBLIC KEY-----",
2548 key, NULL, 0, &len );
2549
2550 if( ret == 0 )
2551 {
2552 /*
2553 * Was PEM encoded
2554 */
2555 keylen = pem.buflen;
2556 }
Paul Bakker00b28602013-06-24 13:02:41 +02002557 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker53019ae2011-03-25 13:58:48 +00002558 {
2559 pem_free( &pem );
2560 return( ret );
2561 }
2562
2563 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2564#else
2565 p = (unsigned char *) key;
2566#endif
2567 end = p + keylen;
2568
2569 /*
2570 * PublicKeyInfo ::= SEQUENCE {
2571 * algorithm AlgorithmIdentifier,
2572 * PublicKey BIT STRING
2573 * }
2574 *
2575 * AlgorithmIdentifier ::= SEQUENCE {
2576 * algorithm OBJECT IDENTIFIER,
2577 * parameters ANY DEFINED BY algorithm OPTIONAL
2578 * }
2579 *
2580 * RSAPublicKey ::= SEQUENCE {
2581 * modulus INTEGER, -- n
2582 * publicExponent INTEGER -- e
2583 * }
2584 */
2585
2586 if( ( ret = asn1_get_tag( &p, end, &len,
2587 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2588 {
2589#if defined(POLARSSL_PEM_C)
2590 pem_free( &pem );
2591#endif
2592 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002593 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002594 }
2595
2596 if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
2597 {
2598#if defined(POLARSSL_PEM_C)
2599 pem_free( &pem );
2600#endif
2601 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002602 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002603 }
2604
2605 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
2606 {
2607#if defined(POLARSSL_PEM_C)
2608 pem_free( &pem );
2609#endif
2610 rsa_free( rsa );
2611 return( ret );
2612 }
2613
2614 rsa->len = mpi_size( &rsa->N );
2615
2616#if defined(POLARSSL_PEM_C)
2617 pem_free( &pem );
2618#endif
2619
2620 return( 0 );
2621}
2622
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002623#if defined(POLARSSL_ECP_C)
2624/*
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002625 * Parse a SEC1 encoded private EC key
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002626 */
2627static int x509parse_key_sec1_der( ecp_keypair *eck,
2628 const unsigned char *key,
2629 size_t keylen )
2630{
2631 int ret;
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002632 int version;
2633 size_t len;
2634 ecp_group_id grp_id;
2635 unsigned char *p = (unsigned char *) key;
2636 unsigned char *end = p + keylen;
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002637
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002638 /*
2639 * RFC 5915, orf SEC1 Appendix C.4
2640 *
2641 * ECPrivateKey ::= SEQUENCE {
2642 * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
2643 * privateKey OCTET STRING,
2644 * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
2645 * publicKey [1] BIT STRING OPTIONAL
2646 * }
2647 */
2648 if( ( ret = asn1_get_tag( &p, end, &len,
2649 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2650 {
2651 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2652 }
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002653
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002654 end = p + len;
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002655
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002656 if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 )
2657 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002658
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002659 if( version != 1 )
2660 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION );
2661
2662 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2663 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2664
2665 if( ( ret = mpi_read_binary( &eck->d, p, len ) ) != 0 )
2666 {
2667 ecp_keypair_free( eck );
2668 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2669 }
2670
2671 p += len;
2672
2673 /*
2674 * Is 'parameters' present?
2675 */
2676 if( ( ret = asn1_get_tag( &p, end, &len,
2677 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) == 0 )
2678 {
2679 if( ( ret = x509_get_ecparams( &p, p + len, &grp_id) ) != 0 )
2680 return( ret );
2681
Manuel Pégourié-Gonnardd4ec21d2013-07-04 12:04:57 +02002682 /*
2683 * If we're wrapped in a bigger structure (eg PKCS#8), grp may have been
2684 * defined externally. In this case, make sure both definitions match.
2685 */
2686 if( eck->grp.id != 0 )
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002687 {
Manuel Pégourié-Gonnardd4ec21d2013-07-04 12:04:57 +02002688 if( eck->grp.id != grp_id )
2689 {
2690 ecp_keypair_free( eck );
2691 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2692 }
2693 }
2694 else
2695 {
2696 if( ( ret = ecp_use_known_dp( &eck->grp, grp_id ) ) != 0 )
2697 {
2698 ecp_keypair_free( eck );
2699 return( ret );
2700 }
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002701 }
2702 }
2703 else if ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
2704 {
2705 ecp_keypair_free( eck );
2706 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2707 }
2708
2709 /*
2710 * Is 'publickey' present?
2711 */
2712 if( ( ret = asn1_get_tag( &p, end, &len,
2713 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 )
2714 {
2715 if( ( ret = x509_get_subpubkey_ec( &p, p + len, &eck->grp, &eck->Q ) )
2716 != 0 )
2717 {
2718 ecp_keypair_free( eck );
2719 return( ret );
2720 }
2721
2722 if( ( ret = ecp_check_pubkey( &eck->grp, &eck->Q ) ) != 0 )
2723 {
2724 ecp_keypair_free( eck );
2725 return( ret );
2726 }
2727 }
2728 else if ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
2729 {
2730 ecp_keypair_free( eck );
2731 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2732 }
2733
2734 if( ( ret = ecp_check_prvkey( &eck->grp, &eck->d ) ) != 0 )
2735 {
2736 ecp_keypair_free( eck );
2737 return( ret );
2738 }
2739
2740 return 0;
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002741}
2742
2743/*
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002744 * Parse an unencrypted PKCS#8 encoded private EC key
2745 */
2746static int x509parse_key_pkcs8_unencrypted_der_ec(
2747 ecp_keypair *eck,
2748 const unsigned char* key,
2749 size_t keylen )
2750{
2751 int ret, version;
2752 size_t len;
2753 x509_buf pk_alg_oid;
2754 ecp_group_id grp_id;
2755 const unsigned char *params_end;
2756 unsigned char *p = (unsigned char *) key;
2757 unsigned char *end = p + keylen;
2758 pk_type_t pk_alg = POLARSSL_PK_NONE;
2759
2760 /*
2761 * This function parses the PrivatKeyInfo object (PKCS#8 v1.2 = RFC 5208)
2762 *
2763 * PrivateKeyInfo ::= SEQUENCE {
2764 * version Version,
2765 * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
2766 * privateKey PrivateKey,
2767 * attributes [0] IMPLICIT Attributes OPTIONAL }
2768 *
2769 * Version ::= INTEGER
2770 * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
2771 * PrivateKey ::= OCTET STRING
2772 *
2773 * The PrivateKey OCTET STRING is a SEC1 ECPrivateKey
2774 */
2775
2776 if( ( ret = asn1_get_tag( &p, end, &len,
2777 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2778 {
2779 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2780 }
2781
2782 end = p + len;
2783
2784 if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 )
2785 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2786
2787 if( version != 0 )
2788 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2789
2790 if( ( ret = x509_get_alg( &p, end, &pk_alg_oid, &params_end ) ) != 0 )
2791 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2792
2793 if( oid_get_pk_alg( &pk_alg_oid, &pk_alg ) != 0 )
2794 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
2795
2796 if( pk_alg != POLARSSL_PK_ECKEY && pk_alg != POLARSSL_PK_ECKEY_DH )
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002797 return( POLARSSL_ERR_X509_CERT_INVALID_ALG );
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002798
2799 if( pk_alg == POLARSSL_PK_ECKEY_DH )
2800 eck->alg = POLARSSL_ECP_KEY_ALG_ECDH;
2801
2802 if( ( ret = x509_get_ecparams( &p, params_end, &grp_id ) ) != 0 )
2803 {
2804 ecp_keypair_free( eck );
2805 return( ret );
2806 }
2807
2808 if( ( ret = ecp_use_known_dp( &eck->grp, grp_id ) ) != 0 )
2809 {
2810 ecp_keypair_free( eck );
2811 return( ret );
2812 }
2813
2814 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2815 {
2816 ecp_keypair_free( eck );
2817 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2818 }
2819
2820 if( ( ret = x509parse_key_sec1_der( eck, p, len ) ) != 0 )
2821 {
2822 ecp_keypair_free( eck );
2823 return( ret );
2824 }
2825
2826 if( ( ret = ecp_check_prvkey( &eck->grp, &eck->d ) ) != 0 )
2827 {
2828 ecp_keypair_free( eck );
2829 return( ret );
2830 }
2831
2832 return 0;
2833}
2834
2835/*
2836 * Parse an encrypted PKCS#8 encoded private EC key
2837 */
2838static int x509parse_key_pkcs8_encrypted_der_ec(
2839 ecp_keypair *eck,
Manuel Pégourié-Gonnard9c1cf452013-07-04 11:20:24 +02002840 const unsigned char *key, size_t keylen,
2841 const unsigned char *pwd, size_t pwdlen )
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002842{
2843 int ret;
Manuel Pégourié-Gonnard9c1cf452013-07-04 11:20:24 +02002844 unsigned char buf[2048];
2845 size_t len = 0;
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002846
Manuel Pégourié-Gonnard9c1cf452013-07-04 11:20:24 +02002847 if( ( ret = x509parse_pkcs8_decrypt( buf, sizeof( buf ), &len,
2848 key, keylen, pwd, pwdlen ) ) != 0 )
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002849 {
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002850 return( ret );
2851 }
2852
Manuel Pégourié-Gonnard9c1cf452013-07-04 11:20:24 +02002853 return( x509parse_key_pkcs8_unencrypted_der_ec( eck, buf, len ) );
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002854}
2855
2856/*
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002857 * Parse a private EC key
2858 */
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002859static int x509parse_key_ec( ecp_keypair *eck,
2860 const unsigned char *key, size_t keylen,
2861 const unsigned char *pwd, size_t pwdlen )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002862{
2863 int ret;
2864
2865#if defined(POLARSSL_PEM_C)
2866 size_t len;
2867 pem_context pem;
2868
2869 pem_init( &pem );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002870 ret = pem_read_buffer( &pem,
2871 "-----BEGIN EC PRIVATE KEY-----",
2872 "-----END EC PRIVATE KEY-----",
2873 key, pwd, pwdlen, &len );
2874 if( ret == 0 )
2875 {
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002876 if( ( ret = x509parse_key_sec1_der( eck, pem.buf, pem.buflen ) ) != 0 )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002877 {
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002878 ecp_keypair_free( eck );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002879 }
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002880
2881 pem_free( &pem );
2882 return( ret );
2883 }
2884 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
2885 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2886 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
2887 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
2888 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2889 return( ret );
2890
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002891 ret = pem_read_buffer( &pem,
2892 "-----BEGIN PRIVATE KEY-----",
2893 "-----END PRIVATE KEY-----",
2894 key, NULL, 0, &len );
2895 if( ret == 0 )
2896 {
2897 if( ( ret = x509parse_key_pkcs8_unencrypted_der_ec( eck,
2898 pem.buf, pem.buflen ) ) != 0 )
2899 {
2900 ecp_keypair_free( eck );
2901 }
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002902
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002903 pem_free( &pem );
2904 return( ret );
2905 }
2906 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2907 return( ret );
2908
2909 ret = pem_read_buffer( &pem,
2910 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
2911 "-----END ENCRYPTED PRIVATE KEY-----",
2912 key, NULL, 0, &len );
2913 if( ret == 0 )
2914 {
2915 if( ( ret = x509parse_key_pkcs8_encrypted_der_ec( eck,
2916 pem.buf, pem.buflen,
2917 pwd, pwdlen ) ) != 0 )
2918 {
2919 ecp_keypair_free( eck );
2920 }
2921
2922 pem_free( &pem );
2923 return( ret );
2924 }
2925 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2926 return( ret );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002927#else
2928 ((void) pwd);
2929 ((void) pwdlen);
2930#endif /* POLARSSL_PEM_C */
2931
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002932 /*
2933 * At this point we only know it's not a PEM formatted key. Could be any
2934 * of the known DER encoded private key formats
2935 *
2936 * We try the different DER format parsers to see if one passes without
2937 * error
2938 */
2939 if( ( ret = x509parse_key_pkcs8_encrypted_der_ec( eck, key, keylen,
2940 pwd, pwdlen ) ) == 0 )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002941 {
2942 return( 0 );
2943 }
2944
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002945 ecp_keypair_free( eck );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002946
2947 if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH )
2948 {
2949 return( ret );
2950 }
2951
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002952 if( ( ret = x509parse_key_pkcs8_unencrypted_der_ec( eck,
2953 key, keylen ) ) == 0 )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002954 return( 0 );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002955
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002956 ecp_keypair_free( eck );
2957
2958 if( ( ret = x509parse_key_sec1_der( eck, key, keylen ) ) == 0 )
2959 return( 0 );
2960
2961 ecp_keypair_free( eck );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002962
2963 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
2964}
2965
2966/*
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +02002967 * Parse a public EC key in RFC 5480 format, der-encoded
2968 */
2969static int x509parse_public_key_ec_der( ecp_keypair *key,
2970 const unsigned char *buf, size_t len )
2971{
2972 int ret;
2973 ecp_group_id grp_id;
2974 x509_buf alg_oid;
2975 pk_type_t alg = POLARSSL_PK_NONE;
2976 unsigned char *p = (unsigned char *) buf;
2977 unsigned char *end = p + len;
2978 const unsigned char *params_end;
2979 /*
2980 * SubjectPublicKeyInfo ::= SEQUENCE {
2981 * algorithm AlgorithmIdentifier,
2982 * subjectPublicKey BIT STRING
2983 * }
2984 * -- algorithm parameters are ECParameters
2985 * -- subjectPublicKey is an ECPoint
2986 */
2987 if( ( ret = asn1_get_tag( &p, end, &len,
2988 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2989 {
2990 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
2991 }
2992
2993 if( ( ret = x509_get_alg( &p, end, &alg_oid, &params_end ) ) != 0 )
2994 return( ret );
2995
2996 if( oid_get_pk_alg( &alg_oid, &alg ) != 0 )
2997 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
2998
2999 if( alg != POLARSSL_PK_ECKEY && alg != POLARSSL_PK_ECKEY_DH )
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02003000 return( POLARSSL_ERR_X509_CERT_INVALID_ALG );
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +02003001
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02003002 if( alg == POLARSSL_PK_ECKEY_DH )
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +02003003 key->alg = POLARSSL_ECP_KEY_ALG_ECDH;
3004
3005 if( ( ret = x509_get_ecparams( &p, params_end, &grp_id ) ) != 0 )
3006 return( ret );
3007
3008 if( ( ret = ecp_use_known_dp( &key->grp, grp_id ) ) != 0 )
3009 return( ret );
3010
3011 if( ( ret = x509_get_subpubkey_ec( &p, end, &key->grp, &key->Q ) ) != 0 )
3012 {
3013 return( ret );
3014 }
3015
3016 return( 0 );
3017}
3018
3019/*
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003020 * Parse a public EC key
3021 */
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02003022static int x509parse_public_key_ec( ecp_keypair *eckey,
3023 const unsigned char *key, size_t keylen )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003024{
3025 int ret;
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003026#if defined(POLARSSL_PEM_C)
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +02003027 size_t len;
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003028 pem_context pem;
3029
3030 pem_init( &pem );
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +02003031 ret = pem_read_buffer( &pem,
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003032 "-----BEGIN PUBLIC KEY-----",
3033 "-----END PUBLIC KEY-----",
3034 key, NULL, 0, &len );
3035
3036 if( ret == 0 )
3037 {
3038 /*
3039 * Was PEM encoded
3040 */
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +02003041 key = pem.buf;
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003042 keylen = pem.buflen;
3043 }
3044 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
3045 {
3046 pem_free( &pem );
3047 return( ret );
3048 }
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003049#endif
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003050
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +02003051 if( ( ret = x509parse_public_key_ec_der ( eckey, key, keylen ) ) != 0 ||
3052 ( ret = ecp_check_pubkey( &eckey->grp, &eckey->Q ) ) != 0 )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003053 {
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003054 ecp_keypair_free( eckey );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003055 }
3056
3057#if defined(POLARSSL_PEM_C)
3058 pem_free( &pem );
3059#endif
3060
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +02003061 return( ret );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02003062}
3063#endif /* defined(POLARSSL_ECP_C) */
3064
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02003065/*
3066 * Parse a private key
3067 */
3068int x509parse_key( pk_context *ctx,
3069 const unsigned char *key, size_t keylen,
3070 const unsigned char *pwd, size_t pwdlen )
3071{
3072 int ret;
3073
3074 if ( ( ret = pk_set_type( ctx, POLARSSL_PK_RSA ) ) != 0 )
3075 return( ret );
3076
3077 if( ( ret = x509parse_key_rsa( ctx->data, key, keylen, pwd, pwdlen ) )
3078 == 0 )
3079 {
3080 return( 0 );
3081 }
3082
3083 if ( ( ret = pk_set_type( ctx, POLARSSL_PK_ECKEY ) ) != 0 )
3084 return( ret );
3085
3086 if( ( ret = x509parse_key_ec( ctx->data, key, keylen, pwd, pwdlen ) ) == 0 )
3087 {
3088 return( 0 );
3089 }
3090
3091 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
3092}
3093
3094/*
3095 * Parse a public key
3096 */
3097int x509parse_public_key( pk_context *ctx,
3098 const unsigned char *key, size_t keylen )
3099{
3100 int ret;
3101
3102 if ( ( ret = pk_set_type( ctx, POLARSSL_PK_RSA ) ) != 0 )
3103 return( ret );
3104
3105 if( ( ret = x509parse_public_key_rsa( ctx->data, key, keylen ) ) == 0 )
3106 return( 0 );
3107
3108 if ( ( ret = pk_set_type( ctx, POLARSSL_PK_ECKEY ) ) != 0 )
3109 return( ret );
3110
3111 if( ( ret = x509parse_public_key_ec( ctx->data, key, keylen ) ) == 0 )
3112 return( 0 );
3113
3114 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
3115}
3116
Paul Bakkereaa89f82011-04-04 21:36:15 +00003117#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00003118/*
Paul Bakker1b57b062011-01-06 15:48:19 +00003119 * Parse DHM parameters
3120 */
Paul Bakker23986e52011-04-24 08:57:21 +00003121int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
Paul Bakker1b57b062011-01-06 15:48:19 +00003122{
Paul Bakker23986e52011-04-24 08:57:21 +00003123 int ret;
3124 size_t len;
Paul Bakker1b57b062011-01-06 15:48:19 +00003125 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00003126#if defined(POLARSSL_PEM_C)
3127 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00003128
Paul Bakker96743fc2011-02-12 14:30:57 +00003129 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00003130
Paul Bakker96743fc2011-02-12 14:30:57 +00003131 ret = pem_read_buffer( &pem,
3132 "-----BEGIN DH PARAMETERS-----",
3133 "-----END DH PARAMETERS-----",
3134 dhmin, NULL, 0, &dhminlen );
3135
3136 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003137 {
Paul Bakker96743fc2011-02-12 14:30:57 +00003138 /*
3139 * Was PEM encoded
3140 */
3141 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00003142 }
Paul Bakker00b28602013-06-24 13:02:41 +02003143 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00003144 {
Paul Bakker96743fc2011-02-12 14:30:57 +00003145 pem_free( &pem );
3146 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00003147 }
3148
Paul Bakker96743fc2011-02-12 14:30:57 +00003149 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
3150#else
3151 p = (unsigned char *) dhmin;
3152#endif
3153 end = p + dhminlen;
3154
Paul Bakker1b57b062011-01-06 15:48:19 +00003155 memset( dhm, 0, sizeof( dhm_context ) );
3156
Paul Bakker1b57b062011-01-06 15:48:19 +00003157 /*
3158 * DHParams ::= SEQUENCE {
3159 * prime INTEGER, -- P
3160 * generator INTEGER, -- g
3161 * }
3162 */
3163 if( ( ret = asn1_get_tag( &p, end, &len,
3164 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
3165 {
Paul Bakker96743fc2011-02-12 14:30:57 +00003166#if defined(POLARSSL_PEM_C)
3167 pem_free( &pem );
3168#endif
Paul Bakker9d781402011-05-09 16:17:09 +00003169 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00003170 }
3171
3172 end = p + len;
3173
3174 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
3175 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
3176 {
Paul Bakker96743fc2011-02-12 14:30:57 +00003177#if defined(POLARSSL_PEM_C)
3178 pem_free( &pem );
3179#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00003180 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00003181 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00003182 }
3183
3184 if( p != end )
3185 {
Paul Bakker96743fc2011-02-12 14:30:57 +00003186#if defined(POLARSSL_PEM_C)
3187 pem_free( &pem );
3188#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00003189 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00003190 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker1b57b062011-01-06 15:48:19 +00003191 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
3192 }
3193
Paul Bakker96743fc2011-02-12 14:30:57 +00003194#if defined(POLARSSL_PEM_C)
3195 pem_free( &pem );
3196#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00003197
3198 return( 0 );
3199}
3200
Paul Bakker335db3f2011-04-25 15:28:35 +00003201#if defined(POLARSSL_FS_IO)
Paul Bakker1b57b062011-01-06 15:48:19 +00003202/*
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02003203 * Load and parse DHM parameters
Paul Bakker1b57b062011-01-06 15:48:19 +00003204 */
3205int x509parse_dhmfile( dhm_context *dhm, const char *path )
3206{
3207 int ret;
3208 size_t n;
3209 unsigned char *buf;
3210
Paul Bakker69e095c2011-12-10 21:55:01 +00003211 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
3212 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00003213
Paul Bakker27fdf462011-06-09 13:55:13 +00003214 ret = x509parse_dhm( dhm, buf, n );
Paul Bakker1b57b062011-01-06 15:48:19 +00003215
3216 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02003217 polarssl_free( buf );
Paul Bakker1b57b062011-01-06 15:48:19 +00003218
3219 return( ret );
3220}
Paul Bakker335db3f2011-04-25 15:28:35 +00003221#endif /* POLARSSL_FS_IO */
Paul Bakkereaa89f82011-04-04 21:36:15 +00003222#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00003223
Paul Bakker5121ce52009-01-03 21:22:43 +00003224#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00003225#include <stdarg.h>
3226
3227#if !defined vsnprintf
3228#define vsnprintf _vsnprintf
3229#endif // vsnprintf
3230
3231/*
3232 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
3233 * Result value is not size of buffer needed, but -1 if no fit is possible.
3234 *
3235 * This fuction tries to 'fix' this by at least suggesting enlarging the
3236 * size by 20.
3237 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02003238static int compat_snprintf(char *str, size_t size, const char *format, ...)
Paul Bakkerd98030e2009-05-02 15:13:40 +00003239{
3240 va_list ap;
3241 int res = -1;
3242
3243 va_start( ap, format );
3244
3245 res = vsnprintf( str, size, format, ap );
3246
3247 va_end( ap );
3248
3249 // No quick fix possible
3250 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00003251 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003252
3253 return res;
3254}
3255
3256#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00003257#endif
3258
Paul Bakkerd98030e2009-05-02 15:13:40 +00003259#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
3260
3261#define SAFE_SNPRINTF() \
3262{ \
3263 if( ret == -1 ) \
3264 return( -1 ); \
3265 \
Paul Bakker23986e52011-04-24 08:57:21 +00003266 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00003267 p[n - 1] = '\0'; \
3268 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
3269 } \
3270 \
Paul Bakker23986e52011-04-24 08:57:21 +00003271 n -= (unsigned int) ret; \
3272 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00003273}
3274
Paul Bakker5121ce52009-01-03 21:22:43 +00003275/*
3276 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00003277 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00003278 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003279int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00003280{
Paul Bakker23986e52011-04-24 08:57:21 +00003281 int ret;
3282 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00003283 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00003284 const x509_name *name;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003285 const char *short_name = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003286 char s[128], *p;
3287
3288 memset( s, 0, sizeof( s ) );
3289
3290 name = dn;
3291 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003292 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00003293
3294 while( name != NULL )
3295 {
Paul Bakkercefb3962012-06-27 11:51:09 +00003296 if( !name->oid.p )
3297 {
3298 name = name->next;
3299 continue;
3300 }
3301
Paul Bakker74111d32011-01-15 16:57:55 +00003302 if( name != dn )
3303 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00003304 ret = snprintf( p, n, ", " );
3305 SAFE_SNPRINTF();
3306 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003307
Paul Bakkerc70b9822013-04-07 22:00:46 +02003308 ret = oid_get_attr_short_name( &name->oid, &short_name );
Paul Bakker5121ce52009-01-03 21:22:43 +00003309
Paul Bakkerc70b9822013-04-07 22:00:46 +02003310 if( ret == 0 )
3311 ret = snprintf( p, n, "%s=", short_name );
Paul Bakker5121ce52009-01-03 21:22:43 +00003312 else
Paul Bakkerd98030e2009-05-02 15:13:40 +00003313 ret = snprintf( p, n, "\?\?=" );
Paul Bakkerc70b9822013-04-07 22:00:46 +02003314 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003315
3316 for( i = 0; i < name->val.len; i++ )
3317 {
Paul Bakker27fdf462011-06-09 13:55:13 +00003318 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003319 break;
3320
3321 c = name->val.p[i];
3322 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
3323 s[i] = '?';
3324 else s[i] = c;
3325 }
3326 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00003327 ret = snprintf( p, n, "%s", s );
Paul Bakkerc70b9822013-04-07 22:00:46 +02003328 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003329 name = name->next;
3330 }
3331
Paul Bakker23986e52011-04-24 08:57:21 +00003332 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003333}
3334
3335/*
Paul Bakkerdd476992011-01-16 21:34:59 +00003336 * Store the serial in printable form into buf; no more
3337 * than size characters will be written
3338 */
3339int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
3340{
Paul Bakker23986e52011-04-24 08:57:21 +00003341 int ret;
3342 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00003343 char *p;
3344
3345 p = buf;
3346 n = size;
3347
3348 nr = ( serial->len <= 32 )
Paul Bakker03c7c252011-11-25 12:37:37 +00003349 ? serial->len : 28;
Paul Bakkerdd476992011-01-16 21:34:59 +00003350
3351 for( i = 0; i < nr; i++ )
3352 {
Paul Bakker93048802011-12-05 14:38:06 +00003353 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003354 continue;
3355
Paul Bakkerdd476992011-01-16 21:34:59 +00003356 ret = snprintf( p, n, "%02X%s",
3357 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
3358 SAFE_SNPRINTF();
3359 }
3360
Paul Bakker03c7c252011-11-25 12:37:37 +00003361 if( nr != serial->len )
3362 {
3363 ret = snprintf( p, n, "...." );
3364 SAFE_SNPRINTF();
3365 }
3366
Paul Bakker23986e52011-04-24 08:57:21 +00003367 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00003368}
3369
3370/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00003371 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00003372 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003373int x509parse_cert_info( char *buf, size_t size, const char *prefix,
3374 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00003375{
Paul Bakker23986e52011-04-24 08:57:21 +00003376 int ret;
3377 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003378 char *p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003379 const char *desc = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003380
3381 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003382 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00003383
Paul Bakkerd98030e2009-05-02 15:13:40 +00003384 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00003385 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003386 SAFE_SNPRINTF();
3387 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00003388 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003389 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003390
Paul Bakkerdd476992011-01-16 21:34:59 +00003391 ret = x509parse_serial_gets( p, n, &crt->serial);
3392 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003393
Paul Bakkerd98030e2009-05-02 15:13:40 +00003394 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
3395 SAFE_SNPRINTF();
3396 ret = x509parse_dn_gets( p, n, &crt->issuer );
3397 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003398
Paul Bakkerd98030e2009-05-02 15:13:40 +00003399 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
3400 SAFE_SNPRINTF();
3401 ret = x509parse_dn_gets( p, n, &crt->subject );
3402 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003403
Paul Bakkerd98030e2009-05-02 15:13:40 +00003404 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00003405 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3406 crt->valid_from.year, crt->valid_from.mon,
3407 crt->valid_from.day, crt->valid_from.hour,
3408 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003409 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003410
Paul Bakkerd98030e2009-05-02 15:13:40 +00003411 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00003412 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3413 crt->valid_to.year, crt->valid_to.mon,
3414 crt->valid_to.day, crt->valid_to.hour,
3415 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003416 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003417
Paul Bakkerc70b9822013-04-07 22:00:46 +02003418 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003419 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003420
Paul Bakkerc70b9822013-04-07 22:00:46 +02003421 ret = oid_get_sig_alg_desc( &crt->sig_oid1, &desc );
3422 if( ret != 0 )
3423 ret = snprintf( p, n, "???" );
3424 else
3425 ret = snprintf( p, n, desc );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003426 SAFE_SNPRINTF();
3427
3428 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
Paul Bakker5c2364c2012-10-01 14:41:15 +00003429 (int) crt->rsa.N.n * (int) sizeof( t_uint ) * 8 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003430 SAFE_SNPRINTF();
3431
Paul Bakker23986e52011-04-24 08:57:21 +00003432 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003433}
3434
Paul Bakker74111d32011-01-15 16:57:55 +00003435/*
3436 * Return an informational string describing the given OID
3437 */
3438const char *x509_oid_get_description( x509_buf *oid )
3439{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003440 const char *desc = NULL;
3441 int ret;
Paul Bakker74111d32011-01-15 16:57:55 +00003442
Paul Bakkerc70b9822013-04-07 22:00:46 +02003443 ret = oid_get_extended_key_usage( oid, &desc );
Paul Bakker74111d32011-01-15 16:57:55 +00003444
Paul Bakkerc70b9822013-04-07 22:00:46 +02003445 if( ret != 0 )
3446 return( NULL );
Paul Bakker74111d32011-01-15 16:57:55 +00003447
Paul Bakkerc70b9822013-04-07 22:00:46 +02003448 return( desc );
Paul Bakker74111d32011-01-15 16:57:55 +00003449}
3450
3451/* Return the x.y.z.... style numeric string for the given OID */
3452int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
3453{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003454 return oid_get_numeric_string( buf, size, oid );
Paul Bakker74111d32011-01-15 16:57:55 +00003455}
3456
Paul Bakkerd98030e2009-05-02 15:13:40 +00003457/*
3458 * Return an informational string about the CRL.
3459 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003460int x509parse_crl_info( char *buf, size_t size, const char *prefix,
3461 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003462{
Paul Bakker23986e52011-04-24 08:57:21 +00003463 int ret;
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003464 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003465 char *p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003466 const char *desc;
Paul Bakkerff60ee62010-03-16 21:09:09 +00003467 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003468
3469 p = buf;
3470 n = size;
3471
3472 ret = snprintf( p, n, "%sCRL version : %d",
3473 prefix, crl->version );
3474 SAFE_SNPRINTF();
3475
3476 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
3477 SAFE_SNPRINTF();
3478 ret = x509parse_dn_gets( p, n, &crl->issuer );
3479 SAFE_SNPRINTF();
3480
3481 ret = snprintf( p, n, "\n%sthis update : " \
3482 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3483 crl->this_update.year, crl->this_update.mon,
3484 crl->this_update.day, crl->this_update.hour,
3485 crl->this_update.min, crl->this_update.sec );
3486 SAFE_SNPRINTF();
3487
3488 ret = snprintf( p, n, "\n%snext update : " \
3489 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3490 crl->next_update.year, crl->next_update.mon,
3491 crl->next_update.day, crl->next_update.hour,
3492 crl->next_update.min, crl->next_update.sec );
3493 SAFE_SNPRINTF();
3494
3495 entry = &crl->entry;
3496
3497 ret = snprintf( p, n, "\n%sRevoked certificates:",
3498 prefix );
3499 SAFE_SNPRINTF();
3500
Paul Bakker9be19372009-07-27 20:21:53 +00003501 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003502 {
3503 ret = snprintf( p, n, "\n%sserial number: ",
3504 prefix );
3505 SAFE_SNPRINTF();
3506
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003507 ret = x509parse_serial_gets( p, n, &entry->serial);
3508 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003509
Paul Bakkerd98030e2009-05-02 15:13:40 +00003510 ret = snprintf( p, n, " revocation date: " \
3511 "%04d-%02d-%02d %02d:%02d:%02d",
3512 entry->revocation_date.year, entry->revocation_date.mon,
3513 entry->revocation_date.day, entry->revocation_date.hour,
3514 entry->revocation_date.min, entry->revocation_date.sec );
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003515 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003516
3517 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003518 }
3519
Paul Bakkerc70b9822013-04-07 22:00:46 +02003520 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003521 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003522
Paul Bakkerc70b9822013-04-07 22:00:46 +02003523 ret = oid_get_sig_alg_desc( &crl->sig_oid1, &desc );
3524 if( ret != 0 )
3525 ret = snprintf( p, n, "???" );
3526 else
3527 ret = snprintf( p, n, desc );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003528 SAFE_SNPRINTF();
3529
Paul Bakker1e27bb22009-07-19 20:25:25 +00003530 ret = snprintf( p, n, "\n" );
3531 SAFE_SNPRINTF();
3532
Paul Bakker23986e52011-04-24 08:57:21 +00003533 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003534}
3535
3536/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00003537 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00003538 */
Paul Bakkerfa9b1002013-07-03 15:31:03 +02003539#if defined(POLARSSL_HAVE_TIME)
Paul Bakkerff60ee62010-03-16 21:09:09 +00003540int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00003541{
Paul Bakkercce9d772011-11-18 14:26:47 +00003542 int year, mon, day;
3543 int hour, min, sec;
3544
3545#if defined(_WIN32)
3546 SYSTEMTIME st;
3547
3548 GetLocalTime(&st);
3549
3550 year = st.wYear;
3551 mon = st.wMonth;
3552 day = st.wDay;
3553 hour = st.wHour;
3554 min = st.wMinute;
3555 sec = st.wSecond;
3556#else
Paul Bakker5121ce52009-01-03 21:22:43 +00003557 struct tm *lt;
3558 time_t tt;
3559
3560 tt = time( NULL );
3561 lt = localtime( &tt );
3562
Paul Bakkercce9d772011-11-18 14:26:47 +00003563 year = lt->tm_year + 1900;
3564 mon = lt->tm_mon + 1;
3565 day = lt->tm_mday;
3566 hour = lt->tm_hour;
3567 min = lt->tm_min;
3568 sec = lt->tm_sec;
3569#endif
3570
3571 if( year > to->year )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003572 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003573
Paul Bakkercce9d772011-11-18 14:26:47 +00003574 if( year == to->year &&
3575 mon > to->mon )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003576 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003577
Paul Bakkercce9d772011-11-18 14:26:47 +00003578 if( year == to->year &&
3579 mon == to->mon &&
3580 day > to->day )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003581 return( 1 );
3582
Paul Bakkercce9d772011-11-18 14:26:47 +00003583 if( year == to->year &&
3584 mon == to->mon &&
3585 day == to->day &&
3586 hour > to->hour )
Paul Bakkerb6194992011-01-16 21:40:22 +00003587 return( 1 );
3588
Paul Bakkercce9d772011-11-18 14:26:47 +00003589 if( year == to->year &&
3590 mon == to->mon &&
3591 day == to->day &&
3592 hour == to->hour &&
3593 min > to->min )
Paul Bakkerb6194992011-01-16 21:40:22 +00003594 return( 1 );
3595
Paul Bakkercce9d772011-11-18 14:26:47 +00003596 if( year == to->year &&
3597 mon == to->mon &&
3598 day == to->day &&
3599 hour == to->hour &&
3600 min == to->min &&
3601 sec > to->sec )
Paul Bakkerb6194992011-01-16 21:40:22 +00003602 return( 1 );
3603
Paul Bakker40ea7de2009-05-03 10:18:48 +00003604 return( 0 );
3605}
Paul Bakkerfa9b1002013-07-03 15:31:03 +02003606#else /* POLARSSL_HAVE_TIME */
3607int x509parse_time_expired( const x509_time *to )
3608{
3609 ((void) to);
3610 return( 0 );
3611}
3612#endif /* POLARSSL_HAVE_TIME */
Paul Bakker40ea7de2009-05-03 10:18:48 +00003613
3614/*
3615 * Return 1 if the certificate is revoked, or 0 otherwise.
3616 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003617int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003618{
Paul Bakkerff60ee62010-03-16 21:09:09 +00003619 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00003620
3621 while( cur != NULL && cur->serial.len != 0 )
3622 {
Paul Bakkera056efc2011-01-16 21:38:35 +00003623 if( crt->serial.len == cur->serial.len &&
3624 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003625 {
3626 if( x509parse_time_expired( &cur->revocation_date ) )
3627 return( 1 );
3628 }
3629
3630 cur = cur->next;
3631 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003632
3633 return( 0 );
3634}
3635
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003636/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00003637 * Check that the given certificate is valid accoring to the CRL.
3638 */
3639static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
3640 x509_crl *crl_list)
3641{
3642 int flags = 0;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003643 unsigned char hash[POLARSSL_MD_MAX_SIZE];
3644 const md_info_t *md_info;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003645
Paul Bakker915275b2012-09-28 07:10:55 +00003646 if( ca == NULL )
3647 return( flags );
3648
Paul Bakker76fd75a2011-01-16 21:12:10 +00003649 /*
3650 * TODO: What happens if no CRL is present?
3651 * Suggestion: Revocation state should be unknown if no CRL is present.
3652 * For backwards compatibility this is not yet implemented.
3653 */
3654
Paul Bakker915275b2012-09-28 07:10:55 +00003655 while( crl_list != NULL )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003656 {
Paul Bakker915275b2012-09-28 07:10:55 +00003657 if( crl_list->version == 0 ||
3658 crl_list->issuer_raw.len != ca->subject_raw.len ||
Paul Bakker76fd75a2011-01-16 21:12:10 +00003659 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
3660 crl_list->issuer_raw.len ) != 0 )
3661 {
3662 crl_list = crl_list->next;
3663 continue;
3664 }
3665
3666 /*
3667 * Check if CRL is correctly signed by the trusted CA
3668 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02003669 md_info = md_info_from_type( crl_list->sig_md );
3670 if( md_info == NULL )
3671 {
3672 /*
3673 * Cannot check 'unknown' hash
3674 */
3675 flags |= BADCRL_NOT_TRUSTED;
3676 break;
3677 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00003678
Paul Bakkerc70b9822013-04-07 22:00:46 +02003679 md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
Paul Bakker76fd75a2011-01-16 21:12:10 +00003680
Paul Bakkerc70b9822013-04-07 22:00:46 +02003681 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, crl_list->sig_md,
Paul Bakker76fd75a2011-01-16 21:12:10 +00003682 0, hash, crl_list->sig.p ) == 0 )
3683 {
3684 /*
3685 * CRL is not trusted
3686 */
3687 flags |= BADCRL_NOT_TRUSTED;
3688 break;
3689 }
3690
3691 /*
3692 * Check for validity of CRL (Do not drop out)
3693 */
3694 if( x509parse_time_expired( &crl_list->next_update ) )
3695 flags |= BADCRL_EXPIRED;
3696
3697 /*
3698 * Check if certificate is revoked
3699 */
3700 if( x509parse_revoked(crt, crl_list) )
3701 {
3702 flags |= BADCERT_REVOKED;
3703 break;
3704 }
3705
3706 crl_list = crl_list->next;
3707 }
3708 return flags;
3709}
3710
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02003711static int x509_wildcard_verify( const char *cn, x509_buf *name )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003712{
3713 size_t i;
3714 size_t cn_idx = 0;
3715
Paul Bakker57b12982012-02-11 17:38:38 +00003716 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003717 return( 0 );
3718
3719 for( i = 0; i < strlen( cn ); ++i )
3720 {
3721 if( cn[i] == '.' )
3722 {
3723 cn_idx = i;
3724 break;
3725 }
3726 }
3727
3728 if( cn_idx == 0 )
3729 return( 0 );
3730
Paul Bakker535e97d2012-08-23 10:49:55 +00003731 if( strlen( cn ) - cn_idx == name->len - 1 &&
3732 memcmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003733 {
3734 return( 1 );
3735 }
3736
3737 return( 0 );
3738}
3739
Paul Bakker915275b2012-09-28 07:10:55 +00003740static int x509parse_verify_top(
3741 x509_cert *child, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003742 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003743 int (*f_vrfy)(void *, x509_cert *, int, int *),
3744 void *p_vrfy )
3745{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003746 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003747 int ca_flags = 0, check_path_cnt = path_cnt + 1;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003748 unsigned char hash[POLARSSL_MD_MAX_SIZE];
3749 const md_info_t *md_info;
Paul Bakker915275b2012-09-28 07:10:55 +00003750
3751 if( x509parse_time_expired( &child->valid_to ) )
3752 *flags |= BADCERT_EXPIRED;
3753
3754 /*
3755 * Child is the top of the chain. Check against the trust_ca list.
3756 */
3757 *flags |= BADCERT_NOT_TRUSTED;
3758
3759 while( trust_ca != NULL )
3760 {
3761 if( trust_ca->version == 0 ||
3762 child->issuer_raw.len != trust_ca->subject_raw.len ||
3763 memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
3764 child->issuer_raw.len ) != 0 )
3765 {
3766 trust_ca = trust_ca->next;
3767 continue;
3768 }
3769
Paul Bakker9a736322012-11-14 12:39:52 +00003770 /*
3771 * Reduce path_len to check against if top of the chain is
3772 * the same as the trusted CA
3773 */
3774 if( child->subject_raw.len == trust_ca->subject_raw.len &&
3775 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3776 child->issuer_raw.len ) == 0 )
3777 {
3778 check_path_cnt--;
3779 }
3780
Paul Bakker915275b2012-09-28 07:10:55 +00003781 if( trust_ca->max_pathlen > 0 &&
Paul Bakker9a736322012-11-14 12:39:52 +00003782 trust_ca->max_pathlen < check_path_cnt )
Paul Bakker915275b2012-09-28 07:10:55 +00003783 {
3784 trust_ca = trust_ca->next;
3785 continue;
3786 }
3787
Paul Bakkerc70b9822013-04-07 22:00:46 +02003788 md_info = md_info_from_type( child->sig_md );
3789 if( md_info == NULL )
3790 {
3791 /*
3792 * Cannot check 'unknown' hash
3793 */
3794 continue;
3795 }
Paul Bakker915275b2012-09-28 07:10:55 +00003796
Paul Bakkerc70b9822013-04-07 22:00:46 +02003797 md( md_info, child->tbs.p, child->tbs.len, hash );
Paul Bakker915275b2012-09-28 07:10:55 +00003798
Paul Bakkerc70b9822013-04-07 22:00:46 +02003799 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, child->sig_md,
Paul Bakker915275b2012-09-28 07:10:55 +00003800 0, hash, child->sig.p ) != 0 )
3801 {
3802 trust_ca = trust_ca->next;
3803 continue;
3804 }
3805
3806 /*
3807 * Top of chain is signed by a trusted CA
3808 */
3809 *flags &= ~BADCERT_NOT_TRUSTED;
3810 break;
3811 }
3812
Paul Bakker9a736322012-11-14 12:39:52 +00003813 /*
Paul Bakker3497d8c2012-11-24 11:53:17 +01003814 * If top of chain is not the same as the trusted CA send a verify request
3815 * to the callback for any issues with validity and CRL presence for the
3816 * trusted CA certificate.
Paul Bakker9a736322012-11-14 12:39:52 +00003817 */
3818 if( trust_ca != NULL &&
3819 ( child->subject_raw.len != trust_ca->subject_raw.len ||
3820 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3821 child->issuer_raw.len ) != 0 ) )
Paul Bakker915275b2012-09-28 07:10:55 +00003822 {
3823 /* Check trusted CA's CRL for then chain's top crt */
3824 *flags |= x509parse_verifycrl( child, trust_ca, ca_crl );
3825
3826 if( x509parse_time_expired( &trust_ca->valid_to ) )
3827 ca_flags |= BADCERT_EXPIRED;
3828
Paul Bakker915275b2012-09-28 07:10:55 +00003829 if( NULL != f_vrfy )
3830 {
Paul Bakker9a736322012-11-14 12:39:52 +00003831 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003832 return( ret );
3833 }
3834 }
3835
3836 /* Call callback on top cert */
3837 if( NULL != f_vrfy )
3838 {
Paul Bakker9a736322012-11-14 12:39:52 +00003839 if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003840 return( ret );
3841 }
3842
Paul Bakker915275b2012-09-28 07:10:55 +00003843 *flags |= ca_flags;
3844
3845 return( 0 );
3846}
3847
3848static int x509parse_verify_child(
3849 x509_cert *child, x509_cert *parent, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003850 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003851 int (*f_vrfy)(void *, x509_cert *, int, int *),
3852 void *p_vrfy )
3853{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003854 int ret;
Paul Bakker915275b2012-09-28 07:10:55 +00003855 int parent_flags = 0;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003856 unsigned char hash[POLARSSL_MD_MAX_SIZE];
Paul Bakker915275b2012-09-28 07:10:55 +00003857 x509_cert *grandparent;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003858 const md_info_t *md_info;
Paul Bakker915275b2012-09-28 07:10:55 +00003859
3860 if( x509parse_time_expired( &child->valid_to ) )
3861 *flags |= BADCERT_EXPIRED;
3862
Paul Bakkerc70b9822013-04-07 22:00:46 +02003863 md_info = md_info_from_type( child->sig_md );
3864 if( md_info == NULL )
3865 {
3866 /*
3867 * Cannot check 'unknown' hash
3868 */
Paul Bakker915275b2012-09-28 07:10:55 +00003869 *flags |= BADCERT_NOT_TRUSTED;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003870 }
3871 else
3872 {
3873 md( md_info, child->tbs.p, child->tbs.len, hash );
3874
3875 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, child->sig_md, 0, hash,
3876 child->sig.p ) != 0 )
3877 *flags |= BADCERT_NOT_TRUSTED;
3878 }
3879
Paul Bakker915275b2012-09-28 07:10:55 +00003880 /* Check trusted CA's CRL for the given crt */
3881 *flags |= x509parse_verifycrl(child, parent, ca_crl);
3882
3883 grandparent = parent->next;
3884
3885 while( grandparent != NULL )
3886 {
3887 if( grandparent->version == 0 ||
3888 grandparent->ca_istrue == 0 ||
3889 parent->issuer_raw.len != grandparent->subject_raw.len ||
3890 memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
3891 parent->issuer_raw.len ) != 0 )
3892 {
3893 grandparent = grandparent->next;
3894 continue;
3895 }
3896 break;
3897 }
3898
Paul Bakker915275b2012-09-28 07:10:55 +00003899 if( grandparent != NULL )
3900 {
3901 /*
3902 * Part of the chain
3903 */
Paul Bakker9a736322012-11-14 12:39:52 +00003904 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 +00003905 if( ret != 0 )
3906 return( ret );
3907 }
3908 else
3909 {
Paul Bakker9a736322012-11-14 12:39:52 +00003910 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 +00003911 if( ret != 0 )
3912 return( ret );
3913 }
3914
3915 /* child is verified to be a child of the parent, call verify callback */
3916 if( NULL != f_vrfy )
Paul Bakker9a736322012-11-14 12:39:52 +00003917 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003918 return( ret );
Paul Bakker915275b2012-09-28 07:10:55 +00003919
3920 *flags |= parent_flags;
3921
3922 return( 0 );
3923}
3924
Paul Bakker76fd75a2011-01-16 21:12:10 +00003925/*
Paul Bakker5121ce52009-01-03 21:22:43 +00003926 * Verify the certificate validity
3927 */
3928int x509parse_verify( x509_cert *crt,
3929 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00003930 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003931 const char *cn, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003932 int (*f_vrfy)(void *, x509_cert *, int, int *),
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003933 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00003934{
Paul Bakker23986e52011-04-24 08:57:21 +00003935 size_t cn_len;
Paul Bakker915275b2012-09-28 07:10:55 +00003936 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003937 int pathlen = 0;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003938 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00003939 x509_name *name;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003940 x509_sequence *cur = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003941
Paul Bakker40ea7de2009-05-03 10:18:48 +00003942 *flags = 0;
3943
Paul Bakker5121ce52009-01-03 21:22:43 +00003944 if( cn != NULL )
3945 {
3946 name = &crt->subject;
3947 cn_len = strlen( cn );
3948
Paul Bakker4d2c1242012-05-10 14:12:46 +00003949 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
Paul Bakker5121ce52009-01-03 21:22:43 +00003950 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00003951 cur = &crt->subject_alt_names;
3952
3953 while( cur != NULL )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003954 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003955 if( cur->buf.len == cn_len &&
3956 memcmp( cn, cur->buf.p, cn_len ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003957 break;
3958
Paul Bakker535e97d2012-08-23 10:49:55 +00003959 if( cur->buf.len > 2 &&
3960 memcmp( cur->buf.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003961 x509_wildcard_verify( cn, &cur->buf ) )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003962 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003963
Paul Bakker4d2c1242012-05-10 14:12:46 +00003964 cur = cur->next;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003965 }
3966
3967 if( cur == NULL )
3968 *flags |= BADCERT_CN_MISMATCH;
3969 }
Paul Bakker4d2c1242012-05-10 14:12:46 +00003970 else
3971 {
3972 while( name != NULL )
3973 {
Paul Bakkerc70b9822013-04-07 22:00:46 +02003974 if( OID_CMP( OID_AT_CN, &name->oid ) )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003975 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003976 if( name->val.len == cn_len &&
3977 memcmp( name->val.p, cn, cn_len ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003978 break;
3979
Paul Bakker535e97d2012-08-23 10:49:55 +00003980 if( name->val.len > 2 &&
3981 memcmp( name->val.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003982 x509_wildcard_verify( cn, &name->val ) )
3983 break;
3984 }
3985
3986 name = name->next;
3987 }
3988
3989 if( name == NULL )
3990 *flags |= BADCERT_CN_MISMATCH;
3991 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003992 }
3993
Paul Bakker5121ce52009-01-03 21:22:43 +00003994 /*
Paul Bakker915275b2012-09-28 07:10:55 +00003995 * Iterate upwards in the given cert chain, to find our crt parent.
3996 * Ignore any upper cert with CA != TRUE.
Paul Bakker5121ce52009-01-03 21:22:43 +00003997 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003998 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003999
Paul Bakker76fd75a2011-01-16 21:12:10 +00004000 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00004001 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00004002 if( parent->ca_istrue == 0 ||
4003 crt->issuer_raw.len != parent->subject_raw.len ||
4004 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00004005 crt->issuer_raw.len ) != 0 )
4006 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00004007 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00004008 continue;
4009 }
Paul Bakker915275b2012-09-28 07:10:55 +00004010 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00004011 }
4012
Paul Bakker915275b2012-09-28 07:10:55 +00004013 if( parent != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00004014 {
Paul Bakker915275b2012-09-28 07:10:55 +00004015 /*
4016 * Part of the chain
4017 */
Paul Bakker9a736322012-11-14 12:39:52 +00004018 ret = x509parse_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00004019 if( ret != 0 )
4020 return( ret );
4021 }
4022 else
Paul Bakker74111d32011-01-15 16:57:55 +00004023 {
Paul Bakker9a736322012-11-14 12:39:52 +00004024 ret = x509parse_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00004025 if( ret != 0 )
4026 return( ret );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00004027 }
Paul Bakker915275b2012-09-28 07:10:55 +00004028
4029 if( *flags != 0 )
Paul Bakker76fd75a2011-01-16 21:12:10 +00004030 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00004031
Paul Bakker5121ce52009-01-03 21:22:43 +00004032 return( 0 );
4033}
4034
4035/*
4036 * Unallocate all certificate data
4037 */
4038void x509_free( x509_cert *crt )
4039{
4040 x509_cert *cert_cur = crt;
4041 x509_cert *cert_prv;
4042 x509_name *name_cur;
4043 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00004044 x509_sequence *seq_cur;
4045 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00004046
4047 if( crt == NULL )
4048 return;
4049
4050 do
4051 {
4052 rsa_free( &cert_cur->rsa );
4053
4054 name_cur = cert_cur->issuer.next;
4055 while( name_cur != NULL )
4056 {
4057 name_prv = name_cur;
4058 name_cur = name_cur->next;
4059 memset( name_prv, 0, sizeof( x509_name ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02004060 polarssl_free( name_prv );
Paul Bakker5121ce52009-01-03 21:22:43 +00004061 }
4062
4063 name_cur = cert_cur->subject.next;
4064 while( name_cur != NULL )
4065 {
4066 name_prv = name_cur;
4067 name_cur = name_cur->next;
4068 memset( name_prv, 0, sizeof( x509_name ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02004069 polarssl_free( name_prv );
Paul Bakker5121ce52009-01-03 21:22:43 +00004070 }
4071
Paul Bakker74111d32011-01-15 16:57:55 +00004072 seq_cur = cert_cur->ext_key_usage.next;
4073 while( seq_cur != NULL )
4074 {
4075 seq_prv = seq_cur;
4076 seq_cur = seq_cur->next;
4077 memset( seq_prv, 0, sizeof( x509_sequence ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02004078 polarssl_free( seq_prv );
Paul Bakker74111d32011-01-15 16:57:55 +00004079 }
4080
Paul Bakker8afa70d2012-02-11 18:42:45 +00004081 seq_cur = cert_cur->subject_alt_names.next;
4082 while( seq_cur != NULL )
4083 {
4084 seq_prv = seq_cur;
4085 seq_cur = seq_cur->next;
4086 memset( seq_prv, 0, sizeof( x509_sequence ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02004087 polarssl_free( seq_prv );
Paul Bakker8afa70d2012-02-11 18:42:45 +00004088 }
4089
Paul Bakker5121ce52009-01-03 21:22:43 +00004090 if( cert_cur->raw.p != NULL )
4091 {
4092 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
Paul Bakker6e339b52013-07-03 13:37:05 +02004093 polarssl_free( cert_cur->raw.p );
Paul Bakker5121ce52009-01-03 21:22:43 +00004094 }
4095
4096 cert_cur = cert_cur->next;
4097 }
4098 while( cert_cur != NULL );
4099
4100 cert_cur = crt;
4101 do
4102 {
4103 cert_prv = cert_cur;
4104 cert_cur = cert_cur->next;
4105
4106 memset( cert_prv, 0, sizeof( x509_cert ) );
4107 if( cert_prv != crt )
Paul Bakker6e339b52013-07-03 13:37:05 +02004108 polarssl_free( cert_prv );
Paul Bakker5121ce52009-01-03 21:22:43 +00004109 }
4110 while( cert_cur != NULL );
4111}
4112
Paul Bakkerd98030e2009-05-02 15:13:40 +00004113/*
4114 * Unallocate all CRL data
4115 */
4116void x509_crl_free( x509_crl *crl )
4117{
4118 x509_crl *crl_cur = crl;
4119 x509_crl *crl_prv;
4120 x509_name *name_cur;
4121 x509_name *name_prv;
4122 x509_crl_entry *entry_cur;
4123 x509_crl_entry *entry_prv;
4124
4125 if( crl == NULL )
4126 return;
4127
4128 do
4129 {
4130 name_cur = crl_cur->issuer.next;
4131 while( name_cur != NULL )
4132 {
4133 name_prv = name_cur;
4134 name_cur = name_cur->next;
4135 memset( name_prv, 0, sizeof( x509_name ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02004136 polarssl_free( name_prv );
Paul Bakkerd98030e2009-05-02 15:13:40 +00004137 }
4138
4139 entry_cur = crl_cur->entry.next;
4140 while( entry_cur != NULL )
4141 {
4142 entry_prv = entry_cur;
4143 entry_cur = entry_cur->next;
4144 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02004145 polarssl_free( entry_prv );
Paul Bakkerd98030e2009-05-02 15:13:40 +00004146 }
4147
4148 if( crl_cur->raw.p != NULL )
4149 {
4150 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
Paul Bakker6e339b52013-07-03 13:37:05 +02004151 polarssl_free( crl_cur->raw.p );
Paul Bakkerd98030e2009-05-02 15:13:40 +00004152 }
4153
4154 crl_cur = crl_cur->next;
4155 }
4156 while( crl_cur != NULL );
4157
4158 crl_cur = crl;
4159 do
4160 {
4161 crl_prv = crl_cur;
4162 crl_cur = crl_cur->next;
4163
4164 memset( crl_prv, 0, sizeof( x509_crl ) );
4165 if( crl_prv != crl )
Paul Bakker6e339b52013-07-03 13:37:05 +02004166 polarssl_free( crl_prv );
Paul Bakkerd98030e2009-05-02 15:13:40 +00004167 }
4168 while( crl_cur != NULL );
4169}
4170
Paul Bakker40e46942009-01-03 21:51:57 +00004171#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00004172
Paul Bakker40e46942009-01-03 21:51:57 +00004173#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00004174
4175/*
4176 * Checkup routine
4177 */
4178int x509_self_test( int verbose )
4179{
Paul Bakker5690efc2011-05-26 13:16:06 +00004180#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00004181 int ret;
4182 int flags;
4183 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00004184 x509_cert cacert;
4185 x509_cert clicert;
4186 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00004187#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00004188 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00004189#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00004190
4191 if( verbose != 0 )
4192 printf( " X.509 certificate load: " );
4193
4194 memset( &clicert, 0, sizeof( x509_cert ) );
4195
Paul Bakker3c2122f2013-06-24 19:03:14 +02004196 ret = x509parse_crt( &clicert, (const unsigned char *) test_cli_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00004197 strlen( test_cli_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00004198 if( ret != 0 )
4199 {
4200 if( verbose != 0 )
4201 printf( "failed\n" );
4202
4203 return( ret );
4204 }
4205
4206 memset( &cacert, 0, sizeof( x509_cert ) );
4207
Paul Bakker3c2122f2013-06-24 19:03:14 +02004208 ret = x509parse_crt( &cacert, (const unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00004209 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00004210 if( ret != 0 )
4211 {
4212 if( verbose != 0 )
4213 printf( "failed\n" );
4214
4215 return( ret );
4216 }
4217
4218 if( verbose != 0 )
4219 printf( "passed\n X.509 private key load: " );
4220
4221 i = strlen( test_ca_key );
4222 j = strlen( test_ca_pwd );
4223
Paul Bakker66b78b22011-03-25 14:22:50 +00004224 rsa_init( &rsa, RSA_PKCS_V15, 0 );
4225
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02004226 if( ( ret = x509parse_key_rsa( &rsa,
Paul Bakker3c2122f2013-06-24 19:03:14 +02004227 (const unsigned char *) test_ca_key, i,
4228 (const unsigned char *) test_ca_pwd, j ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00004229 {
4230 if( verbose != 0 )
4231 printf( "failed\n" );
4232
4233 return( ret );
4234 }
4235
4236 if( verbose != 0 )
4237 printf( "passed\n X.509 signature verify: ");
4238
Paul Bakker23986e52011-04-24 08:57:21 +00004239 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00004240 if( ret != 0 )
4241 {
Paul Bakker23986e52011-04-24 08:57:21 +00004242 printf("%02x", flags);
Paul Bakker5121ce52009-01-03 21:22:43 +00004243 if( verbose != 0 )
4244 printf( "failed\n" );
4245
4246 return( ret );
4247 }
4248
Paul Bakker5690efc2011-05-26 13:16:06 +00004249#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00004250 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00004251 printf( "passed\n X.509 DHM parameter load: " );
4252
4253 i = strlen( test_dhm_params );
4254 j = strlen( test_ca_pwd );
4255
Paul Bakker3c2122f2013-06-24 19:03:14 +02004256 if( ( ret = x509parse_dhm( &dhm, (const unsigned char *) test_dhm_params, i ) ) != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00004257 {
4258 if( verbose != 0 )
4259 printf( "failed\n" );
4260
4261 return( ret );
4262 }
4263
4264 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00004265 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00004266#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00004267
4268 x509_free( &cacert );
4269 x509_free( &clicert );
4270 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00004271#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00004272 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00004273#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00004274
4275 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00004276#else
4277 ((void) verbose);
4278 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
4279#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00004280}
4281
4282#endif
4283
4284#endif