blob: 840319f43f5bd01623ec881c0b674e208bace556 [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/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000237 * AttributeTypeAndValue ::= SEQUENCE {
238 * type AttributeType,
239 * value AttributeValue }
240 *
241 * AttributeType ::= OBJECT IDENTIFIER
242 *
243 * AttributeValue ::= ANY DEFINED BY AttributeType
244 */
Paul Bakker400ff6f2011-02-20 10:40:16 +0000245static int x509_get_attr_type_value( unsigned char **p,
246 const unsigned char *end,
247 x509_name *cur )
Paul Bakker5121ce52009-01-03 21:22:43 +0000248{
Paul Bakker23986e52011-04-24 08:57:21 +0000249 int ret;
250 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000251 x509_buf *oid;
252 x509_buf *val;
253
254 if( ( ret = asn1_get_tag( p, end, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000255 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000256 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000257
Paul Bakker5121ce52009-01-03 21:22:43 +0000258 oid = &cur->oid;
259 oid->tag = **p;
260
261 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000262 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000263
264 oid->p = *p;
265 *p += oid->len;
266
267 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000268 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000269 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000270
271 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
272 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
273 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker9d781402011-05-09 16:17:09 +0000274 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000275 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000276
277 val = &cur->val;
278 val->tag = *(*p)++;
279
280 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000281 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000282
283 val->p = *p;
284 *p += val->len;
285
286 cur->next = NULL;
287
Paul Bakker400ff6f2011-02-20 10:40:16 +0000288 return( 0 );
289}
290
291/*
292 * RelativeDistinguishedName ::=
293 * SET OF AttributeTypeAndValue
294 *
295 * AttributeTypeAndValue ::= SEQUENCE {
296 * type AttributeType,
297 * value AttributeValue }
298 *
299 * AttributeType ::= OBJECT IDENTIFIER
300 *
301 * AttributeValue ::= ANY DEFINED BY AttributeType
302 */
303static int x509_get_name( unsigned char **p,
304 const unsigned char *end,
305 x509_name *cur )
306{
Paul Bakker23986e52011-04-24 08:57:21 +0000307 int ret;
308 size_t len;
Paul Bakker400ff6f2011-02-20 10:40:16 +0000309 const unsigned char *end2;
310 x509_name *use;
311
312 if( ( ret = asn1_get_tag( p, end, &len,
313 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000314 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000315
316 end2 = end;
317 end = *p + len;
318 use = cur;
319
320 do
321 {
322 if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
323 return( ret );
324
325 if( *p != end )
326 {
Paul Bakker6e339b52013-07-03 13:37:05 +0200327 use->next = (x509_name *) polarssl_malloc(
Paul Bakker400ff6f2011-02-20 10:40:16 +0000328 sizeof( x509_name ) );
329
330 if( use->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000331 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000332
333 memset( use->next, 0, sizeof( x509_name ) );
334
335 use = use->next;
336 }
337 }
338 while( *p != end );
Paul Bakker5121ce52009-01-03 21:22:43 +0000339
340 /*
341 * recurse until end of SEQUENCE is reached
342 */
343 if( *p == end2 )
344 return( 0 );
345
Paul Bakker6e339b52013-07-03 13:37:05 +0200346 cur->next = (x509_name *) polarssl_malloc(
Paul Bakker5121ce52009-01-03 21:22:43 +0000347 sizeof( x509_name ) );
348
349 if( cur->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000350 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000351
Paul Bakker430ffbe2012-05-01 08:14:20 +0000352 memset( cur->next, 0, sizeof( x509_name ) );
353
Paul Bakker5121ce52009-01-03 21:22:43 +0000354 return( x509_get_name( p, end2, cur->next ) );
355}
356
357/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000358 * Time ::= CHOICE {
359 * utcTime UTCTime,
360 * generalTime GeneralizedTime }
361 */
Paul Bakker91200182010-02-18 21:26:15 +0000362static int x509_get_time( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000363 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000364 x509_time *time )
365{
Paul Bakker23986e52011-04-24 08:57:21 +0000366 int ret;
367 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000368 char date[64];
Paul Bakker91200182010-02-18 21:26:15 +0000369 unsigned char tag;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000370
Paul Bakker91200182010-02-18 21:26:15 +0000371 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000372 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
373 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000374
Paul Bakker91200182010-02-18 21:26:15 +0000375 tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000376
Paul Bakker91200182010-02-18 21:26:15 +0000377 if ( tag == ASN1_UTC_TIME )
378 {
379 (*p)++;
380 ret = asn1_get_len( p, end, &len );
381
382 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000383 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000384
Paul Bakker91200182010-02-18 21:26:15 +0000385 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000386 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
387 len : sizeof( date ) - 1 );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000388
Paul Bakker91200182010-02-18 21:26:15 +0000389 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
390 &time->year, &time->mon, &time->day,
391 &time->hour, &time->min, &time->sec ) < 5 )
392 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000393
Paul Bakker400ff6f2011-02-20 10:40:16 +0000394 time->year += 100 * ( time->year < 50 );
Paul Bakker91200182010-02-18 21:26:15 +0000395 time->year += 1900;
396
397 *p += len;
398
399 return( 0 );
400 }
401 else if ( tag == ASN1_GENERALIZED_TIME )
402 {
403 (*p)++;
404 ret = asn1_get_len( p, end, &len );
405
406 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000407 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker91200182010-02-18 21:26:15 +0000408
409 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000410 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
411 len : sizeof( date ) - 1 );
Paul Bakker91200182010-02-18 21:26:15 +0000412
413 if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
414 &time->year, &time->mon, &time->day,
415 &time->hour, &time->min, &time->sec ) < 5 )
416 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
417
418 *p += len;
419
420 return( 0 );
421 }
422 else
Paul Bakker9d781402011-05-09 16:17:09 +0000423 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000424}
425
426
427/*
428 * Validity ::= SEQUENCE {
429 * notBefore Time,
430 * notAfter Time }
431 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000432static int x509_get_dates( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000433 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000434 x509_time *from,
435 x509_time *to )
436{
Paul Bakker23986e52011-04-24 08:57:21 +0000437 int ret;
438 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000439
440 if( ( ret = asn1_get_tag( p, end, &len,
441 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000442 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000443
444 end = *p + len;
445
Paul Bakker91200182010-02-18 21:26:15 +0000446 if( ( ret = x509_get_time( p, end, from ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000447 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000448
Paul Bakker91200182010-02-18 21:26:15 +0000449 if( ( ret = x509_get_time( p, end, to ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000450 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000451
452 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000453 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker40e46942009-01-03 21:51:57 +0000454 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000455
456 return( 0 );
457}
458
459/*
460 * SubjectPublicKeyInfo ::= SEQUENCE {
461 * algorithm AlgorithmIdentifier,
462 * subjectPublicKey BIT STRING }
463 */
464static int x509_get_pubkey( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000465 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000466 x509_buf *pk_alg_oid,
467 mpi *N, mpi *E )
468{
Paul Bakkerc70b9822013-04-07 22:00:46 +0200469 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000470 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000471 unsigned char *end2;
Paul Bakkerc70b9822013-04-07 22:00:46 +0200472 pk_type_t pk_alg = POLARSSL_PK_NONE;
Paul Bakker5121ce52009-01-03 21:22:43 +0000473
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200474 if( ( ret = asn1_get_alg_null( p, end, pk_alg_oid ) ) != 0 )
475 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000476
477 /*
478 * only RSA public keys handled at this time
479 */
Paul Bakkerc70b9822013-04-07 22:00:46 +0200480 if( oid_get_pk_alg( pk_alg_oid, &pk_alg ) != 0 )
Paul Bakkered56b222011-07-13 11:26:43 +0000481 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000482
483 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000484 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000485
486 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000487 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000488 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000489
490 end2 = *p + len;
491
492 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000493 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000494
495 /*
496 * RSAPublicKey ::= SEQUENCE {
497 * modulus INTEGER, -- n
498 * publicExponent INTEGER -- e
499 * }
500 */
501 if( ( ret = asn1_get_tag( p, end2, &len,
502 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000503 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000504
505 if( *p + len != end2 )
Paul Bakker9d781402011-05-09 16:17:09 +0000506 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000507 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000508
509 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
510 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000511 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000512
513 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000514 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000515 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000516
517 return( 0 );
518}
519
520static int x509_get_sig( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000521 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000522 x509_buf *sig )
523{
Paul Bakker23986e52011-04-24 08:57:21 +0000524 int ret;
525 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000526
Paul Bakker8afa70d2012-02-11 18:42:45 +0000527 if( ( end - *p ) < 1 )
528 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE +
529 POLARSSL_ERR_ASN1_OUT_OF_DATA );
530
Paul Bakker5121ce52009-01-03 21:22:43 +0000531 sig->tag = **p;
532
533 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000534 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000535
Paul Bakker74111d32011-01-15 16:57:55 +0000536
Paul Bakker5121ce52009-01-03 21:22:43 +0000537 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000538 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000539
540 sig->len = len;
541 sig->p = *p;
542
543 *p += len;
544
545 return( 0 );
546}
547
548/*
549 * X.509 v2/v3 unique identifier (not parsed)
550 */
551static int x509_get_uid( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000552 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000553 x509_buf *uid, int n )
554{
555 int ret;
556
557 if( *p == end )
558 return( 0 );
559
560 uid->tag = **p;
561
562 if( ( ret = asn1_get_tag( p, end, &uid->len,
563 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
564 {
Paul Bakker40e46942009-01-03 21:51:57 +0000565 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000566 return( 0 );
567
568 return( ret );
569 }
570
571 uid->p = *p;
572 *p += uid->len;
573
574 return( 0 );
575}
576
577/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000578 * X.509 Extensions (No parsing of extensions, pointer should
579 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000580 */
581static int x509_get_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000582 const unsigned char *end,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000583 x509_buf *ext, int tag )
Paul Bakker5121ce52009-01-03 21:22:43 +0000584{
Paul Bakker23986e52011-04-24 08:57:21 +0000585 int ret;
586 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000587
588 if( *p == end )
589 return( 0 );
590
591 ext->tag = **p;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000592
Paul Bakker5121ce52009-01-03 21:22:43 +0000593 if( ( ret = asn1_get_tag( p, end, &ext->len,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000594 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000595 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000596
597 ext->p = *p;
598 end = *p + ext->len;
599
600 /*
601 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
602 *
603 * Extension ::= SEQUENCE {
604 * extnID OBJECT IDENTIFIER,
605 * critical BOOLEAN DEFAULT FALSE,
606 * extnValue OCTET STRING }
607 */
608 if( ( ret = asn1_get_tag( p, end, &len,
609 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000610 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000611
612 if( end != *p + len )
Paul Bakker9d781402011-05-09 16:17:09 +0000613 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +0000614 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000615
Paul Bakkerd98030e2009-05-02 15:13:40 +0000616 return( 0 );
617}
618
619/*
620 * X.509 CRL v2 extensions (no extensions parsed yet.)
621 */
622static int x509_get_crl_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000623 const unsigned char *end,
624 x509_buf *ext )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000625{
Paul Bakker23986e52011-04-24 08:57:21 +0000626 int ret;
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000627 size_t len = 0;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000628
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000629 /* Get explicit tag */
630 if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000631 {
632 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
633 return( 0 );
634
635 return( ret );
636 }
637
638 while( *p < end )
639 {
640 if( ( ret = asn1_get_tag( p, end, &len,
641 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000642 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000643
644 *p += len;
645 }
646
647 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000648 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerd98030e2009-05-02 15:13:40 +0000649 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
650
651 return( 0 );
652}
653
Paul Bakkerb5a11ab2011-10-12 09:58:41 +0000654/*
655 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
656 */
657static int x509_get_crl_entry_ext( unsigned char **p,
658 const unsigned char *end,
659 x509_buf *ext )
660{
661 int ret;
662 size_t len = 0;
663
664 /* OPTIONAL */
665 if (end <= *p)
666 return( 0 );
667
668 ext->tag = **p;
669 ext->p = *p;
670
671 /*
672 * Get CRL-entry extension sequence header
673 * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
674 */
675 if( ( ret = asn1_get_tag( p, end, &ext->len,
676 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
677 {
678 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
679 {
680 ext->p = NULL;
681 return( 0 );
682 }
683 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
684 }
685
686 end = *p + ext->len;
687
688 if( end != *p + ext->len )
689 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
690 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
691
692 while( *p < end )
693 {
694 if( ( ret = asn1_get_tag( p, end, &len,
695 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
696 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
697
698 *p += len;
699 }
700
701 if( *p != end )
702 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
703 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
704
705 return( 0 );
706}
707
Paul Bakker74111d32011-01-15 16:57:55 +0000708static int x509_get_basic_constraints( unsigned char **p,
709 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000710 int *ca_istrue,
711 int *max_pathlen )
712{
Paul Bakker23986e52011-04-24 08:57:21 +0000713 int ret;
714 size_t len;
Paul Bakker74111d32011-01-15 16:57:55 +0000715
716 /*
717 * BasicConstraints ::= SEQUENCE {
718 * cA BOOLEAN DEFAULT FALSE,
719 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
720 */
Paul Bakker3cccddb2011-01-16 21:46:31 +0000721 *ca_istrue = 0; /* DEFAULT FALSE */
Paul Bakker74111d32011-01-15 16:57:55 +0000722 *max_pathlen = 0; /* endless */
723
724 if( ( ret = asn1_get_tag( p, end, &len,
725 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000726 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000727
728 if( *p == end )
729 return 0;
730
Paul Bakker3cccddb2011-01-16 21:46:31 +0000731 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000732 {
733 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker3cccddb2011-01-16 21:46:31 +0000734 ret = asn1_get_int( p, end, ca_istrue );
Paul Bakker74111d32011-01-15 16:57:55 +0000735
736 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000737 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000738
Paul Bakker3cccddb2011-01-16 21:46:31 +0000739 if( *ca_istrue != 0 )
740 *ca_istrue = 1;
Paul Bakker74111d32011-01-15 16:57:55 +0000741 }
742
743 if( *p == end )
744 return 0;
745
746 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000747 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000748
749 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000750 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000751 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
752
753 (*max_pathlen)++;
754
Paul Bakker74111d32011-01-15 16:57:55 +0000755 return 0;
756}
757
758static int x509_get_ns_cert_type( unsigned char **p,
759 const unsigned char *end,
760 unsigned char *ns_cert_type)
761{
762 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000763 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000764
765 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000766 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000767
768 if( bs.len != 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000769 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000770 POLARSSL_ERR_ASN1_INVALID_LENGTH );
771
772 /* Get actual bitstring */
773 *ns_cert_type = *bs.p;
774 return 0;
775}
776
777static int x509_get_key_usage( unsigned char **p,
778 const unsigned char *end,
779 unsigned char *key_usage)
780{
781 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000782 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000783
784 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000785 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000786
Paul Bakker94a67962012-08-23 13:03:52 +0000787 if( bs.len < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000788 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000789 POLARSSL_ERR_ASN1_INVALID_LENGTH );
790
791 /* Get actual bitstring */
792 *key_usage = *bs.p;
793 return 0;
794}
795
Paul Bakkerd98030e2009-05-02 15:13:40 +0000796/*
Paul Bakker74111d32011-01-15 16:57:55 +0000797 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
798 *
799 * KeyPurposeId ::= OBJECT IDENTIFIER
800 */
801static int x509_get_ext_key_usage( unsigned char **p,
802 const unsigned char *end,
803 x509_sequence *ext_key_usage)
804{
805 int ret;
806
807 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000808 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000809
810 /* Sequence length must be >= 1 */
811 if( ext_key_usage->buf.p == NULL )
Paul Bakker9d781402011-05-09 16:17:09 +0000812 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000813 POLARSSL_ERR_ASN1_INVALID_LENGTH );
814
815 return 0;
816}
817
818/*
Paul Bakkera8cd2392012-02-11 16:09:32 +0000819 * SubjectAltName ::= GeneralNames
820 *
821 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
822 *
823 * GeneralName ::= CHOICE {
824 * otherName [0] OtherName,
825 * rfc822Name [1] IA5String,
826 * dNSName [2] IA5String,
827 * x400Address [3] ORAddress,
828 * directoryName [4] Name,
829 * ediPartyName [5] EDIPartyName,
830 * uniformResourceIdentifier [6] IA5String,
831 * iPAddress [7] OCTET STRING,
832 * registeredID [8] OBJECT IDENTIFIER }
833 *
834 * OtherName ::= SEQUENCE {
835 * type-id OBJECT IDENTIFIER,
836 * value [0] EXPLICIT ANY DEFINED BY type-id }
837 *
838 * EDIPartyName ::= SEQUENCE {
839 * nameAssigner [0] DirectoryString OPTIONAL,
840 * partyName [1] DirectoryString }
841 *
842 * NOTE: PolarSSL only parses and uses dNSName at this point.
843 */
844static int x509_get_subject_alt_name( unsigned char **p,
845 const unsigned char *end,
846 x509_sequence *subject_alt_name )
847{
848 int ret;
849 size_t len, tag_len;
850 asn1_buf *buf;
851 unsigned char tag;
852 asn1_sequence *cur = subject_alt_name;
853
854 /* Get main sequence tag */
855 if( ( ret = asn1_get_tag( p, end, &len,
856 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
857 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
858
859 if( *p + len != end )
860 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
861 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
862
863 while( *p < end )
864 {
865 if( ( end - *p ) < 1 )
866 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
867 POLARSSL_ERR_ASN1_OUT_OF_DATA );
868
869 tag = **p;
870 (*p)++;
871 if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 )
872 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
873
874 if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC )
875 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
876 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
877
878 if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) )
879 {
880 *p += tag_len;
881 continue;
882 }
883
884 buf = &(cur->buf);
885 buf->tag = tag;
886 buf->p = *p;
887 buf->len = tag_len;
888 *p += buf->len;
889
890 /* Allocate and assign next pointer */
891 if (*p < end)
892 {
Paul Bakker6e339b52013-07-03 13:37:05 +0200893 cur->next = (asn1_sequence *) polarssl_malloc(
Paul Bakkera8cd2392012-02-11 16:09:32 +0000894 sizeof( asn1_sequence ) );
895
896 if( cur->next == NULL )
897 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
898 POLARSSL_ERR_ASN1_MALLOC_FAILED );
899
Paul Bakker535e97d2012-08-23 10:49:55 +0000900 memset( cur->next, 0, sizeof( asn1_sequence ) );
Paul Bakkera8cd2392012-02-11 16:09:32 +0000901 cur = cur->next;
902 }
903 }
904
905 /* Set final sequence entry's next pointer to NULL */
906 cur->next = NULL;
907
908 if( *p != end )
909 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
910 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
911
912 return( 0 );
913}
914
915/*
Paul Bakker74111d32011-01-15 16:57:55 +0000916 * X.509 v3 extensions
917 *
918 * TODO: Perform all of the basic constraints tests required by the RFC
919 * TODO: Set values for undetected extensions to a sane default?
920 *
Paul Bakkerd98030e2009-05-02 15:13:40 +0000921 */
922static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000923 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000924 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000925{
Paul Bakker23986e52011-04-24 08:57:21 +0000926 int ret;
927 size_t len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000928 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000929
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000930 if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000931 {
932 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
933 return( 0 );
934
935 return( ret );
936 }
937
Paul Bakker5121ce52009-01-03 21:22:43 +0000938 while( *p < end )
939 {
Paul Bakker74111d32011-01-15 16:57:55 +0000940 /*
941 * Extension ::= SEQUENCE {
942 * extnID OBJECT IDENTIFIER,
943 * critical BOOLEAN DEFAULT FALSE,
944 * extnValue OCTET STRING }
945 */
946 x509_buf extn_oid = {0, 0, NULL};
947 int is_critical = 0; /* DEFAULT FALSE */
Paul Bakkerc70b9822013-04-07 22:00:46 +0200948 int ext_type = 0;
Paul Bakker74111d32011-01-15 16:57:55 +0000949
Paul Bakker5121ce52009-01-03 21:22:43 +0000950 if( ( ret = asn1_get_tag( p, end, &len,
951 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000952 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000953
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000954 end_ext_data = *p + len;
955
Paul Bakker74111d32011-01-15 16:57:55 +0000956 /* Get extension ID */
957 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000958
Paul Bakker74111d32011-01-15 16:57:55 +0000959 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000960 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000961
Paul Bakker74111d32011-01-15 16:57:55 +0000962 extn_oid.p = *p;
963 *p += extn_oid.len;
964
965 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000966 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000967 POLARSSL_ERR_ASN1_OUT_OF_DATA );
968
969 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000970 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000971 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
Paul Bakker9d781402011-05-09 16:17:09 +0000972 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000973
Paul Bakker74111d32011-01-15 16:57:55 +0000974 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000975 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000976 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000977 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000978
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000979 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000980
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000981 if( end_ext_octet != end_ext_data )
Paul Bakker9d781402011-05-09 16:17:09 +0000982 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000983 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000984
Paul Bakker74111d32011-01-15 16:57:55 +0000985 /*
986 * Detect supported extensions
987 */
Paul Bakkerc70b9822013-04-07 22:00:46 +0200988 ret = oid_get_x509_ext_type( &extn_oid, &ext_type );
989
990 if( ret != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000991 {
992 /* No parser found, skip extension */
993 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +0000994
Paul Bakker5c721f92011-07-27 16:51:09 +0000995#if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
Paul Bakker74111d32011-01-15 16:57:55 +0000996 if( is_critical )
997 {
998 /* Data is marked as critical: fail */
Paul Bakker9d781402011-05-09 16:17:09 +0000999 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +00001000 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
1001 }
Paul Bakker5c721f92011-07-27 16:51:09 +00001002#endif
Paul Bakkerc70b9822013-04-07 22:00:46 +02001003 continue;
1004 }
1005
1006 crt->ext_types |= ext_type;
1007
1008 switch( ext_type )
1009 {
1010 case EXT_BASIC_CONSTRAINTS:
1011 /* Parse basic constraints */
1012 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
1013 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
1014 return ( ret );
1015 break;
1016
1017 case EXT_KEY_USAGE:
1018 /* Parse key usage */
1019 if( ( ret = x509_get_key_usage( p, end_ext_octet,
1020 &crt->key_usage ) ) != 0 )
1021 return ( ret );
1022 break;
1023
1024 case EXT_EXTENDED_KEY_USAGE:
1025 /* Parse extended key usage */
1026 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
1027 &crt->ext_key_usage ) ) != 0 )
1028 return ( ret );
1029 break;
1030
1031 case EXT_SUBJECT_ALT_NAME:
1032 /* Parse subject alt name */
1033 if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
1034 &crt->subject_alt_names ) ) != 0 )
1035 return ( ret );
1036 break;
1037
1038 case EXT_NS_CERT_TYPE:
1039 /* Parse netscape certificate type */
1040 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
1041 &crt->ns_cert_type ) ) != 0 )
1042 return ( ret );
1043 break;
1044
1045 default:
1046 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker74111d32011-01-15 16:57:55 +00001047 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001048 }
1049
1050 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +00001051 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +00001052 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001053
Paul Bakker5121ce52009-01-03 21:22:43 +00001054 return( 0 );
1055}
1056
1057/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001058 * X.509 CRL Entries
1059 */
1060static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001061 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001062 x509_crl_entry *entry )
1063{
Paul Bakker23986e52011-04-24 08:57:21 +00001064 int ret;
1065 size_t entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001066 x509_crl_entry *cur_entry = entry;
1067
1068 if( *p == end )
1069 return( 0 );
1070
Paul Bakker9be19372009-07-27 20:21:53 +00001071 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001072 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1073 {
1074 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
1075 return( 0 );
1076
1077 return( ret );
1078 }
1079
Paul Bakker9be19372009-07-27 20:21:53 +00001080 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001081
1082 while( *p < end )
1083 {
Paul Bakker23986e52011-04-24 08:57:21 +00001084 size_t len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001085 const unsigned char *end2;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001086
1087 if( ( ret = asn1_get_tag( p, end, &len2,
1088 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1089 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001090 return( ret );
1091 }
1092
Paul Bakker9be19372009-07-27 20:21:53 +00001093 cur_entry->raw.tag = **p;
1094 cur_entry->raw.p = *p;
1095 cur_entry->raw.len = len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001096 end2 = *p + len2;
Paul Bakker9be19372009-07-27 20:21:53 +00001097
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001098 if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001099 return( ret );
1100
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001101 if( ( ret = x509_get_time( p, end2, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001102 return( ret );
1103
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001104 if( ( ret = x509_get_crl_entry_ext( p, end2, &cur_entry->entry_ext ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001105 return( ret );
1106
Paul Bakker74111d32011-01-15 16:57:55 +00001107 if ( *p < end )
1108 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001109 cur_entry->next = polarssl_malloc( sizeof( x509_crl_entry ) );
Paul Bakkerb15b8512012-01-13 13:44:06 +00001110
1111 if( cur_entry->next == NULL )
1112 return( POLARSSL_ERR_X509_MALLOC_FAILED );
1113
Paul Bakkerd98030e2009-05-02 15:13:40 +00001114 cur_entry = cur_entry->next;
1115 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
1116 }
1117 }
1118
1119 return( 0 );
1120}
1121
Paul Bakkerc70b9822013-04-07 22:00:46 +02001122static int x509_get_sig_alg( const x509_buf *sig_oid, md_type_t *md_alg,
1123 pk_type_t *pk_alg )
Paul Bakker27d66162010-03-17 06:56:01 +00001124{
Paul Bakkerc70b9822013-04-07 22:00:46 +02001125 int ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg );
Paul Bakker27d66162010-03-17 06:56:01 +00001126
Paul Bakkerc70b9822013-04-07 22:00:46 +02001127 if( ret != 0 )
1128 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG + ret );
Paul Bakker27d66162010-03-17 06:56:01 +00001129
Paul Bakkerc70b9822013-04-07 22:00:46 +02001130 return( 0 );
Paul Bakker27d66162010-03-17 06:56:01 +00001131}
1132
Paul Bakkerd98030e2009-05-02 15:13:40 +00001133/*
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001134 * Parse and fill a single X.509 certificate in DER format
Paul Bakker5121ce52009-01-03 21:22:43 +00001135 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02001136static int x509parse_crt_der_core( x509_cert *crt, const unsigned char *buf,
1137 size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001138{
Paul Bakker23986e52011-04-24 08:57:21 +00001139 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001140 size_t len;
Paul Bakkerb00ca422012-09-25 12:10:00 +00001141 unsigned char *p, *end, *crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001142
Paul Bakker320a4b52009-03-28 18:52:39 +00001143 /*
1144 * Check for valid input
1145 */
1146 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001147 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker320a4b52009-03-28 18:52:39 +00001148
Paul Bakker6e339b52013-07-03 13:37:05 +02001149 p = (unsigned char *) polarssl_malloc( len = buflen );
Paul Bakker96743fc2011-02-12 14:30:57 +00001150
1151 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001152 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001153
1154 memcpy( p, buf, buflen );
1155
1156 buflen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001157
1158 crt->raw.p = p;
1159 crt->raw.len = len;
1160 end = p + len;
1161
1162 /*
1163 * Certificate ::= SEQUENCE {
1164 * tbsCertificate TBSCertificate,
1165 * signatureAlgorithm AlgorithmIdentifier,
1166 * signatureValue BIT STRING }
1167 */
1168 if( ( ret = asn1_get_tag( &p, end, &len,
1169 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1170 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001171 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001172 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001173 }
1174
Paul Bakkerb00ca422012-09-25 12:10:00 +00001175 if( len > (size_t) ( end - p ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001176 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001177 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001178 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001179 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001180 }
Paul Bakkerb00ca422012-09-25 12:10:00 +00001181 crt_end = p + len;
Paul Bakker42c65812013-06-24 19:21:59 +02001182
Paul Bakker5121ce52009-01-03 21:22:43 +00001183 /*
1184 * TBSCertificate ::= SEQUENCE {
1185 */
1186 crt->tbs.p = p;
1187
1188 if( ( ret = asn1_get_tag( &p, end, &len,
1189 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1190 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001191 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001192 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001193 }
1194
1195 end = p + len;
1196 crt->tbs.len = end - crt->tbs.p;
1197
1198 /*
1199 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1200 *
1201 * CertificateSerialNumber ::= INTEGER
1202 *
1203 * signature AlgorithmIdentifier
1204 */
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +02001205 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1206 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1207 ( ret = x509_get_alg( &p, end, &crt->sig_oid1, NULL ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001208 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001209 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001210 return( ret );
1211 }
1212
1213 crt->version++;
1214
1215 if( crt->version > 3 )
1216 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001217 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001218 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001219 }
1220
Paul Bakkerc70b9822013-04-07 22:00:46 +02001221 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_md,
1222 &crt->sig_pk ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001223 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001224 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001225 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001226 }
1227
1228 /*
1229 * issuer Name
1230 */
1231 crt->issuer_raw.p = p;
1232
1233 if( ( ret = asn1_get_tag( &p, end, &len,
1234 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1235 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001236 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001237 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001238 }
1239
1240 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1241 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001242 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001243 return( ret );
1244 }
1245
1246 crt->issuer_raw.len = p - crt->issuer_raw.p;
1247
1248 /*
1249 * Validity ::= SEQUENCE {
1250 * notBefore Time,
1251 * notAfter Time }
1252 *
1253 */
1254 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1255 &crt->valid_to ) ) != 0 )
1256 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001257 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001258 return( ret );
1259 }
1260
1261 /*
1262 * subject Name
1263 */
1264 crt->subject_raw.p = p;
1265
1266 if( ( ret = asn1_get_tag( &p, end, &len,
1267 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1268 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001269 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001270 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001271 }
1272
Paul Bakkercefb3962012-06-27 11:51:09 +00001273 if( len && ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001274 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001275 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001276 return( ret );
1277 }
1278
1279 crt->subject_raw.len = p - crt->subject_raw.p;
1280
1281 /*
1282 * SubjectPublicKeyInfo ::= SEQUENCE
1283 * algorithm AlgorithmIdentifier,
1284 * subjectPublicKey BIT STRING }
1285 */
1286 if( ( ret = asn1_get_tag( &p, end, &len,
1287 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1288 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001289 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001290 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001291 }
1292
1293 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1294 &crt->rsa.N, &crt->rsa.E ) ) != 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 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1301 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001302 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001303 return( ret );
1304 }
1305
1306 crt->rsa.len = mpi_size( &crt->rsa.N );
1307
1308 /*
1309 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1310 * -- If present, version shall be v2 or v3
1311 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1312 * -- If present, version shall be v2 or v3
1313 * extensions [3] EXPLICIT Extensions OPTIONAL
1314 * -- If present, version shall be v3
1315 */
1316 if( crt->version == 2 || crt->version == 3 )
1317 {
1318 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1319 if( ret != 0 )
1320 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001321 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001322 return( ret );
1323 }
1324 }
1325
1326 if( crt->version == 2 || crt->version == 3 )
1327 {
1328 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1329 if( ret != 0 )
1330 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001331 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001332 return( ret );
1333 }
1334 }
1335
1336 if( crt->version == 3 )
1337 {
Paul Bakker74111d32011-01-15 16:57:55 +00001338 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001339 if( ret != 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
1346 if( p != end )
1347 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001348 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001349 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001350 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001351 }
1352
Paul Bakkerb00ca422012-09-25 12:10:00 +00001353 end = crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001354
1355 /*
1356 * signatureAlgorithm AlgorithmIdentifier,
1357 * signatureValue BIT STRING
1358 */
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +02001359 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2, NULL ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001360 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001361 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001362 return( ret );
1363 }
1364
Paul Bakker535e97d2012-08-23 10:49:55 +00001365 if( crt->sig_oid1.len != crt->sig_oid2.len ||
1366 memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001367 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001368 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001369 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001370 }
1371
1372 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1373 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001374 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001375 return( ret );
1376 }
1377
1378 if( p != end )
1379 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001380 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001381 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001382 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001383 }
1384
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001385 return( 0 );
1386}
1387
1388/*
Paul Bakker42c65812013-06-24 19:21:59 +02001389 * Parse one X.509 certificate in DER format from a buffer and add them to a
1390 * chained list
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001391 */
Paul Bakker42c65812013-06-24 19:21:59 +02001392int x509parse_crt_der( x509_cert *chain, const unsigned char *buf, size_t buflen )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001393{
Paul Bakker42c65812013-06-24 19:21:59 +02001394 int ret;
1395 x509_cert *crt = chain, *prev = NULL;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001396
1397 /*
1398 * Check for valid input
1399 */
1400 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001401 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001402
1403 while( crt->version != 0 && crt->next != NULL )
1404 {
1405 prev = crt;
1406 crt = crt->next;
1407 }
1408
1409 /*
1410 * Add new certificate on the end of the chain if needed.
1411 */
1412 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001413 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001414 crt->next = (x509_cert *) polarssl_malloc( sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001415
Paul Bakker7d06ad22009-05-02 15:53:56 +00001416 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001417 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker320a4b52009-03-28 18:52:39 +00001418
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001419 prev = crt;
Paul Bakker7d06ad22009-05-02 15:53:56 +00001420 crt = crt->next;
1421 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001422 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001423
Paul Bakker42c65812013-06-24 19:21:59 +02001424 if( ( ret = x509parse_crt_der_core( crt, buf, buflen ) ) != 0 )
1425 {
1426 if( prev )
1427 prev->next = NULL;
1428
1429 if( crt != chain )
Paul Bakker6e339b52013-07-03 13:37:05 +02001430 polarssl_free( crt );
Paul Bakker42c65812013-06-24 19:21:59 +02001431
1432 return( ret );
1433 }
1434
1435 return( 0 );
1436}
1437
1438/*
1439 * Parse one or more PEM certificates from a buffer and add them to the chained list
1440 */
1441int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
1442{
1443 int ret, success = 0, first_error = 0, total_failed = 0;
1444 int buf_format = X509_FORMAT_DER;
1445
1446 /*
1447 * Check for valid input
1448 */
1449 if( chain == NULL || buf == NULL )
1450 return( POLARSSL_ERR_X509_INVALID_INPUT );
1451
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001452 /*
1453 * Determine buffer content. Buffer contains either one DER certificate or
1454 * one or more PEM certificates.
1455 */
1456#if defined(POLARSSL_PEM_C)
Paul Bakker3c2122f2013-06-24 19:03:14 +02001457 if( strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001458 buf_format = X509_FORMAT_PEM;
1459#endif
1460
1461 if( buf_format == X509_FORMAT_DER )
Paul Bakker42c65812013-06-24 19:21:59 +02001462 return x509parse_crt_der( chain, buf, buflen );
1463
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001464#if defined(POLARSSL_PEM_C)
1465 if( buf_format == X509_FORMAT_PEM )
1466 {
1467 pem_context pem;
1468
1469 while( buflen > 0 )
1470 {
1471 size_t use_len;
1472 pem_init( &pem );
1473
1474 ret = pem_read_buffer( &pem,
1475 "-----BEGIN CERTIFICATE-----",
1476 "-----END CERTIFICATE-----",
1477 buf, NULL, 0, &use_len );
1478
1479 if( ret == 0 )
1480 {
1481 /*
1482 * Was PEM encoded
1483 */
1484 buflen -= use_len;
1485 buf += use_len;
1486 }
Paul Bakker5ed3b342013-06-24 19:05:46 +02001487 else if( ret == POLARSSL_ERR_PEM_BAD_INPUT_DATA )
1488 {
1489 return( ret );
1490 }
Paul Bakker00b28602013-06-24 13:02:41 +02001491 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001492 {
1493 pem_free( &pem );
1494
Paul Bakker5ed3b342013-06-24 19:05:46 +02001495 /*
1496 * PEM header and footer were found
1497 */
1498 buflen -= use_len;
1499 buf += use_len;
1500
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001501 if( first_error == 0 )
1502 first_error = ret;
1503
1504 continue;
1505 }
1506 else
1507 break;
1508
Paul Bakker42c65812013-06-24 19:21:59 +02001509 ret = x509parse_crt_der( chain, pem.buf, pem.buflen );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001510
1511 pem_free( &pem );
1512
1513 if( ret != 0 )
1514 {
1515 /*
Paul Bakker42c65812013-06-24 19:21:59 +02001516 * Quit parsing on a memory error
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001517 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001518 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001519 return( ret );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001520
1521 if( first_error == 0 )
1522 first_error = ret;
1523
Paul Bakker42c65812013-06-24 19:21:59 +02001524 total_failed++;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001525 continue;
1526 }
1527
1528 success = 1;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001529 }
1530 }
1531#endif
1532
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001533 if( success )
Paul Bakker69e095c2011-12-10 21:55:01 +00001534 return( total_failed );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001535 else if( first_error )
1536 return( first_error );
1537 else
1538 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001539}
1540
1541/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001542 * Parse one or more CRLs and add them to the chained list
1543 */
Paul Bakker23986e52011-04-24 08:57:21 +00001544int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001545{
Paul Bakker23986e52011-04-24 08:57:21 +00001546 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001547 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001548 unsigned char *p, *end;
1549 x509_crl *crl;
Paul Bakker96743fc2011-02-12 14:30:57 +00001550#if defined(POLARSSL_PEM_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00001551 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001552 pem_context pem;
1553#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001554
1555 crl = chain;
1556
1557 /*
1558 * Check for valid input
1559 */
1560 if( crl == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001561 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001562
1563 while( crl->version != 0 && crl->next != NULL )
1564 crl = crl->next;
1565
1566 /*
1567 * Add new CRL on the end of the chain if needed.
1568 */
1569 if ( crl->version != 0 && crl->next == NULL)
1570 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001571 crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001572
Paul Bakker7d06ad22009-05-02 15:53:56 +00001573 if( crl->next == NULL )
1574 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001575 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001576 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001577 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001578
Paul Bakker7d06ad22009-05-02 15:53:56 +00001579 crl = crl->next;
1580 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001581 }
1582
Paul Bakker96743fc2011-02-12 14:30:57 +00001583#if defined(POLARSSL_PEM_C)
1584 pem_init( &pem );
1585 ret = pem_read_buffer( &pem,
1586 "-----BEGIN X509 CRL-----",
1587 "-----END X509 CRL-----",
1588 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001589
Paul Bakker96743fc2011-02-12 14:30:57 +00001590 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001591 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001592 /*
1593 * Was PEM encoded
1594 */
1595 buflen -= use_len;
1596 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001597
1598 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001599 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001600 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001601 p = pem.buf;
1602 pem.buf = NULL;
1603 len = pem.buflen;
1604 pem_free( &pem );
1605 }
Paul Bakker00b28602013-06-24 13:02:41 +02001606 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker96743fc2011-02-12 14:30:57 +00001607 {
1608 pem_free( &pem );
1609 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001610 }
1611 else
1612 {
1613 /*
1614 * nope, copy the raw DER data
1615 */
Paul Bakker6e339b52013-07-03 13:37:05 +02001616 p = (unsigned char *) polarssl_malloc( len = buflen );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001617
1618 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001619 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001620
1621 memcpy( p, buf, buflen );
1622
1623 buflen = 0;
1624 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001625#else
Paul Bakker6e339b52013-07-03 13:37:05 +02001626 p = (unsigned char *) polarssl_malloc( len = buflen );
Paul Bakker96743fc2011-02-12 14:30:57 +00001627
1628 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001629 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001630
1631 memcpy( p, buf, buflen );
1632
1633 buflen = 0;
1634#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001635
1636 crl->raw.p = p;
1637 crl->raw.len = len;
1638 end = p + len;
1639
1640 /*
1641 * CertificateList ::= SEQUENCE {
1642 * tbsCertList TBSCertList,
1643 * signatureAlgorithm AlgorithmIdentifier,
1644 * signatureValue BIT STRING }
1645 */
1646 if( ( ret = asn1_get_tag( &p, end, &len,
1647 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1648 {
1649 x509_crl_free( crl );
1650 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1651 }
1652
Paul Bakker23986e52011-04-24 08:57:21 +00001653 if( len != (size_t) ( end - p ) )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001654 {
1655 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001656 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001657 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1658 }
1659
1660 /*
1661 * TBSCertList ::= SEQUENCE {
1662 */
1663 crl->tbs.p = p;
1664
1665 if( ( ret = asn1_get_tag( &p, end, &len,
1666 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1667 {
1668 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001669 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001670 }
1671
1672 end = p + len;
1673 crl->tbs.len = end - crl->tbs.p;
1674
1675 /*
1676 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1677 * -- if present, MUST be v2
1678 *
1679 * signature AlgorithmIdentifier
1680 */
Paul Bakker3329d1f2011-10-12 09:55:01 +00001681 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +02001682 ( ret = x509_get_alg( &p, end, &crl->sig_oid1, NULL ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001683 {
1684 x509_crl_free( crl );
1685 return( ret );
1686 }
1687
1688 crl->version++;
1689
1690 if( crl->version > 2 )
1691 {
1692 x509_crl_free( crl );
1693 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1694 }
1695
Paul Bakkerc70b9822013-04-07 22:00:46 +02001696 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_md,
1697 &crl->sig_pk ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001698 {
1699 x509_crl_free( crl );
1700 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1701 }
1702
1703 /*
1704 * issuer Name
1705 */
1706 crl->issuer_raw.p = p;
1707
1708 if( ( ret = asn1_get_tag( &p, end, &len,
1709 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1710 {
1711 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001712 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001713 }
1714
1715 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1716 {
1717 x509_crl_free( crl );
1718 return( ret );
1719 }
1720
1721 crl->issuer_raw.len = p - crl->issuer_raw.p;
1722
1723 /*
1724 * thisUpdate Time
1725 * nextUpdate Time OPTIONAL
1726 */
Paul Bakker91200182010-02-18 21:26:15 +00001727 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001728 {
1729 x509_crl_free( crl );
1730 return( ret );
1731 }
1732
Paul Bakker91200182010-02-18 21:26:15 +00001733 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001734 {
Paul Bakker9d781402011-05-09 16:17:09 +00001735 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001736 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker9d781402011-05-09 16:17:09 +00001737 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001738 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001739 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001740 x509_crl_free( crl );
1741 return( ret );
1742 }
1743 }
1744
1745 /*
1746 * revokedCertificates SEQUENCE OF SEQUENCE {
1747 * userCertificate CertificateSerialNumber,
1748 * revocationDate Time,
1749 * crlEntryExtensions Extensions OPTIONAL
1750 * -- if present, MUST be v2
1751 * } OPTIONAL
1752 */
1753 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1754 {
1755 x509_crl_free( crl );
1756 return( ret );
1757 }
1758
1759 /*
1760 * crlExtensions EXPLICIT Extensions OPTIONAL
1761 * -- if present, MUST be v2
1762 */
1763 if( crl->version == 2 )
1764 {
1765 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1766
1767 if( ret != 0 )
1768 {
1769 x509_crl_free( crl );
1770 return( ret );
1771 }
1772 }
1773
1774 if( p != end )
1775 {
1776 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001777 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001778 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1779 }
1780
1781 end = crl->raw.p + crl->raw.len;
1782
1783 /*
1784 * signatureAlgorithm AlgorithmIdentifier,
1785 * signatureValue BIT STRING
1786 */
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +02001787 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2, NULL ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001788 {
1789 x509_crl_free( crl );
1790 return( ret );
1791 }
1792
Paul Bakker535e97d2012-08-23 10:49:55 +00001793 if( crl->sig_oid1.len != crl->sig_oid2.len ||
1794 memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001795 {
1796 x509_crl_free( crl );
1797 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1798 }
1799
1800 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1801 {
1802 x509_crl_free( crl );
1803 return( ret );
1804 }
1805
1806 if( p != end )
1807 {
1808 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001809 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001810 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1811 }
1812
1813 if( buflen > 0 )
1814 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001815 crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001816
Paul Bakker7d06ad22009-05-02 15:53:56 +00001817 if( crl->next == NULL )
1818 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001819 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001820 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001821 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001822
Paul Bakker7d06ad22009-05-02 15:53:56 +00001823 crl = crl->next;
1824 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001825
1826 return( x509parse_crl( crl, buf, buflen ) );
1827 }
1828
1829 return( 0 );
1830}
1831
Paul Bakker335db3f2011-04-25 15:28:35 +00001832#if defined(POLARSSL_FS_IO)
Paul Bakkerd98030e2009-05-02 15:13:40 +00001833/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001834 * Load all data from a file into a given buffer.
1835 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02001836static int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001837{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001838 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001839
Paul Bakkerd98030e2009-05-02 15:13:40 +00001840 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001841 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001842
Paul Bakkerd98030e2009-05-02 15:13:40 +00001843 fseek( f, 0, SEEK_END );
1844 *n = (size_t) ftell( f );
1845 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001846
Paul Bakker6e339b52013-07-03 13:37:05 +02001847 if( ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
Paul Bakkerf6a19bd2013-05-14 13:26:51 +02001848 {
1849 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +00001850 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerf6a19bd2013-05-14 13:26:51 +02001851 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001852
Paul Bakkerd98030e2009-05-02 15:13:40 +00001853 if( fread( *buf, 1, *n, f ) != *n )
1854 {
1855 fclose( f );
Paul Bakker6e339b52013-07-03 13:37:05 +02001856 polarssl_free( *buf );
Paul Bakker69e095c2011-12-10 21:55:01 +00001857 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001858 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001859
Paul Bakkerd98030e2009-05-02 15:13:40 +00001860 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001861
Paul Bakkerd98030e2009-05-02 15:13:40 +00001862 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001863
Paul Bakkerd98030e2009-05-02 15:13:40 +00001864 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001865}
1866
1867/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001868 * Load one or more certificates and add them to the chained list
1869 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001870int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001871{
1872 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001873 size_t n;
1874 unsigned char *buf;
1875
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02001876 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00001877 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001878
Paul Bakker69e095c2011-12-10 21:55:01 +00001879 ret = x509parse_crt( chain, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001880
1881 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02001882 polarssl_free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001883
1884 return( ret );
1885}
1886
Paul Bakker8d914582012-06-04 12:46:42 +00001887int x509parse_crtpath( x509_cert *chain, const char *path )
1888{
1889 int ret = 0;
1890#if defined(_WIN32)
Paul Bakker3338b792012-10-01 21:13:10 +00001891 int w_ret;
1892 WCHAR szDir[MAX_PATH];
1893 char filename[MAX_PATH];
1894 char *p;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001895 int len = strlen( path );
Paul Bakker3338b792012-10-01 21:13:10 +00001896
Paul Bakker97872ac2012-11-02 12:53:26 +00001897 WIN32_FIND_DATAW file_data;
Paul Bakker8d914582012-06-04 12:46:42 +00001898 HANDLE hFind;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001899
1900 if( len > MAX_PATH - 3 )
1901 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker8d914582012-06-04 12:46:42 +00001902
Paul Bakker3338b792012-10-01 21:13:10 +00001903 memset( szDir, 0, sizeof(szDir) );
1904 memset( filename, 0, MAX_PATH );
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001905 memcpy( filename, path, len );
1906 filename[len++] = '\\';
1907 p = filename + len;
1908 filename[len++] = '*';
Paul Bakker3338b792012-10-01 21:13:10 +00001909
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001910 w_ret = MultiByteToWideChar( CP_ACP, 0, path, len, szDir, MAX_PATH - 3 );
Paul Bakker8d914582012-06-04 12:46:42 +00001911
Paul Bakker97872ac2012-11-02 12:53:26 +00001912 hFind = FindFirstFileW( szDir, &file_data );
Paul Bakker8d914582012-06-04 12:46:42 +00001913 if (hFind == INVALID_HANDLE_VALUE)
1914 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1915
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001916 len = MAX_PATH - len;
Paul Bakker8d914582012-06-04 12:46:42 +00001917 do
1918 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001919 memset( p, 0, len );
Paul Bakker3338b792012-10-01 21:13:10 +00001920
Paul Bakkere4791f32012-06-04 21:29:15 +00001921 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
Paul Bakker8d914582012-06-04 12:46:42 +00001922 continue;
1923
Paul Bakker3338b792012-10-01 21:13:10 +00001924 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
1925 lstrlenW(file_data.cFileName),
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001926 p, len - 1,
1927 NULL, NULL );
Paul Bakker8d914582012-06-04 12:46:42 +00001928
Paul Bakker3338b792012-10-01 21:13:10 +00001929 w_ret = x509parse_crtfile( chain, filename );
1930 if( w_ret < 0 )
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001931 ret++;
1932 else
1933 ret += w_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001934 }
Paul Bakker97872ac2012-11-02 12:53:26 +00001935 while( FindNextFileW( hFind, &file_data ) != 0 );
Paul Bakker8d914582012-06-04 12:46:42 +00001936
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001937 if (GetLastError() != ERROR_NO_MORE_FILES)
1938 ret = POLARSSL_ERR_X509_FILE_IO_ERROR;
Paul Bakker8d914582012-06-04 12:46:42 +00001939
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001940cleanup:
Paul Bakker8d914582012-06-04 12:46:42 +00001941 FindClose( hFind );
1942#else
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001943 int t_ret, i;
1944 struct stat sb;
1945 struct dirent entry, *result = NULL;
Paul Bakker8d914582012-06-04 12:46:42 +00001946 char entry_name[255];
1947 DIR *dir = opendir( path );
1948
1949 if( dir == NULL)
1950 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1951
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001952 while( ( t_ret = readdir_r( dir, &entry, &result ) ) == 0 )
Paul Bakker8d914582012-06-04 12:46:42 +00001953 {
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001954 if( result == NULL )
1955 break;
1956
1957 snprintf( entry_name, sizeof(entry_name), "%s/%s", path, entry.d_name );
1958
1959 i = stat( entry_name, &sb );
1960
1961 if( i == -1 )
1962 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1963
1964 if( !S_ISREG( sb.st_mode ) )
Paul Bakker8d914582012-06-04 12:46:42 +00001965 continue;
1966
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001967 // Ignore parse errors
1968 //
Paul Bakker8d914582012-06-04 12:46:42 +00001969 t_ret = x509parse_crtfile( chain, entry_name );
1970 if( t_ret < 0 )
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001971 ret++;
1972 else
1973 ret += t_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001974 }
1975 closedir( dir );
1976#endif
1977
1978 return( ret );
1979}
1980
Paul Bakkerd98030e2009-05-02 15:13:40 +00001981/*
1982 * Load one or more CRLs and add them to the chained list
1983 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001984int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001985{
1986 int ret;
1987 size_t n;
1988 unsigned char *buf;
1989
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02001990 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00001991 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001992
Paul Bakker27fdf462011-06-09 13:55:13 +00001993 ret = x509parse_crl( chain, buf, n );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001994
1995 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02001996 polarssl_free( buf );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001997
1998 return( ret );
1999}
2000
Paul Bakker5121ce52009-01-03 21:22:43 +00002001/*
Paul Bakker335db3f2011-04-25 15:28:35 +00002002 * Load and parse a private RSA key
2003 */
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002004int x509parse_keyfile_rsa( rsa_context *rsa, const char *path, const char *pwd )
Paul Bakker335db3f2011-04-25 15:28:35 +00002005{
2006 int ret;
2007 size_t n;
2008 unsigned char *buf;
2009
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02002010 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00002011 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002012
2013 if( pwd == NULL )
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002014 ret = x509parse_key_rsa( rsa, buf, n, NULL, 0 );
Paul Bakker335db3f2011-04-25 15:28:35 +00002015 else
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002016 ret = x509parse_key_rsa( rsa, buf, n,
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02002017 (const unsigned char *) pwd, strlen( pwd ) );
Paul Bakker335db3f2011-04-25 15:28:35 +00002018
2019 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02002020 polarssl_free( buf );
Paul Bakker335db3f2011-04-25 15:28:35 +00002021
2022 return( ret );
2023}
2024
2025/*
2026 * Load and parse a public RSA key
2027 */
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002028int x509parse_public_keyfile_rsa( rsa_context *rsa, const char *path )
Paul Bakker335db3f2011-04-25 15:28:35 +00002029{
2030 int ret;
2031 size_t n;
2032 unsigned char *buf;
2033
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02002034 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00002035 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002036
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002037 ret = x509parse_public_key_rsa( rsa, buf, n );
Paul Bakker335db3f2011-04-25 15:28:35 +00002038
2039 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02002040 polarssl_free( buf );
Paul Bakker335db3f2011-04-25 15:28:35 +00002041
2042 return( ret );
2043}
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002044
2045#if defined(POLARSSL_ECP_C)
2046/*
2047 * Load and parse a private EC key
2048 */
2049int x509parse_keyfile_ec( ecp_keypair *eckey,
2050 const char *path, const char *pwd )
2051{
2052 int ret;
2053 size_t n;
2054 unsigned char *buf;
2055
2056 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2057 return( ret );
2058
2059 if( pwd == NULL )
2060 ret = x509parse_key_ec( eckey, buf, n, NULL, 0 );
2061 else
2062 ret = x509parse_key_ec( eckey, buf, n,
2063 (const unsigned char *) pwd, strlen( pwd ) );
2064
2065 memset( buf, 0, n + 1 );
2066 free( buf );
2067
2068 return( ret );
2069}
2070
2071/*
2072 * Load and parse a public EC key
2073 */
2074int x509parse_public_keyfile_ec( ecp_keypair *eckey, const char *path )
2075{
2076 int ret;
2077 size_t n;
2078 unsigned char *buf;
2079
2080 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2081 return( ret );
2082
2083 ret = x509parse_public_key_ec( eckey, buf, n );
2084
2085 memset( buf, 0, n + 1 );
2086 free( buf );
2087
2088 return( ret );
2089}
2090#endif /* defined(POLARSSL_ECP_C) */
Paul Bakker335db3f2011-04-25 15:28:35 +00002091#endif /* POLARSSL_FS_IO */
2092
2093/*
Paul Bakkere2f50402013-06-24 19:00:59 +02002094 * Parse a PKCS#1 encoded private RSA key
Paul Bakker5121ce52009-01-03 21:22:43 +00002095 */
Paul Bakkere2f50402013-06-24 19:00:59 +02002096static int x509parse_key_pkcs1_der( rsa_context *rsa,
2097 const unsigned char *key,
2098 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +00002099{
Paul Bakker23986e52011-04-24 08:57:21 +00002100 int ret;
2101 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00002102 unsigned char *p, *end;
Paul Bakkered56b222011-07-13 11:26:43 +00002103
Paul Bakker96743fc2011-02-12 14:30:57 +00002104 p = (unsigned char *) key;
Paul Bakker96743fc2011-02-12 14:30:57 +00002105 end = p + keylen;
2106
Paul Bakker5121ce52009-01-03 21:22:43 +00002107 /*
Paul Bakkere2f50402013-06-24 19:00:59 +02002108 * This function parses the RSAPrivateKey (PKCS#1)
Paul Bakkered56b222011-07-13 11:26:43 +00002109 *
Paul Bakker5121ce52009-01-03 21:22:43 +00002110 * RSAPrivateKey ::= SEQUENCE {
2111 * version Version,
2112 * modulus INTEGER, -- n
2113 * publicExponent INTEGER, -- e
2114 * privateExponent INTEGER, -- d
2115 * prime1 INTEGER, -- p
2116 * prime2 INTEGER, -- q
2117 * exponent1 INTEGER, -- d mod (p-1)
2118 * exponent2 INTEGER, -- d mod (q-1)
2119 * coefficient INTEGER, -- (inverse of q) mod p
2120 * otherPrimeInfos OtherPrimeInfos OPTIONAL
2121 * }
2122 */
2123 if( ( ret = asn1_get_tag( &p, end, &len,
2124 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2125 {
Paul Bakker9d781402011-05-09 16:17:09 +00002126 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002127 }
2128
2129 end = p + len;
2130
2131 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2132 {
Paul Bakker9d781402011-05-09 16:17:09 +00002133 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002134 }
2135
2136 if( rsa->ver != 0 )
2137 {
Paul Bakker9d781402011-05-09 16:17:09 +00002138 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002139 }
2140
2141 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
2142 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
2143 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
2144 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
2145 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
2146 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
2147 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
2148 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
2149 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002150 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002151 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002152 }
2153
2154 rsa->len = mpi_size( &rsa->N );
2155
2156 if( p != end )
2157 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002158 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002159 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00002160 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002161 }
2162
2163 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2164 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002165 rsa_free( rsa );
2166 return( ret );
2167 }
2168
Paul Bakkere2f50402013-06-24 19:00:59 +02002169 return( 0 );
2170}
2171
2172/*
2173 * Parse an unencrypted PKCS#8 encoded private RSA key
2174 */
2175static int x509parse_key_pkcs8_unencrypted_der(
2176 rsa_context *rsa,
2177 const unsigned char *key,
2178 size_t keylen )
2179{
2180 int ret;
2181 size_t len;
2182 unsigned char *p, *end;
2183 x509_buf pk_alg_oid;
2184 pk_type_t pk_alg = POLARSSL_PK_NONE;
2185
2186 p = (unsigned char *) key;
2187 end = p + keylen;
2188
2189 /*
2190 * This function parses the PrivatKeyInfo object (PKCS#8)
2191 *
2192 * PrivateKeyInfo ::= SEQUENCE {
2193 * version Version,
2194 * algorithm AlgorithmIdentifier,
2195 * PrivateKey BIT STRING
2196 * }
2197 *
2198 * AlgorithmIdentifier ::= SEQUENCE {
2199 * algorithm OBJECT IDENTIFIER,
2200 * parameters ANY DEFINED BY algorithm OPTIONAL
2201 * }
2202 *
2203 * The PrivateKey BIT STRING is a PKCS#1 RSAPrivateKey
2204 */
2205 if( ( ret = asn1_get_tag( &p, end, &len,
2206 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2207 {
2208 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2209 }
2210
2211 end = p + len;
2212
2213 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2214 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2215
2216 if( rsa->ver != 0 )
2217 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2218
Paul Bakkerf8d018a2013-06-29 12:16:17 +02002219 if( ( ret = asn1_get_alg_null( &p, end, &pk_alg_oid ) ) != 0 )
Paul Bakkere2f50402013-06-24 19:00:59 +02002220 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2221
2222 /*
2223 * only RSA keys handled at this time
2224 */
2225 if( oid_get_pk_alg( &pk_alg_oid, &pk_alg ) != 0 )
2226 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
2227
2228 /*
2229 * Get the OCTET STRING and parse the PKCS#1 format inside
2230 */
2231 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2232 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2233
2234 if( ( end - p ) < 1 )
2235 {
2236 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
2237 POLARSSL_ERR_ASN1_OUT_OF_DATA );
2238 }
2239
2240 end = p + len;
2241
2242 if( ( ret = x509parse_key_pkcs1_der( rsa, p, end - p ) ) != 0 )
2243 return( ret );
2244
2245 return( 0 );
2246}
2247
2248/*
Paul Bakkerbda7cb72013-06-24 19:34:25 +02002249 * Parse an encrypted PKCS#8 encoded private RSA key
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002250 */
2251static int x509parse_key_pkcs8_encrypted_der(
2252 rsa_context *rsa,
2253 const unsigned char *key,
2254 size_t keylen,
2255 const unsigned char *pwd,
2256 size_t pwdlen )
2257{
2258 int ret;
2259 size_t len;
Paul Bakkerf8d018a2013-06-29 12:16:17 +02002260 unsigned char *p, *end;
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002261 x509_buf pbe_alg_oid, pbe_params;
2262 unsigned char buf[2048];
Paul Bakker7749a222013-06-28 17:28:20 +02002263#if defined(POLARSSL_PKCS12_C)
2264 cipher_type_t cipher_alg;
2265 md_type_t md_alg;
2266#endif
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002267
2268 memset(buf, 0, 2048);
2269
2270 p = (unsigned char *) key;
2271 end = p + keylen;
2272
Paul Bakker28144de2013-06-24 19:28:55 +02002273 if( pwdlen == 0 )
2274 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
2275
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002276 /*
2277 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
2278 *
2279 * EncryptedPrivateKeyInfo ::= SEQUENCE {
2280 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
2281 * encryptedData EncryptedData
2282 * }
2283 *
2284 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
2285 *
2286 * EncryptedData ::= OCTET STRING
2287 *
2288 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
2289 */
2290 if( ( ret = asn1_get_tag( &p, end, &len,
2291 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2292 {
2293 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2294 }
2295
2296 end = p + len;
2297
Paul Bakkerf8d018a2013-06-29 12:16:17 +02002298 if( ( ret = asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002299 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002300
2301 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2302 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2303
2304 // buf has been sized to 2048 bytes
2305 if( len > 2048 )
2306 return( POLARSSL_ERR_X509_INVALID_INPUT );
2307
2308 /*
2309 * Decrypt EncryptedData with appropriate PDE
2310 */
Paul Bakker38b50d72013-06-24 19:33:27 +02002311#if defined(POLARSSL_PKCS12_C)
Paul Bakker7749a222013-06-28 17:28:20 +02002312 if( oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002313 {
Paul Bakker38b50d72013-06-24 19:33:27 +02002314 if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
Paul Bakker7749a222013-06-28 17:28:20 +02002315 cipher_alg, md_alg,
Paul Bakker38b50d72013-06-24 19:33:27 +02002316 pwd, pwdlen, p, len, buf ) ) != 0 )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002317 {
Paul Bakker38b50d72013-06-24 19:33:27 +02002318 if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH )
2319 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2320
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002321 return( ret );
2322 }
2323 }
2324 else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) )
2325 {
2326 if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params,
2327 PKCS12_PBE_DECRYPT,
2328 pwd, pwdlen,
2329 p, len, buf ) ) != 0 )
2330 {
2331 return( ret );
2332 }
Paul Bakker38b50d72013-06-24 19:33:27 +02002333
2334 // Best guess for password mismatch when using RC4. If first tag is
2335 // not ASN1_CONSTRUCTED | ASN1_SEQUENCE
2336 //
2337 if( *buf != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
2338 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002339 }
Paul Bakker38b50d72013-06-24 19:33:27 +02002340 else
2341#endif /* POLARSSL_PKCS12_C */
Paul Bakker28144de2013-06-24 19:28:55 +02002342#if defined(POLARSSL_PKCS5_C)
Paul Bakker38b50d72013-06-24 19:33:27 +02002343 if( OID_CMP( OID_PKCS5_PBES2, &pbe_alg_oid ) )
Paul Bakker28144de2013-06-24 19:28:55 +02002344 {
2345 if( ( ret = pkcs5_pbes2( &pbe_params, PKCS5_DECRYPT, pwd, pwdlen,
2346 p, len, buf ) ) != 0 )
2347 {
2348 if( ret == POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH )
2349 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2350
2351 return( ret );
2352 }
2353 }
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002354 else
Paul Bakker38b50d72013-06-24 19:33:27 +02002355#endif /* POLARSSL_PKCS5_C */
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002356 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
2357
2358 return x509parse_key_pkcs8_unencrypted_der( rsa, buf, len );
2359}
2360
2361/*
Paul Bakkere2f50402013-06-24 19:00:59 +02002362 * Parse a private RSA key
2363 */
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002364int x509parse_key_rsa( rsa_context *rsa,
2365 const unsigned char *key, size_t keylen,
2366 const unsigned char *pwd, size_t pwdlen )
Paul Bakkere2f50402013-06-24 19:00:59 +02002367{
2368 int ret;
2369
Paul Bakker96743fc2011-02-12 14:30:57 +00002370#if defined(POLARSSL_PEM_C)
Paul Bakkere2f50402013-06-24 19:00:59 +02002371 size_t len;
2372 pem_context pem;
2373
2374 pem_init( &pem );
2375 ret = pem_read_buffer( &pem,
2376 "-----BEGIN RSA PRIVATE KEY-----",
2377 "-----END RSA PRIVATE KEY-----",
2378 key, pwd, pwdlen, &len );
2379 if( ret == 0 )
2380 {
2381 if( ( ret = x509parse_key_pkcs1_der( rsa, pem.buf, pem.buflen ) ) != 0 )
2382 {
2383 rsa_free( rsa );
2384 }
2385
2386 pem_free( &pem );
2387 return( ret );
2388 }
Paul Bakkera4232a72013-06-24 19:32:25 +02002389 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
2390 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2391 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
2392 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
Paul Bakkere2f50402013-06-24 19:00:59 +02002393 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkere2f50402013-06-24 19:00:59 +02002394 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002395
2396 ret = pem_read_buffer( &pem,
2397 "-----BEGIN PRIVATE KEY-----",
2398 "-----END PRIVATE KEY-----",
2399 key, NULL, 0, &len );
2400 if( ret == 0 )
2401 {
2402 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa,
2403 pem.buf, pem.buflen ) ) != 0 )
2404 {
2405 rsa_free( rsa );
2406 }
2407
2408 pem_free( &pem );
2409 return( ret );
2410 }
2411 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkere2f50402013-06-24 19:00:59 +02002412 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002413
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002414 ret = pem_read_buffer( &pem,
2415 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
2416 "-----END ENCRYPTED PRIVATE KEY-----",
2417 key, NULL, 0, &len );
2418 if( ret == 0 )
2419 {
2420 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa,
2421 pem.buf, pem.buflen,
2422 pwd, pwdlen ) ) != 0 )
2423 {
2424 rsa_free( rsa );
2425 }
2426
2427 pem_free( &pem );
2428 return( ret );
2429 }
2430 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002431 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002432#else
2433 ((void) pwd);
2434 ((void) pwdlen);
2435#endif /* POLARSSL_PEM_C */
2436
2437 // At this point we only know it's not a PEM formatted key. Could be any
2438 // of the known DER encoded private key formats
2439 //
2440 // We try the different DER format parsers to see if one passes without
2441 // error
2442 //
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002443 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa, key, keylen,
2444 pwd, pwdlen ) ) == 0 )
Paul Bakkere2f50402013-06-24 19:00:59 +02002445 {
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002446 return( 0 );
Paul Bakkere2f50402013-06-24 19:00:59 +02002447 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002448
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002449 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002450
2451 if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH )
2452 {
2453 return( ret );
2454 }
2455
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002456 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa, key, keylen ) ) == 0 )
2457 return( 0 );
2458
2459 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002460
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002461 if( ( ret = x509parse_key_pkcs1_der( rsa, key, keylen ) ) == 0 )
2462 return( 0 );
2463
2464 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002465
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002466 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00002467}
2468
2469/*
Paul Bakker53019ae2011-03-25 13:58:48 +00002470 * Parse a public RSA key
2471 */
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002472int x509parse_public_key_rsa( rsa_context *rsa,
2473 const unsigned char *key, size_t keylen )
Paul Bakker53019ae2011-03-25 13:58:48 +00002474{
Paul Bakker23986e52011-04-24 08:57:21 +00002475 int ret;
2476 size_t len;
Paul Bakker53019ae2011-03-25 13:58:48 +00002477 unsigned char *p, *end;
2478 x509_buf alg_oid;
2479#if defined(POLARSSL_PEM_C)
2480 pem_context pem;
2481
2482 pem_init( &pem );
2483 ret = pem_read_buffer( &pem,
2484 "-----BEGIN PUBLIC KEY-----",
2485 "-----END PUBLIC KEY-----",
2486 key, NULL, 0, &len );
2487
2488 if( ret == 0 )
2489 {
2490 /*
2491 * Was PEM encoded
2492 */
2493 keylen = pem.buflen;
2494 }
Paul Bakker00b28602013-06-24 13:02:41 +02002495 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker53019ae2011-03-25 13:58:48 +00002496 {
2497 pem_free( &pem );
2498 return( ret );
2499 }
2500
2501 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2502#else
2503 p = (unsigned char *) key;
2504#endif
2505 end = p + keylen;
2506
2507 /*
2508 * PublicKeyInfo ::= SEQUENCE {
2509 * algorithm AlgorithmIdentifier,
2510 * PublicKey BIT STRING
2511 * }
2512 *
2513 * AlgorithmIdentifier ::= SEQUENCE {
2514 * algorithm OBJECT IDENTIFIER,
2515 * parameters ANY DEFINED BY algorithm OPTIONAL
2516 * }
2517 *
2518 * RSAPublicKey ::= SEQUENCE {
2519 * modulus INTEGER, -- n
2520 * publicExponent INTEGER -- e
2521 * }
2522 */
2523
2524 if( ( ret = asn1_get_tag( &p, end, &len,
2525 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2526 {
2527#if defined(POLARSSL_PEM_C)
2528 pem_free( &pem );
2529#endif
2530 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002531 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002532 }
2533
2534 if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
2535 {
2536#if defined(POLARSSL_PEM_C)
2537 pem_free( &pem );
2538#endif
2539 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002540 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002541 }
2542
2543 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
2544 {
2545#if defined(POLARSSL_PEM_C)
2546 pem_free( &pem );
2547#endif
2548 rsa_free( rsa );
2549 return( ret );
2550 }
2551
2552 rsa->len = mpi_size( &rsa->N );
2553
2554#if defined(POLARSSL_PEM_C)
2555 pem_free( &pem );
2556#endif
2557
2558 return( 0 );
2559}
2560
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002561#if defined(POLARSSL_ECP_C)
2562/*
2563 * Parse a private EC key
2564 */
2565int x509parse_key_ec( ecp_keypair *eckey,
2566 const unsigned char *key, size_t keylen,
2567 const unsigned char *pwd, size_t pwdlen )
2568{
2569 int ret;
2570
2571#if defined(POLARSSL_PEM_C)
2572 size_t len;
2573 pem_context pem;
2574
2575 pem_init( &pem );
2576 /* TODO: get list of correct PEM headers */
2577 ret = pem_read_buffer( &pem,
2578 "-----BEGIN EC PRIVATE KEY-----",
2579 "-----END EC PRIVATE KEY-----",
2580 key, pwd, pwdlen, &len );
2581 if( ret == 0 )
2582 {
2583 /* TODO: write der decoding function
2584 if( ( ret = x509parse_key_pkcs8_encrypted_der( eckey,
2585 pem.buf, pem.buflen,
2586 pwd, pwdlen ) ) != 0 )
2587 {
2588 ecp_keypair_free( eckey );
2589 }
2590 */
2591
2592 pem_free( &pem );
2593 return( ret );
2594 }
2595 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
2596 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2597 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
2598 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
2599 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2600 return( ret );
2601
2602 /* TODO: now repeat with other valid PEM headers */
2603
2604#else
2605 ((void) pwd);
2606 ((void) pwdlen);
2607#endif /* POLARSSL_PEM_C */
2608
2609 ((void) keylen);
2610 /* TODO: write der decoding functions (encrypted, unencnrypted)
2611 if( ( ret = x509parse_key_pkcs8_encrypted_der( eckey, key, keylen,
2612 pwd, pwdlen ) ) == 0 )
2613 {
2614 return( 0 );
2615 }
2616
2617 ecp_keypair_free( eckey );
2618
2619 if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH )
2620 {
2621 return( ret );
2622 }
2623
2624 if( ( ret = x509parse_key_pkcs8_unencrypted_der( eckey, key, keylen ) )
2625 == 0 )
2626 {
2627 return( 0 );
2628 }
2629 */
2630
2631 ecp_keypair_free( eckey );
2632
2633 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
2634}
2635
2636/*
2637 * Parse a public EC key
2638 */
2639int x509parse_public_key_ec( ecp_keypair *eckey,
2640 const unsigned char *key, size_t keylen )
2641{
2642 int ret;
2643 size_t len;
2644 unsigned char *p, *end;
2645 x509_buf alg_oid;
2646#if defined(POLARSSL_PEM_C)
2647 pem_context pem;
2648
2649 pem_init( &pem );
2650 ret = pem_read_buffer( &pem, /* TODO: check header */
2651 "-----BEGIN PUBLIC KEY-----",
2652 "-----END PUBLIC KEY-----",
2653 key, NULL, 0, &len );
2654
2655 if( ret == 0 )
2656 {
2657 /*
2658 * Was PEM encoded
2659 */
2660 keylen = pem.buflen;
2661 }
2662 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2663 {
2664 pem_free( &pem );
2665 return( ret );
2666 }
2667
2668 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2669#else
2670 p = (unsigned char *) key;
2671#endif
2672 end = p + keylen;
2673
2674 /* TODO: parse key */
2675 (void) alg_oid;
2676 (void) end;
2677 (void) eckey;
2678
2679 if( ( ret = ecp_check_pubkey( &eckey->grp, &eckey->Q ) ) != 0 )
2680 {
2681#if defined(POLARSSL_PEM_C)
2682 pem_free( &pem );
2683#endif
2684 ecp_keypair_free( eckey );
2685 return( ret );
2686 }
2687
2688#if defined(POLARSSL_PEM_C)
2689 pem_free( &pem );
2690#endif
2691
2692 return( 0 );
2693}
2694#endif /* defined(POLARSSL_ECP_C) */
2695
Paul Bakkereaa89f82011-04-04 21:36:15 +00002696#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00002697/*
Paul Bakker1b57b062011-01-06 15:48:19 +00002698 * Parse DHM parameters
2699 */
Paul Bakker23986e52011-04-24 08:57:21 +00002700int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
Paul Bakker1b57b062011-01-06 15:48:19 +00002701{
Paul Bakker23986e52011-04-24 08:57:21 +00002702 int ret;
2703 size_t len;
Paul Bakker1b57b062011-01-06 15:48:19 +00002704 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00002705#if defined(POLARSSL_PEM_C)
2706 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00002707
Paul Bakker96743fc2011-02-12 14:30:57 +00002708 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00002709
Paul Bakker96743fc2011-02-12 14:30:57 +00002710 ret = pem_read_buffer( &pem,
2711 "-----BEGIN DH PARAMETERS-----",
2712 "-----END DH PARAMETERS-----",
2713 dhmin, NULL, 0, &dhminlen );
2714
2715 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00002716 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002717 /*
2718 * Was PEM encoded
2719 */
2720 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00002721 }
Paul Bakker00b28602013-06-24 13:02:41 +02002722 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00002723 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002724 pem_free( &pem );
2725 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002726 }
2727
Paul Bakker96743fc2011-02-12 14:30:57 +00002728 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
2729#else
2730 p = (unsigned char *) dhmin;
2731#endif
2732 end = p + dhminlen;
2733
Paul Bakker1b57b062011-01-06 15:48:19 +00002734 memset( dhm, 0, sizeof( dhm_context ) );
2735
Paul Bakker1b57b062011-01-06 15:48:19 +00002736 /*
2737 * DHParams ::= SEQUENCE {
2738 * prime INTEGER, -- P
2739 * generator INTEGER, -- g
2740 * }
2741 */
2742 if( ( ret = asn1_get_tag( &p, end, &len,
2743 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2744 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002745#if defined(POLARSSL_PEM_C)
2746 pem_free( &pem );
2747#endif
Paul Bakker9d781402011-05-09 16:17:09 +00002748 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002749 }
2750
2751 end = p + len;
2752
2753 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
2754 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
2755 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002756#if defined(POLARSSL_PEM_C)
2757 pem_free( &pem );
2758#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002759 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002760 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002761 }
2762
2763 if( p != end )
2764 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002765#if defined(POLARSSL_PEM_C)
2766 pem_free( &pem );
2767#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002768 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002769 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker1b57b062011-01-06 15:48:19 +00002770 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
2771 }
2772
Paul Bakker96743fc2011-02-12 14:30:57 +00002773#if defined(POLARSSL_PEM_C)
2774 pem_free( &pem );
2775#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002776
2777 return( 0 );
2778}
2779
Paul Bakker335db3f2011-04-25 15:28:35 +00002780#if defined(POLARSSL_FS_IO)
Paul Bakker1b57b062011-01-06 15:48:19 +00002781/*
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02002782 * Load and parse DHM parameters
Paul Bakker1b57b062011-01-06 15:48:19 +00002783 */
2784int x509parse_dhmfile( dhm_context *dhm, const char *path )
2785{
2786 int ret;
2787 size_t n;
2788 unsigned char *buf;
2789
Paul Bakker69e095c2011-12-10 21:55:01 +00002790 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
2791 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002792
Paul Bakker27fdf462011-06-09 13:55:13 +00002793 ret = x509parse_dhm( dhm, buf, n );
Paul Bakker1b57b062011-01-06 15:48:19 +00002794
2795 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02002796 polarssl_free( buf );
Paul Bakker1b57b062011-01-06 15:48:19 +00002797
2798 return( ret );
2799}
Paul Bakker335db3f2011-04-25 15:28:35 +00002800#endif /* POLARSSL_FS_IO */
Paul Bakkereaa89f82011-04-04 21:36:15 +00002801#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00002802
Paul Bakker5121ce52009-01-03 21:22:43 +00002803#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002804#include <stdarg.h>
2805
2806#if !defined vsnprintf
2807#define vsnprintf _vsnprintf
2808#endif // vsnprintf
2809
2810/*
2811 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2812 * Result value is not size of buffer needed, but -1 if no fit is possible.
2813 *
2814 * This fuction tries to 'fix' this by at least suggesting enlarging the
2815 * size by 20.
2816 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02002817static int compat_snprintf(char *str, size_t size, const char *format, ...)
Paul Bakkerd98030e2009-05-02 15:13:40 +00002818{
2819 va_list ap;
2820 int res = -1;
2821
2822 va_start( ap, format );
2823
2824 res = vsnprintf( str, size, format, ap );
2825
2826 va_end( ap );
2827
2828 // No quick fix possible
2829 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00002830 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002831
2832 return res;
2833}
2834
2835#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002836#endif
2837
Paul Bakkerd98030e2009-05-02 15:13:40 +00002838#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2839
2840#define SAFE_SNPRINTF() \
2841{ \
2842 if( ret == -1 ) \
2843 return( -1 ); \
2844 \
Paul Bakker23986e52011-04-24 08:57:21 +00002845 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002846 p[n - 1] = '\0'; \
2847 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2848 } \
2849 \
Paul Bakker23986e52011-04-24 08:57:21 +00002850 n -= (unsigned int) ret; \
2851 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002852}
2853
Paul Bakker5121ce52009-01-03 21:22:43 +00002854/*
2855 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002856 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002857 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002858int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002859{
Paul Bakker23986e52011-04-24 08:57:21 +00002860 int ret;
2861 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002862 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002863 const x509_name *name;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002864 const char *short_name = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00002865 char s[128], *p;
2866
2867 memset( s, 0, sizeof( s ) );
2868
2869 name = dn;
2870 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002871 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002872
2873 while( name != NULL )
2874 {
Paul Bakkercefb3962012-06-27 11:51:09 +00002875 if( !name->oid.p )
2876 {
2877 name = name->next;
2878 continue;
2879 }
2880
Paul Bakker74111d32011-01-15 16:57:55 +00002881 if( name != dn )
2882 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002883 ret = snprintf( p, n, ", " );
2884 SAFE_SNPRINTF();
2885 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002886
Paul Bakkerc70b9822013-04-07 22:00:46 +02002887 ret = oid_get_attr_short_name( &name->oid, &short_name );
Paul Bakker5121ce52009-01-03 21:22:43 +00002888
Paul Bakkerc70b9822013-04-07 22:00:46 +02002889 if( ret == 0 )
2890 ret = snprintf( p, n, "%s=", short_name );
Paul Bakker5121ce52009-01-03 21:22:43 +00002891 else
Paul Bakkerd98030e2009-05-02 15:13:40 +00002892 ret = snprintf( p, n, "\?\?=" );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002893 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002894
2895 for( i = 0; i < name->val.len; i++ )
2896 {
Paul Bakker27fdf462011-06-09 13:55:13 +00002897 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002898 break;
2899
2900 c = name->val.p[i];
2901 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2902 s[i] = '?';
2903 else s[i] = c;
2904 }
2905 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002906 ret = snprintf( p, n, "%s", s );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002907 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002908 name = name->next;
2909 }
2910
Paul Bakker23986e52011-04-24 08:57:21 +00002911 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002912}
2913
2914/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002915 * Store the serial in printable form into buf; no more
2916 * than size characters will be written
2917 */
2918int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2919{
Paul Bakker23986e52011-04-24 08:57:21 +00002920 int ret;
2921 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00002922 char *p;
2923
2924 p = buf;
2925 n = size;
2926
2927 nr = ( serial->len <= 32 )
Paul Bakker03c7c252011-11-25 12:37:37 +00002928 ? serial->len : 28;
Paul Bakkerdd476992011-01-16 21:34:59 +00002929
2930 for( i = 0; i < nr; i++ )
2931 {
Paul Bakker93048802011-12-05 14:38:06 +00002932 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002933 continue;
2934
Paul Bakkerdd476992011-01-16 21:34:59 +00002935 ret = snprintf( p, n, "%02X%s",
2936 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2937 SAFE_SNPRINTF();
2938 }
2939
Paul Bakker03c7c252011-11-25 12:37:37 +00002940 if( nr != serial->len )
2941 {
2942 ret = snprintf( p, n, "...." );
2943 SAFE_SNPRINTF();
2944 }
2945
Paul Bakker23986e52011-04-24 08:57:21 +00002946 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00002947}
2948
2949/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002950 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002951 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002952int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2953 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002954{
Paul Bakker23986e52011-04-24 08:57:21 +00002955 int ret;
2956 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002957 char *p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002958 const char *desc = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00002959
2960 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002961 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002962
Paul Bakkerd98030e2009-05-02 15:13:40 +00002963 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002964 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002965 SAFE_SNPRINTF();
2966 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002967 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002968 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002969
Paul Bakkerdd476992011-01-16 21:34:59 +00002970 ret = x509parse_serial_gets( p, n, &crt->serial);
2971 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002972
Paul Bakkerd98030e2009-05-02 15:13:40 +00002973 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2974 SAFE_SNPRINTF();
2975 ret = x509parse_dn_gets( p, n, &crt->issuer );
2976 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002977
Paul Bakkerd98030e2009-05-02 15:13:40 +00002978 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2979 SAFE_SNPRINTF();
2980 ret = x509parse_dn_gets( p, n, &crt->subject );
2981 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002982
Paul Bakkerd98030e2009-05-02 15:13:40 +00002983 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002984 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2985 crt->valid_from.year, crt->valid_from.mon,
2986 crt->valid_from.day, crt->valid_from.hour,
2987 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002988 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002989
Paul Bakkerd98030e2009-05-02 15:13:40 +00002990 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002991 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2992 crt->valid_to.year, crt->valid_to.mon,
2993 crt->valid_to.day, crt->valid_to.hour,
2994 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002995 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002996
Paul Bakkerc70b9822013-04-07 22:00:46 +02002997 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002998 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002999
Paul Bakkerc70b9822013-04-07 22:00:46 +02003000 ret = oid_get_sig_alg_desc( &crt->sig_oid1, &desc );
3001 if( ret != 0 )
3002 ret = snprintf( p, n, "???" );
3003 else
3004 ret = snprintf( p, n, desc );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003005 SAFE_SNPRINTF();
3006
3007 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
Paul Bakker5c2364c2012-10-01 14:41:15 +00003008 (int) crt->rsa.N.n * (int) sizeof( t_uint ) * 8 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003009 SAFE_SNPRINTF();
3010
Paul Bakker23986e52011-04-24 08:57:21 +00003011 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003012}
3013
Paul Bakker74111d32011-01-15 16:57:55 +00003014/*
3015 * Return an informational string describing the given OID
3016 */
3017const char *x509_oid_get_description( x509_buf *oid )
3018{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003019 const char *desc = NULL;
3020 int ret;
Paul Bakker74111d32011-01-15 16:57:55 +00003021
Paul Bakkerc70b9822013-04-07 22:00:46 +02003022 ret = oid_get_extended_key_usage( oid, &desc );
Paul Bakker74111d32011-01-15 16:57:55 +00003023
Paul Bakkerc70b9822013-04-07 22:00:46 +02003024 if( ret != 0 )
3025 return( NULL );
Paul Bakker74111d32011-01-15 16:57:55 +00003026
Paul Bakkerc70b9822013-04-07 22:00:46 +02003027 return( desc );
Paul Bakker74111d32011-01-15 16:57:55 +00003028}
3029
3030/* Return the x.y.z.... style numeric string for the given OID */
3031int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
3032{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003033 return oid_get_numeric_string( buf, size, oid );
Paul Bakker74111d32011-01-15 16:57:55 +00003034}
3035
Paul Bakkerd98030e2009-05-02 15:13:40 +00003036/*
3037 * Return an informational string about the CRL.
3038 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003039int x509parse_crl_info( char *buf, size_t size, const char *prefix,
3040 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003041{
Paul Bakker23986e52011-04-24 08:57:21 +00003042 int ret;
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003043 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003044 char *p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003045 const char *desc;
Paul Bakkerff60ee62010-03-16 21:09:09 +00003046 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003047
3048 p = buf;
3049 n = size;
3050
3051 ret = snprintf( p, n, "%sCRL version : %d",
3052 prefix, crl->version );
3053 SAFE_SNPRINTF();
3054
3055 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
3056 SAFE_SNPRINTF();
3057 ret = x509parse_dn_gets( p, n, &crl->issuer );
3058 SAFE_SNPRINTF();
3059
3060 ret = snprintf( p, n, "\n%sthis update : " \
3061 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3062 crl->this_update.year, crl->this_update.mon,
3063 crl->this_update.day, crl->this_update.hour,
3064 crl->this_update.min, crl->this_update.sec );
3065 SAFE_SNPRINTF();
3066
3067 ret = snprintf( p, n, "\n%snext update : " \
3068 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3069 crl->next_update.year, crl->next_update.mon,
3070 crl->next_update.day, crl->next_update.hour,
3071 crl->next_update.min, crl->next_update.sec );
3072 SAFE_SNPRINTF();
3073
3074 entry = &crl->entry;
3075
3076 ret = snprintf( p, n, "\n%sRevoked certificates:",
3077 prefix );
3078 SAFE_SNPRINTF();
3079
Paul Bakker9be19372009-07-27 20:21:53 +00003080 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003081 {
3082 ret = snprintf( p, n, "\n%sserial number: ",
3083 prefix );
3084 SAFE_SNPRINTF();
3085
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003086 ret = x509parse_serial_gets( p, n, &entry->serial);
3087 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003088
Paul Bakkerd98030e2009-05-02 15:13:40 +00003089 ret = snprintf( p, n, " revocation date: " \
3090 "%04d-%02d-%02d %02d:%02d:%02d",
3091 entry->revocation_date.year, entry->revocation_date.mon,
3092 entry->revocation_date.day, entry->revocation_date.hour,
3093 entry->revocation_date.min, entry->revocation_date.sec );
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003094 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003095
3096 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003097 }
3098
Paul Bakkerc70b9822013-04-07 22:00:46 +02003099 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003100 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003101
Paul Bakkerc70b9822013-04-07 22:00:46 +02003102 ret = oid_get_sig_alg_desc( &crl->sig_oid1, &desc );
3103 if( ret != 0 )
3104 ret = snprintf( p, n, "???" );
3105 else
3106 ret = snprintf( p, n, desc );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003107 SAFE_SNPRINTF();
3108
Paul Bakker1e27bb22009-07-19 20:25:25 +00003109 ret = snprintf( p, n, "\n" );
3110 SAFE_SNPRINTF();
3111
Paul Bakker23986e52011-04-24 08:57:21 +00003112 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003113}
3114
3115/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00003116 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00003117 */
Paul Bakkerfa9b1002013-07-03 15:31:03 +02003118#if defined(POLARSSL_HAVE_TIME)
Paul Bakkerff60ee62010-03-16 21:09:09 +00003119int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00003120{
Paul Bakkercce9d772011-11-18 14:26:47 +00003121 int year, mon, day;
3122 int hour, min, sec;
3123
3124#if defined(_WIN32)
3125 SYSTEMTIME st;
3126
3127 GetLocalTime(&st);
3128
3129 year = st.wYear;
3130 mon = st.wMonth;
3131 day = st.wDay;
3132 hour = st.wHour;
3133 min = st.wMinute;
3134 sec = st.wSecond;
3135#else
Paul Bakker5121ce52009-01-03 21:22:43 +00003136 struct tm *lt;
3137 time_t tt;
3138
3139 tt = time( NULL );
3140 lt = localtime( &tt );
3141
Paul Bakkercce9d772011-11-18 14:26:47 +00003142 year = lt->tm_year + 1900;
3143 mon = lt->tm_mon + 1;
3144 day = lt->tm_mday;
3145 hour = lt->tm_hour;
3146 min = lt->tm_min;
3147 sec = lt->tm_sec;
3148#endif
3149
3150 if( year > to->year )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003151 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003152
Paul Bakkercce9d772011-11-18 14:26:47 +00003153 if( year == to->year &&
3154 mon > to->mon )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003155 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003156
Paul Bakkercce9d772011-11-18 14:26:47 +00003157 if( year == to->year &&
3158 mon == to->mon &&
3159 day > to->day )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003160 return( 1 );
3161
Paul Bakkercce9d772011-11-18 14:26:47 +00003162 if( year == to->year &&
3163 mon == to->mon &&
3164 day == to->day &&
3165 hour > to->hour )
Paul Bakkerb6194992011-01-16 21:40:22 +00003166 return( 1 );
3167
Paul Bakkercce9d772011-11-18 14:26:47 +00003168 if( year == to->year &&
3169 mon == to->mon &&
3170 day == to->day &&
3171 hour == to->hour &&
3172 min > to->min )
Paul Bakkerb6194992011-01-16 21:40:22 +00003173 return( 1 );
3174
Paul Bakkercce9d772011-11-18 14:26:47 +00003175 if( year == to->year &&
3176 mon == to->mon &&
3177 day == to->day &&
3178 hour == to->hour &&
3179 min == to->min &&
3180 sec > to->sec )
Paul Bakkerb6194992011-01-16 21:40:22 +00003181 return( 1 );
3182
Paul Bakker40ea7de2009-05-03 10:18:48 +00003183 return( 0 );
3184}
Paul Bakkerfa9b1002013-07-03 15:31:03 +02003185#else /* POLARSSL_HAVE_TIME */
3186int x509parse_time_expired( const x509_time *to )
3187{
3188 ((void) to);
3189 return( 0 );
3190}
3191#endif /* POLARSSL_HAVE_TIME */
Paul Bakker40ea7de2009-05-03 10:18:48 +00003192
3193/*
3194 * Return 1 if the certificate is revoked, or 0 otherwise.
3195 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003196int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003197{
Paul Bakkerff60ee62010-03-16 21:09:09 +00003198 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00003199
3200 while( cur != NULL && cur->serial.len != 0 )
3201 {
Paul Bakkera056efc2011-01-16 21:38:35 +00003202 if( crt->serial.len == cur->serial.len &&
3203 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003204 {
3205 if( x509parse_time_expired( &cur->revocation_date ) )
3206 return( 1 );
3207 }
3208
3209 cur = cur->next;
3210 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003211
3212 return( 0 );
3213}
3214
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003215/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00003216 * Check that the given certificate is valid accoring to the CRL.
3217 */
3218static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
3219 x509_crl *crl_list)
3220{
3221 int flags = 0;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003222 unsigned char hash[POLARSSL_MD_MAX_SIZE];
3223 const md_info_t *md_info;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003224
Paul Bakker915275b2012-09-28 07:10:55 +00003225 if( ca == NULL )
3226 return( flags );
3227
Paul Bakker76fd75a2011-01-16 21:12:10 +00003228 /*
3229 * TODO: What happens if no CRL is present?
3230 * Suggestion: Revocation state should be unknown if no CRL is present.
3231 * For backwards compatibility this is not yet implemented.
3232 */
3233
Paul Bakker915275b2012-09-28 07:10:55 +00003234 while( crl_list != NULL )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003235 {
Paul Bakker915275b2012-09-28 07:10:55 +00003236 if( crl_list->version == 0 ||
3237 crl_list->issuer_raw.len != ca->subject_raw.len ||
Paul Bakker76fd75a2011-01-16 21:12:10 +00003238 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
3239 crl_list->issuer_raw.len ) != 0 )
3240 {
3241 crl_list = crl_list->next;
3242 continue;
3243 }
3244
3245 /*
3246 * Check if CRL is correctly signed by the trusted CA
3247 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02003248 md_info = md_info_from_type( crl_list->sig_md );
3249 if( md_info == NULL )
3250 {
3251 /*
3252 * Cannot check 'unknown' hash
3253 */
3254 flags |= BADCRL_NOT_TRUSTED;
3255 break;
3256 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00003257
Paul Bakkerc70b9822013-04-07 22:00:46 +02003258 md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
Paul Bakker76fd75a2011-01-16 21:12:10 +00003259
Paul Bakkerc70b9822013-04-07 22:00:46 +02003260 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, crl_list->sig_md,
Paul Bakker76fd75a2011-01-16 21:12:10 +00003261 0, hash, crl_list->sig.p ) == 0 )
3262 {
3263 /*
3264 * CRL is not trusted
3265 */
3266 flags |= BADCRL_NOT_TRUSTED;
3267 break;
3268 }
3269
3270 /*
3271 * Check for validity of CRL (Do not drop out)
3272 */
3273 if( x509parse_time_expired( &crl_list->next_update ) )
3274 flags |= BADCRL_EXPIRED;
3275
3276 /*
3277 * Check if certificate is revoked
3278 */
3279 if( x509parse_revoked(crt, crl_list) )
3280 {
3281 flags |= BADCERT_REVOKED;
3282 break;
3283 }
3284
3285 crl_list = crl_list->next;
3286 }
3287 return flags;
3288}
3289
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02003290static int x509_wildcard_verify( const char *cn, x509_buf *name )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003291{
3292 size_t i;
3293 size_t cn_idx = 0;
3294
Paul Bakker57b12982012-02-11 17:38:38 +00003295 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003296 return( 0 );
3297
3298 for( i = 0; i < strlen( cn ); ++i )
3299 {
3300 if( cn[i] == '.' )
3301 {
3302 cn_idx = i;
3303 break;
3304 }
3305 }
3306
3307 if( cn_idx == 0 )
3308 return( 0 );
3309
Paul Bakker535e97d2012-08-23 10:49:55 +00003310 if( strlen( cn ) - cn_idx == name->len - 1 &&
3311 memcmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003312 {
3313 return( 1 );
3314 }
3315
3316 return( 0 );
3317}
3318
Paul Bakker915275b2012-09-28 07:10:55 +00003319static int x509parse_verify_top(
3320 x509_cert *child, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003321 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003322 int (*f_vrfy)(void *, x509_cert *, int, int *),
3323 void *p_vrfy )
3324{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003325 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003326 int ca_flags = 0, check_path_cnt = path_cnt + 1;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003327 unsigned char hash[POLARSSL_MD_MAX_SIZE];
3328 const md_info_t *md_info;
Paul Bakker915275b2012-09-28 07:10:55 +00003329
3330 if( x509parse_time_expired( &child->valid_to ) )
3331 *flags |= BADCERT_EXPIRED;
3332
3333 /*
3334 * Child is the top of the chain. Check against the trust_ca list.
3335 */
3336 *flags |= BADCERT_NOT_TRUSTED;
3337
3338 while( trust_ca != NULL )
3339 {
3340 if( trust_ca->version == 0 ||
3341 child->issuer_raw.len != trust_ca->subject_raw.len ||
3342 memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
3343 child->issuer_raw.len ) != 0 )
3344 {
3345 trust_ca = trust_ca->next;
3346 continue;
3347 }
3348
Paul Bakker9a736322012-11-14 12:39:52 +00003349 /*
3350 * Reduce path_len to check against if top of the chain is
3351 * the same as the trusted CA
3352 */
3353 if( child->subject_raw.len == trust_ca->subject_raw.len &&
3354 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3355 child->issuer_raw.len ) == 0 )
3356 {
3357 check_path_cnt--;
3358 }
3359
Paul Bakker915275b2012-09-28 07:10:55 +00003360 if( trust_ca->max_pathlen > 0 &&
Paul Bakker9a736322012-11-14 12:39:52 +00003361 trust_ca->max_pathlen < check_path_cnt )
Paul Bakker915275b2012-09-28 07:10:55 +00003362 {
3363 trust_ca = trust_ca->next;
3364 continue;
3365 }
3366
Paul Bakkerc70b9822013-04-07 22:00:46 +02003367 md_info = md_info_from_type( child->sig_md );
3368 if( md_info == NULL )
3369 {
3370 /*
3371 * Cannot check 'unknown' hash
3372 */
3373 continue;
3374 }
Paul Bakker915275b2012-09-28 07:10:55 +00003375
Paul Bakkerc70b9822013-04-07 22:00:46 +02003376 md( md_info, child->tbs.p, child->tbs.len, hash );
Paul Bakker915275b2012-09-28 07:10:55 +00003377
Paul Bakkerc70b9822013-04-07 22:00:46 +02003378 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, child->sig_md,
Paul Bakker915275b2012-09-28 07:10:55 +00003379 0, hash, child->sig.p ) != 0 )
3380 {
3381 trust_ca = trust_ca->next;
3382 continue;
3383 }
3384
3385 /*
3386 * Top of chain is signed by a trusted CA
3387 */
3388 *flags &= ~BADCERT_NOT_TRUSTED;
3389 break;
3390 }
3391
Paul Bakker9a736322012-11-14 12:39:52 +00003392 /*
Paul Bakker3497d8c2012-11-24 11:53:17 +01003393 * If top of chain is not the same as the trusted CA send a verify request
3394 * to the callback for any issues with validity and CRL presence for the
3395 * trusted CA certificate.
Paul Bakker9a736322012-11-14 12:39:52 +00003396 */
3397 if( trust_ca != NULL &&
3398 ( child->subject_raw.len != trust_ca->subject_raw.len ||
3399 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3400 child->issuer_raw.len ) != 0 ) )
Paul Bakker915275b2012-09-28 07:10:55 +00003401 {
3402 /* Check trusted CA's CRL for then chain's top crt */
3403 *flags |= x509parse_verifycrl( child, trust_ca, ca_crl );
3404
3405 if( x509parse_time_expired( &trust_ca->valid_to ) )
3406 ca_flags |= BADCERT_EXPIRED;
3407
Paul Bakker915275b2012-09-28 07:10:55 +00003408 if( NULL != f_vrfy )
3409 {
Paul Bakker9a736322012-11-14 12:39:52 +00003410 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003411 return( ret );
3412 }
3413 }
3414
3415 /* Call callback on top cert */
3416 if( NULL != f_vrfy )
3417 {
Paul Bakker9a736322012-11-14 12:39:52 +00003418 if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003419 return( ret );
3420 }
3421
Paul Bakker915275b2012-09-28 07:10:55 +00003422 *flags |= ca_flags;
3423
3424 return( 0 );
3425}
3426
3427static int x509parse_verify_child(
3428 x509_cert *child, x509_cert *parent, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003429 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003430 int (*f_vrfy)(void *, x509_cert *, int, int *),
3431 void *p_vrfy )
3432{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003433 int ret;
Paul Bakker915275b2012-09-28 07:10:55 +00003434 int parent_flags = 0;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003435 unsigned char hash[POLARSSL_MD_MAX_SIZE];
Paul Bakker915275b2012-09-28 07:10:55 +00003436 x509_cert *grandparent;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003437 const md_info_t *md_info;
Paul Bakker915275b2012-09-28 07:10:55 +00003438
3439 if( x509parse_time_expired( &child->valid_to ) )
3440 *flags |= BADCERT_EXPIRED;
3441
Paul Bakkerc70b9822013-04-07 22:00:46 +02003442 md_info = md_info_from_type( child->sig_md );
3443 if( md_info == NULL )
3444 {
3445 /*
3446 * Cannot check 'unknown' hash
3447 */
Paul Bakker915275b2012-09-28 07:10:55 +00003448 *flags |= BADCERT_NOT_TRUSTED;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003449 }
3450 else
3451 {
3452 md( md_info, child->tbs.p, child->tbs.len, hash );
3453
3454 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, child->sig_md, 0, hash,
3455 child->sig.p ) != 0 )
3456 *flags |= BADCERT_NOT_TRUSTED;
3457 }
3458
Paul Bakker915275b2012-09-28 07:10:55 +00003459 /* Check trusted CA's CRL for the given crt */
3460 *flags |= x509parse_verifycrl(child, parent, ca_crl);
3461
3462 grandparent = parent->next;
3463
3464 while( grandparent != NULL )
3465 {
3466 if( grandparent->version == 0 ||
3467 grandparent->ca_istrue == 0 ||
3468 parent->issuer_raw.len != grandparent->subject_raw.len ||
3469 memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
3470 parent->issuer_raw.len ) != 0 )
3471 {
3472 grandparent = grandparent->next;
3473 continue;
3474 }
3475 break;
3476 }
3477
Paul Bakker915275b2012-09-28 07:10:55 +00003478 if( grandparent != NULL )
3479 {
3480 /*
3481 * Part of the chain
3482 */
Paul Bakker9a736322012-11-14 12:39:52 +00003483 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 +00003484 if( ret != 0 )
3485 return( ret );
3486 }
3487 else
3488 {
Paul Bakker9a736322012-11-14 12:39:52 +00003489 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 +00003490 if( ret != 0 )
3491 return( ret );
3492 }
3493
3494 /* child is verified to be a child of the parent, call verify callback */
3495 if( NULL != f_vrfy )
Paul Bakker9a736322012-11-14 12:39:52 +00003496 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003497 return( ret );
Paul Bakker915275b2012-09-28 07:10:55 +00003498
3499 *flags |= parent_flags;
3500
3501 return( 0 );
3502}
3503
Paul Bakker76fd75a2011-01-16 21:12:10 +00003504/*
Paul Bakker5121ce52009-01-03 21:22:43 +00003505 * Verify the certificate validity
3506 */
3507int x509parse_verify( x509_cert *crt,
3508 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00003509 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003510 const char *cn, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003511 int (*f_vrfy)(void *, x509_cert *, int, int *),
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003512 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00003513{
Paul Bakker23986e52011-04-24 08:57:21 +00003514 size_t cn_len;
Paul Bakker915275b2012-09-28 07:10:55 +00003515 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003516 int pathlen = 0;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003517 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00003518 x509_name *name;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003519 x509_sequence *cur = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003520
Paul Bakker40ea7de2009-05-03 10:18:48 +00003521 *flags = 0;
3522
Paul Bakker5121ce52009-01-03 21:22:43 +00003523 if( cn != NULL )
3524 {
3525 name = &crt->subject;
3526 cn_len = strlen( cn );
3527
Paul Bakker4d2c1242012-05-10 14:12:46 +00003528 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
Paul Bakker5121ce52009-01-03 21:22:43 +00003529 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00003530 cur = &crt->subject_alt_names;
3531
3532 while( cur != NULL )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003533 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003534 if( cur->buf.len == cn_len &&
3535 memcmp( cn, cur->buf.p, cn_len ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003536 break;
3537
Paul Bakker535e97d2012-08-23 10:49:55 +00003538 if( cur->buf.len > 2 &&
3539 memcmp( cur->buf.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003540 x509_wildcard_verify( cn, &cur->buf ) )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003541 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003542
Paul Bakker4d2c1242012-05-10 14:12:46 +00003543 cur = cur->next;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003544 }
3545
3546 if( cur == NULL )
3547 *flags |= BADCERT_CN_MISMATCH;
3548 }
Paul Bakker4d2c1242012-05-10 14:12:46 +00003549 else
3550 {
3551 while( name != NULL )
3552 {
Paul Bakkerc70b9822013-04-07 22:00:46 +02003553 if( OID_CMP( OID_AT_CN, &name->oid ) )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003554 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003555 if( name->val.len == cn_len &&
3556 memcmp( name->val.p, cn, cn_len ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003557 break;
3558
Paul Bakker535e97d2012-08-23 10:49:55 +00003559 if( name->val.len > 2 &&
3560 memcmp( name->val.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003561 x509_wildcard_verify( cn, &name->val ) )
3562 break;
3563 }
3564
3565 name = name->next;
3566 }
3567
3568 if( name == NULL )
3569 *flags |= BADCERT_CN_MISMATCH;
3570 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003571 }
3572
Paul Bakker5121ce52009-01-03 21:22:43 +00003573 /*
Paul Bakker915275b2012-09-28 07:10:55 +00003574 * Iterate upwards in the given cert chain, to find our crt parent.
3575 * Ignore any upper cert with CA != TRUE.
Paul Bakker5121ce52009-01-03 21:22:43 +00003576 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003577 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003578
Paul Bakker76fd75a2011-01-16 21:12:10 +00003579 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003580 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003581 if( parent->ca_istrue == 0 ||
3582 crt->issuer_raw.len != parent->subject_raw.len ||
3583 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00003584 crt->issuer_raw.len ) != 0 )
3585 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003586 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003587 continue;
3588 }
Paul Bakker915275b2012-09-28 07:10:55 +00003589 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003590 }
3591
Paul Bakker915275b2012-09-28 07:10:55 +00003592 if( parent != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003593 {
Paul Bakker915275b2012-09-28 07:10:55 +00003594 /*
3595 * Part of the chain
3596 */
Paul Bakker9a736322012-11-14 12:39:52 +00003597 ret = x509parse_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003598 if( ret != 0 )
3599 return( ret );
3600 }
3601 else
Paul Bakker74111d32011-01-15 16:57:55 +00003602 {
Paul Bakker9a736322012-11-14 12:39:52 +00003603 ret = x509parse_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003604 if( ret != 0 )
3605 return( ret );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003606 }
Paul Bakker915275b2012-09-28 07:10:55 +00003607
3608 if( *flags != 0 )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003609 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003610
Paul Bakker5121ce52009-01-03 21:22:43 +00003611 return( 0 );
3612}
3613
3614/*
3615 * Unallocate all certificate data
3616 */
3617void x509_free( x509_cert *crt )
3618{
3619 x509_cert *cert_cur = crt;
3620 x509_cert *cert_prv;
3621 x509_name *name_cur;
3622 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00003623 x509_sequence *seq_cur;
3624 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00003625
3626 if( crt == NULL )
3627 return;
3628
3629 do
3630 {
3631 rsa_free( &cert_cur->rsa );
3632
3633 name_cur = cert_cur->issuer.next;
3634 while( name_cur != NULL )
3635 {
3636 name_prv = name_cur;
3637 name_cur = name_cur->next;
3638 memset( name_prv, 0, sizeof( x509_name ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02003639 polarssl_free( name_prv );
Paul Bakker5121ce52009-01-03 21:22:43 +00003640 }
3641
3642 name_cur = cert_cur->subject.next;
3643 while( name_cur != NULL )
3644 {
3645 name_prv = name_cur;
3646 name_cur = name_cur->next;
3647 memset( name_prv, 0, sizeof( x509_name ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02003648 polarssl_free( name_prv );
Paul Bakker5121ce52009-01-03 21:22:43 +00003649 }
3650
Paul Bakker74111d32011-01-15 16:57:55 +00003651 seq_cur = cert_cur->ext_key_usage.next;
3652 while( seq_cur != NULL )
3653 {
3654 seq_prv = seq_cur;
3655 seq_cur = seq_cur->next;
3656 memset( seq_prv, 0, sizeof( x509_sequence ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02003657 polarssl_free( seq_prv );
Paul Bakker74111d32011-01-15 16:57:55 +00003658 }
3659
Paul Bakker8afa70d2012-02-11 18:42:45 +00003660 seq_cur = cert_cur->subject_alt_names.next;
3661 while( seq_cur != NULL )
3662 {
3663 seq_prv = seq_cur;
3664 seq_cur = seq_cur->next;
3665 memset( seq_prv, 0, sizeof( x509_sequence ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02003666 polarssl_free( seq_prv );
Paul Bakker8afa70d2012-02-11 18:42:45 +00003667 }
3668
Paul Bakker5121ce52009-01-03 21:22:43 +00003669 if( cert_cur->raw.p != NULL )
3670 {
3671 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
Paul Bakker6e339b52013-07-03 13:37:05 +02003672 polarssl_free( cert_cur->raw.p );
Paul Bakker5121ce52009-01-03 21:22:43 +00003673 }
3674
3675 cert_cur = cert_cur->next;
3676 }
3677 while( cert_cur != NULL );
3678
3679 cert_cur = crt;
3680 do
3681 {
3682 cert_prv = cert_cur;
3683 cert_cur = cert_cur->next;
3684
3685 memset( cert_prv, 0, sizeof( x509_cert ) );
3686 if( cert_prv != crt )
Paul Bakker6e339b52013-07-03 13:37:05 +02003687 polarssl_free( cert_prv );
Paul Bakker5121ce52009-01-03 21:22:43 +00003688 }
3689 while( cert_cur != NULL );
3690}
3691
Paul Bakkerd98030e2009-05-02 15:13:40 +00003692/*
3693 * Unallocate all CRL data
3694 */
3695void x509_crl_free( x509_crl *crl )
3696{
3697 x509_crl *crl_cur = crl;
3698 x509_crl *crl_prv;
3699 x509_name *name_cur;
3700 x509_name *name_prv;
3701 x509_crl_entry *entry_cur;
3702 x509_crl_entry *entry_prv;
3703
3704 if( crl == NULL )
3705 return;
3706
3707 do
3708 {
3709 name_cur = crl_cur->issuer.next;
3710 while( name_cur != NULL )
3711 {
3712 name_prv = name_cur;
3713 name_cur = name_cur->next;
3714 memset( name_prv, 0, sizeof( x509_name ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02003715 polarssl_free( name_prv );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003716 }
3717
3718 entry_cur = crl_cur->entry.next;
3719 while( entry_cur != NULL )
3720 {
3721 entry_prv = entry_cur;
3722 entry_cur = entry_cur->next;
3723 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02003724 polarssl_free( entry_prv );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003725 }
3726
3727 if( crl_cur->raw.p != NULL )
3728 {
3729 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
Paul Bakker6e339b52013-07-03 13:37:05 +02003730 polarssl_free( crl_cur->raw.p );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003731 }
3732
3733 crl_cur = crl_cur->next;
3734 }
3735 while( crl_cur != NULL );
3736
3737 crl_cur = crl;
3738 do
3739 {
3740 crl_prv = crl_cur;
3741 crl_cur = crl_cur->next;
3742
3743 memset( crl_prv, 0, sizeof( x509_crl ) );
3744 if( crl_prv != crl )
Paul Bakker6e339b52013-07-03 13:37:05 +02003745 polarssl_free( crl_prv );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003746 }
3747 while( crl_cur != NULL );
3748}
3749
Paul Bakker40e46942009-01-03 21:51:57 +00003750#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00003751
Paul Bakker40e46942009-01-03 21:51:57 +00003752#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00003753
3754/*
3755 * Checkup routine
3756 */
3757int x509_self_test( int verbose )
3758{
Paul Bakker5690efc2011-05-26 13:16:06 +00003759#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00003760 int ret;
3761 int flags;
3762 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00003763 x509_cert cacert;
3764 x509_cert clicert;
3765 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00003766#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003767 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00003768#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003769
3770 if( verbose != 0 )
3771 printf( " X.509 certificate load: " );
3772
3773 memset( &clicert, 0, sizeof( x509_cert ) );
3774
Paul Bakker3c2122f2013-06-24 19:03:14 +02003775 ret = x509parse_crt( &clicert, (const unsigned char *) test_cli_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003776 strlen( test_cli_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003777 if( ret != 0 )
3778 {
3779 if( verbose != 0 )
3780 printf( "failed\n" );
3781
3782 return( ret );
3783 }
3784
3785 memset( &cacert, 0, sizeof( x509_cert ) );
3786
Paul Bakker3c2122f2013-06-24 19:03:14 +02003787 ret = x509parse_crt( &cacert, (const unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003788 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003789 if( ret != 0 )
3790 {
3791 if( verbose != 0 )
3792 printf( "failed\n" );
3793
3794 return( ret );
3795 }
3796
3797 if( verbose != 0 )
3798 printf( "passed\n X.509 private key load: " );
3799
3800 i = strlen( test_ca_key );
3801 j = strlen( test_ca_pwd );
3802
Paul Bakker66b78b22011-03-25 14:22:50 +00003803 rsa_init( &rsa, RSA_PKCS_V15, 0 );
3804
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02003805 if( ( ret = x509parse_key_rsa( &rsa,
Paul Bakker3c2122f2013-06-24 19:03:14 +02003806 (const unsigned char *) test_ca_key, i,
3807 (const unsigned char *) test_ca_pwd, j ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003808 {
3809 if( verbose != 0 )
3810 printf( "failed\n" );
3811
3812 return( ret );
3813 }
3814
3815 if( verbose != 0 )
3816 printf( "passed\n X.509 signature verify: ");
3817
Paul Bakker23986e52011-04-24 08:57:21 +00003818 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003819 if( ret != 0 )
3820 {
Paul Bakker23986e52011-04-24 08:57:21 +00003821 printf("%02x", flags);
Paul Bakker5121ce52009-01-03 21:22:43 +00003822 if( verbose != 0 )
3823 printf( "failed\n" );
3824
3825 return( ret );
3826 }
3827
Paul Bakker5690efc2011-05-26 13:16:06 +00003828#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003829 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003830 printf( "passed\n X.509 DHM parameter load: " );
3831
3832 i = strlen( test_dhm_params );
3833 j = strlen( test_ca_pwd );
3834
Paul Bakker3c2122f2013-06-24 19:03:14 +02003835 if( ( ret = x509parse_dhm( &dhm, (const unsigned char *) test_dhm_params, i ) ) != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003836 {
3837 if( verbose != 0 )
3838 printf( "failed\n" );
3839
3840 return( ret );
3841 }
3842
3843 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003844 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00003845#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003846
3847 x509_free( &cacert );
3848 x509_free( &clicert );
3849 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00003850#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003851 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00003852#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003853
3854 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003855#else
3856 ((void) verbose);
3857 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3858#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003859}
3860
3861#endif
3862
3863#endif