blob: ab33c318bccaba37ce4df7a6a782ca817a7dcdb0 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * X.509 certificate and private key decoding
3 *
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02004 * Copyright (C) 2006-2013, Brainspark B.V.
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
Paul Bakker84f12b72010-07-18 10:13:04 +00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakkerb96f1542010-07-18 20:36:00 +00008 *
Paul Bakker77b385e2009-07-28 17:23:11 +00009 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +000010 *
Paul Bakker5121ce52009-01-03 21:22:43 +000011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25/*
Paul Bakkerad8d3542012-02-16 15:28:14 +000026 * The ITU-T X.509 standard defines a certificate format for PKI.
Paul Bakker5121ce52009-01-03 21:22:43 +000027 *
Paul Bakker5121ce52009-01-03 21:22:43 +000028 * http://www.ietf.org/rfc/rfc3279.txt
Paul Bakkerad8d3542012-02-16 15:28:14 +000029 * http://www.ietf.org/rfc/rfc3280.txt
Paul Bakker5121ce52009-01-03 21:22:43 +000030 *
31 * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
32 *
33 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
34 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
35 */
36
Paul Bakker40e46942009-01-03 21:51:57 +000037#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000038
Paul Bakker40e46942009-01-03 21:51:57 +000039#if defined(POLARSSL_X509_PARSE_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000040
Paul Bakker40e46942009-01-03 21:51:57 +000041#include "polarssl/x509.h"
Paul Bakkerefc30292011-11-10 14:43:23 +000042#include "polarssl/asn1.h"
Paul Bakkerc70b9822013-04-07 22:00:46 +020043#include "polarssl/oid.h"
Paul Bakker96743fc2011-02-12 14:30:57 +000044#include "polarssl/pem.h"
Paul Bakker1b57b062011-01-06 15:48:19 +000045#include "polarssl/dhm.h"
Paul Bakker28144de2013-06-24 19:28:55 +020046#if defined(POLARSSL_PKCS5_C)
47#include "polarssl/pkcs5.h"
48#endif
Paul Bakker38b50d72013-06-24 19:33:27 +020049#if defined(POLARSSL_PKCS12_C)
50#include "polarssl/pkcs12.h"
51#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000052
Paul Bakker6e339b52013-07-03 13:37:05 +020053#if defined(POLARSSL_MEMORY_C)
54#include "polarssl/memory.h"
55#else
56#define polarssl_malloc malloc
57#define polarssl_free free
58#endif
59
Paul Bakker5121ce52009-01-03 21:22:43 +000060#include <string.h>
61#include <stdlib.h>
Paul Bakker4f229e52011-12-04 22:11:35 +000062#if defined(_WIN32)
Paul Bakkercce9d772011-11-18 14:26:47 +000063#include <windows.h>
64#else
Paul Bakker5121ce52009-01-03 21:22:43 +000065#include <time.h>
Paul Bakkercce9d772011-11-18 14:26:47 +000066#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000067
Paul Bakker335db3f2011-04-25 15:28:35 +000068#if defined(POLARSSL_FS_IO)
69#include <stdio.h>
Paul Bakker4a2bd0d2012-11-02 11:06:08 +000070#if !defined(_WIN32)
Paul Bakker8d914582012-06-04 12:46:42 +000071#include <sys/types.h>
Paul Bakker2c8cdd22013-06-24 19:22:42 +020072#include <sys/stat.h>
Paul Bakker8d914582012-06-04 12:46:42 +000073#include <dirent.h>
74#endif
Paul Bakker335db3f2011-04-25 15:28:35 +000075#endif
76
Paul Bakker5121ce52009-01-03 21:22:43 +000077/*
Paul Bakker5121ce52009-01-03 21:22:43 +000078 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
79 */
80static int x509_get_version( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +000081 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +000082 int *ver )
83{
Paul Bakker23986e52011-04-24 08:57:21 +000084 int ret;
85 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +000086
87 if( ( ret = asn1_get_tag( p, end, &len,
88 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
89 {
Paul Bakker40e46942009-01-03 21:51:57 +000090 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +000091 {
92 *ver = 0;
93 return( 0 );
94 }
Paul Bakker5121ce52009-01-03 21:22:43 +000095
96 return( ret );
97 }
98
99 end = *p + len;
100
101 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000102 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000103
104 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000105 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION +
Paul Bakker40e46942009-01-03 21:51:57 +0000106 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000107
108 return( 0 );
109}
110
111/*
Paul Bakkerfae618f2011-10-12 11:53:52 +0000112 * Version ::= INTEGER { v1(0), v2(1) }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000113 */
114static int x509_crl_get_version( unsigned char **p,
115 const unsigned char *end,
116 int *ver )
117{
118 int ret;
119
120 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
121 {
122 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +0000123 {
124 *ver = 0;
125 return( 0 );
126 }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000127
128 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
129 }
130
131 return( 0 );
132}
133
134/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000135 * CertificateSerialNumber ::= INTEGER
136 */
137static int x509_get_serial( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000138 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000139 x509_buf *serial )
140{
141 int ret;
142
143 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000144 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000145 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000146
147 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
148 **p != ASN1_INTEGER )
Paul Bakker9d781402011-05-09 16:17:09 +0000149 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000150 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000151
152 serial->tag = *(*p)++;
153
154 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000155 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000156
157 serial->p = *p;
158 *p += serial->len;
159
160 return( 0 );
161}
162
Manuel Pégourié-Gonnarda1555132013-07-10 13:18:41 +0200163/* Get a PK algorithm identifier
Manuel Pégourié-Gonnard0a64e8f2013-07-08 18:26:18 +0200164 *
165 * AlgorithmIdentifier ::= SEQUENCE {
166 * algorithm OBJECT IDENTIFIER,
167 * parameters ANY DEFINED BY algorithm OPTIONAL }
168 */
Manuel Pégourié-Gonnard7a287c42013-07-10 12:55:08 +0200169static int x509_get_pk_alg( unsigned char **p,
Manuel Pégourié-Gonnarda1555132013-07-10 13:18:41 +0200170 const unsigned char *end,
171 pk_type_t *pk_alg, x509_buf *params )
Manuel Pégourié-Gonnard0a64e8f2013-07-08 18:26:18 +0200172{
173 int ret;
174 x509_buf alg_oid;
175
176 memset( params, 0, sizeof(asn1_buf) );
177
178 if( ( ret = asn1_get_alg( p, end, &alg_oid, params ) ) != 0 )
179 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
180
181 if( oid_get_pk_alg( &alg_oid, pk_alg ) != 0 )
182 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
183
184 /*
185 * No parameters with RSA (only for EC)
186 */
187 if( *pk_alg == POLARSSL_PK_RSA &&
188 ( ( params->tag != ASN1_NULL && params->tag != 0 ) ||
189 params->len != 0 ) )
190 {
191 return( POLARSSL_ERR_X509_CERT_INVALID_ALG );
192 }
193
194 return( 0 );
195}
196
Manuel Pégourié-Gonnarda1555132013-07-10 13:18:41 +0200197/* Get an algorithm identifier without parameters (eg for signatures)
198 *
Paul Bakker5121ce52009-01-03 21:22:43 +0000199 * AlgorithmIdentifier ::= SEQUENCE {
200 * algorithm OBJECT IDENTIFIER,
201 * parameters ANY DEFINED BY algorithm OPTIONAL }
202 */
Manuel Pégourié-Gonnarda1555132013-07-10 13:18:41 +0200203static int x509_get_alg_null( unsigned char **p, const unsigned char *end,
204 x509_buf *alg )
Paul Bakker5121ce52009-01-03 21:22:43 +0000205{
Paul Bakker23986e52011-04-24 08:57:21 +0000206 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000207
Manuel Pégourié-Gonnarda1555132013-07-10 13:18:41 +0200208 if( ( ret = asn1_get_alg_null( p, end, alg ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000209 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000210
Paul Bakker5121ce52009-01-03 21:22:43 +0000211 return( 0 );
212}
213
Manuel Pégourié-Gonnardf838eed2013-07-02 14:56:43 +0200214/* Get an EC group id from an ECParameters buffer
215 *
216 * ECParameters ::= CHOICE {
217 * namedCurve OBJECT IDENTIFIER
218 * -- implicitCurve NULL
219 * -- specifiedCurve SpecifiedECDomain
220 * }
221 */
Manuel Pégourié-Gonnard0a64e8f2013-07-08 18:26:18 +0200222static int x509_ecparams_get_grp_id( const x509_buf *params,
223 ecp_group_id *grp_id )
224{
225 if( oid_get_ec_grp( params, grp_id ) != 0 )
226 return( POLARSSL_ERR_X509_UNKNOWN_NAMED_CURVE );
227
228 return( 0 );
229}
230
231/* Get an EC group id from an ECParameters buffer
232 *
233 * ECParameters ::= CHOICE {
234 * namedCurve OBJECT IDENTIFIER
235 * -- implicitCurve NULL
236 * -- specifiedCurve SpecifiedECDomain
237 * }
238 */
Manuel Pégourié-Gonnardf838eed2013-07-02 14:56:43 +0200239static int x509_get_ecparams( unsigned char **p, const unsigned char *end,
240 ecp_group_id *grp_id )
241{
242 int ret;
243 x509_buf curve;
244
245 curve.tag = **p;
246
247 if( ( ret = asn1_get_tag( p, end, &curve.len, ASN1_OID ) ) != 0 )
248 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
249
250 curve.p = *p;
251 *p += curve.len;
252
253 if( *p != end )
254 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
255 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
256
Manuel Pégourié-Gonnard0a64e8f2013-07-08 18:26:18 +0200257 return( x509_ecparams_get_grp_id( &curve, grp_id ) );
Manuel Pégourié-Gonnardf838eed2013-07-02 14:56:43 +0200258}
259
Paul Bakker5121ce52009-01-03 21:22:43 +0000260/*
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +0200261 * subjectPublicKey BIT STRING
262 * -- which, in our case, contains
263 * ECPoint ::= octet string (not ASN.1)
264 */
265static int x509_get_subpubkey_ec( unsigned char **p, const unsigned char *end,
266 const ecp_group *grp, ecp_point *pt )
267{
268 int ret;
269 size_t len;
270
271 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
272 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
273
274 if( *p + len != end )
275 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
276 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
277
Manuel Pégourié-Gonnard5b18fb02013-07-10 16:07:25 +0200278 if( --len < 1 || *(*p)++ != 0 )
279 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +0200280
281 if( ( ret = ecp_point_read_binary( grp, pt,
282 (const unsigned char *) *p, len ) ) != 0 )
283 {
Manuel Pégourié-Gonnard5b18fb02013-07-10 16:07:25 +0200284 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
285 }
286
287 *p += len;
288
289 if( ( ret = ecp_check_pubkey( grp, pt ) ) != 0 )
290 {
291 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Manuel Pégourié-Gonnard73c0cda2013-07-01 19:45:45 +0200292 }
293
294 return( 0 );
295}
296
297/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000298 * AttributeTypeAndValue ::= SEQUENCE {
299 * type AttributeType,
300 * value AttributeValue }
301 *
302 * AttributeType ::= OBJECT IDENTIFIER
303 *
304 * AttributeValue ::= ANY DEFINED BY AttributeType
305 */
Paul Bakker400ff6f2011-02-20 10:40:16 +0000306static int x509_get_attr_type_value( unsigned char **p,
307 const unsigned char *end,
308 x509_name *cur )
Paul Bakker5121ce52009-01-03 21:22:43 +0000309{
Paul Bakker23986e52011-04-24 08:57:21 +0000310 int ret;
311 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000312 x509_buf *oid;
313 x509_buf *val;
314
315 if( ( ret = asn1_get_tag( p, end, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000316 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000317 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000318
Paul Bakker5121ce52009-01-03 21:22:43 +0000319 oid = &cur->oid;
320 oid->tag = **p;
321
322 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000323 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000324
325 oid->p = *p;
326 *p += oid->len;
327
328 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000329 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000330 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000331
332 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
333 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
334 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker9d781402011-05-09 16:17:09 +0000335 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000336 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000337
338 val = &cur->val;
339 val->tag = *(*p)++;
340
341 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000342 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000343
344 val->p = *p;
345 *p += val->len;
346
347 cur->next = NULL;
348
Paul Bakker400ff6f2011-02-20 10:40:16 +0000349 return( 0 );
350}
351
352/*
353 * RelativeDistinguishedName ::=
354 * SET OF AttributeTypeAndValue
355 *
356 * AttributeTypeAndValue ::= SEQUENCE {
357 * type AttributeType,
358 * value AttributeValue }
359 *
360 * AttributeType ::= OBJECT IDENTIFIER
361 *
362 * AttributeValue ::= ANY DEFINED BY AttributeType
363 */
364static int x509_get_name( unsigned char **p,
365 const unsigned char *end,
366 x509_name *cur )
367{
Paul Bakker23986e52011-04-24 08:57:21 +0000368 int ret;
369 size_t len;
Paul Bakker400ff6f2011-02-20 10:40:16 +0000370 const unsigned char *end2;
371 x509_name *use;
372
373 if( ( ret = asn1_get_tag( p, end, &len,
374 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000375 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000376
377 end2 = end;
378 end = *p + len;
379 use = cur;
380
381 do
382 {
383 if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
384 return( ret );
385
386 if( *p != end )
387 {
Paul Bakker6e339b52013-07-03 13:37:05 +0200388 use->next = (x509_name *) polarssl_malloc(
Paul Bakker400ff6f2011-02-20 10:40:16 +0000389 sizeof( x509_name ) );
390
391 if( use->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000392 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000393
394 memset( use->next, 0, sizeof( x509_name ) );
395
396 use = use->next;
397 }
398 }
399 while( *p != end );
Paul Bakker5121ce52009-01-03 21:22:43 +0000400
401 /*
402 * recurse until end of SEQUENCE is reached
403 */
404 if( *p == end2 )
405 return( 0 );
406
Paul Bakker6e339b52013-07-03 13:37:05 +0200407 cur->next = (x509_name *) polarssl_malloc(
Paul Bakker5121ce52009-01-03 21:22:43 +0000408 sizeof( x509_name ) );
409
410 if( cur->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000411 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000412
Paul Bakker430ffbe2012-05-01 08:14:20 +0000413 memset( cur->next, 0, sizeof( x509_name ) );
414
Paul Bakker5121ce52009-01-03 21:22:43 +0000415 return( x509_get_name( p, end2, cur->next ) );
416}
417
418/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000419 * Time ::= CHOICE {
420 * utcTime UTCTime,
421 * generalTime GeneralizedTime }
422 */
Paul Bakker91200182010-02-18 21:26:15 +0000423static int x509_get_time( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000424 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000425 x509_time *time )
426{
Paul Bakker23986e52011-04-24 08:57:21 +0000427 int ret;
428 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000429 char date[64];
Paul Bakker91200182010-02-18 21:26:15 +0000430 unsigned char tag;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000431
Paul Bakker91200182010-02-18 21:26:15 +0000432 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000433 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
434 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000435
Paul Bakker91200182010-02-18 21:26:15 +0000436 tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000437
Paul Bakker91200182010-02-18 21:26:15 +0000438 if ( tag == ASN1_UTC_TIME )
439 {
440 (*p)++;
441 ret = asn1_get_len( p, end, &len );
442
443 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000444 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000445
Paul Bakker91200182010-02-18 21:26:15 +0000446 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000447 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
448 len : sizeof( date ) - 1 );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000449
Paul Bakker91200182010-02-18 21:26:15 +0000450 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
451 &time->year, &time->mon, &time->day,
452 &time->hour, &time->min, &time->sec ) < 5 )
453 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000454
Paul Bakker400ff6f2011-02-20 10:40:16 +0000455 time->year += 100 * ( time->year < 50 );
Paul Bakker91200182010-02-18 21:26:15 +0000456 time->year += 1900;
457
458 *p += len;
459
460 return( 0 );
461 }
462 else if ( tag == ASN1_GENERALIZED_TIME )
463 {
464 (*p)++;
465 ret = asn1_get_len( p, end, &len );
466
467 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000468 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker91200182010-02-18 21:26:15 +0000469
470 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000471 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
472 len : sizeof( date ) - 1 );
Paul Bakker91200182010-02-18 21:26:15 +0000473
474 if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
475 &time->year, &time->mon, &time->day,
476 &time->hour, &time->min, &time->sec ) < 5 )
477 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
478
479 *p += len;
480
481 return( 0 );
482 }
483 else
Paul Bakker9d781402011-05-09 16:17:09 +0000484 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000485}
486
487
488/*
489 * Validity ::= SEQUENCE {
490 * notBefore Time,
491 * notAfter Time }
492 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000493static int x509_get_dates( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000494 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000495 x509_time *from,
496 x509_time *to )
497{
Paul Bakker23986e52011-04-24 08:57:21 +0000498 int ret;
499 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000500
501 if( ( ret = asn1_get_tag( p, end, &len,
502 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000503 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000504
505 end = *p + len;
506
Paul Bakker91200182010-02-18 21:26:15 +0000507 if( ( ret = x509_get_time( p, end, from ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000508 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000509
Paul Bakker91200182010-02-18 21:26:15 +0000510 if( ( ret = x509_get_time( p, end, to ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000511 return( 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_DATE +
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
520/*
Manuel Pégourié-Gonnard094ad9e2013-07-09 12:32:51 +0200521 * RSAPublicKey ::= SEQUENCE {
522 * modulus INTEGER, -- n
523 * publicExponent INTEGER -- e
524 * }
525 */
526static int x509_get_rsapubkey( unsigned char **p,
527 const unsigned char *end,
528 rsa_context *rsa )
529{
530 int ret;
531 size_t len;
532
533 if( ( ret = asn1_get_tag( p, end, &len,
534 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
535 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
536
537 if( *p + len != end )
538 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
539 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
540
541 if( ( ret = asn1_get_mpi( p, end, &rsa->N ) ) != 0 ||
542 ( ret = asn1_get_mpi( p, end, &rsa->E ) ) != 0 )
543 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
544
545 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
546 return( ret );
547
548 rsa->len = mpi_size( &rsa->N );
549
550 return( 0 );
551}
552
Manuel Pégourié-Gonnardc296c592013-07-09 12:54:04 +0200553static int x509_get_ecpubkey( unsigned char **p, const unsigned char *end,
554 x509_buf *alg_params, ecp_keypair *key )
555{
556 int ret;
557 ecp_group_id grp_id;
558
559 if( ( ret = x509_ecparams_get_grp_id( alg_params, &grp_id ) ) != 0 )
560 return( ret );
561
562 if( ( ret = ecp_use_known_dp( &key->grp, grp_id ) ) != 0 )
563 return( ret );
564
565 if( ( ret = ecp_point_read_binary( &key->grp, &key->Q,
566 (const unsigned char *) *p, end - *p ) ) != 0 )
567 {
Manuel Pégourié-Gonnard5b18fb02013-07-10 16:07:25 +0200568 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
569 }
570
571 *p = (unsigned char *) end;
572
573 if( ( ret = ecp_check_pubkey( &key->grp, &key->Q ) ) != 0 )
574 {
575 ecp_keypair_free( key );
576 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Manuel Pégourié-Gonnardc296c592013-07-09 12:54:04 +0200577 }
578
579 return( 0 );
580}
581
582/*
583 * SubjectPublicKeyInfo ::= SEQUENCE {
584 * algorithm AlgorithmIdentifier,
585 * subjectPublicKey BIT STRING }
586 */
587static int x509_get_pubkey( unsigned char **p,
588 const unsigned char *end,
589 pk_context *pk )
590{
591 int ret;
592 size_t len;
593 x509_buf alg_params;
594 pk_type_t pk_alg = POLARSSL_PK_NONE;
595
596 if( ( ret = asn1_get_tag( p, end, &len,
597 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
598 {
599 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
600 }
601
602 end = *p + len;
603
Manuel Pégourié-Gonnard7a287c42013-07-10 12:55:08 +0200604 if( ( ret = x509_get_pk_alg( p, end, &pk_alg, &alg_params ) ) != 0 )
Manuel Pégourié-Gonnardc296c592013-07-09 12:54:04 +0200605 return( ret );
606
607 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
608 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
609
610 if( ( end - *p ) < 1 )
611 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
612 POLARSSL_ERR_ASN1_OUT_OF_DATA );
613
614 if( *p + len != end )
615 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
616 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
617
Manuel Pégourié-Gonnard5b18fb02013-07-10 16:07:25 +0200618 if( --len < 1 || *(*p)++ != 0 )
Manuel Pégourié-Gonnardc296c592013-07-09 12:54:04 +0200619 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
620
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +0200621 if( ( ret = pk_set_type( pk, pk_alg ) ) != 0 )
622 return( ret );
Manuel Pégourié-Gonnardc296c592013-07-09 12:54:04 +0200623
624 switch( pk_alg )
625 {
626 case POLARSSL_PK_NONE:
Manuel Pégourié-Gonnard7c5819e2013-07-10 12:29:57 +0200627 case POLARSSL_PK_ECDSA:
628 /* Should never happen */
629 ret = POLARSSL_ERR_X509_CERT_INVALID_ALG;
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +0200630 break;
Manuel Pégourié-Gonnardc296c592013-07-09 12:54:04 +0200631
632 case POLARSSL_PK_RSA:
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +0200633 ret = x509_get_rsapubkey( p, end, pk->data );
634 break;
Manuel Pégourié-Gonnardc296c592013-07-09 12:54:04 +0200635
636 case POLARSSL_PK_ECKEY_DH:
637 ((ecp_keypair *) pk->data)->alg = POLARSSL_ECP_KEY_ALG_ECDH;
638 /* FALLTHROUGH */
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +0200639
Manuel Pégourié-Gonnardc296c592013-07-09 12:54:04 +0200640 case POLARSSL_PK_ECKEY:
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +0200641 ret = x509_get_ecpubkey( p, end, &alg_params, pk->data );
642 break;
Manuel Pégourié-Gonnardc296c592013-07-09 12:54:04 +0200643 }
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +0200644
Manuel Pégourié-Gonnard5b18fb02013-07-10 16:07:25 +0200645 if( ret == 0 && *p != end )
646 ret = POLARSSL_ERR_X509_CERT_INVALID_PUBKEY
647 POLARSSL_ERR_ASN1_LENGTH_MISMATCH;
648
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +0200649 if( ret != 0 )
650 pk_free( pk );
651
652 return( ret );
Manuel Pégourié-Gonnardc296c592013-07-09 12:54:04 +0200653}
654
Paul Bakker5121ce52009-01-03 21:22:43 +0000655static int x509_get_sig( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000656 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000657 x509_buf *sig )
658{
Paul Bakker23986e52011-04-24 08:57:21 +0000659 int ret;
660 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000661
Paul Bakker8afa70d2012-02-11 18:42:45 +0000662 if( ( end - *p ) < 1 )
663 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE +
664 POLARSSL_ERR_ASN1_OUT_OF_DATA );
665
Paul Bakker5121ce52009-01-03 21:22:43 +0000666 sig->tag = **p;
667
668 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000669 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000670
Paul Bakker74111d32011-01-15 16:57:55 +0000671
Paul Bakker5121ce52009-01-03 21:22:43 +0000672 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000673 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000674
675 sig->len = len;
676 sig->p = *p;
677
678 *p += len;
679
680 return( 0 );
681}
682
683/*
684 * X.509 v2/v3 unique identifier (not parsed)
685 */
686static int x509_get_uid( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000687 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000688 x509_buf *uid, int n )
689{
690 int ret;
691
692 if( *p == end )
693 return( 0 );
694
695 uid->tag = **p;
696
697 if( ( ret = asn1_get_tag( p, end, &uid->len,
698 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
699 {
Paul Bakker40e46942009-01-03 21:51:57 +0000700 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000701 return( 0 );
702
703 return( ret );
704 }
705
706 uid->p = *p;
707 *p += uid->len;
708
709 return( 0 );
710}
711
712/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000713 * X.509 Extensions (No parsing of extensions, pointer should
714 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000715 */
716static int x509_get_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000717 const unsigned char *end,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000718 x509_buf *ext, int tag )
Paul Bakker5121ce52009-01-03 21:22:43 +0000719{
Paul Bakker23986e52011-04-24 08:57:21 +0000720 int ret;
721 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000722
723 if( *p == end )
724 return( 0 );
725
726 ext->tag = **p;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000727
Paul Bakker5121ce52009-01-03 21:22:43 +0000728 if( ( ret = asn1_get_tag( p, end, &ext->len,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000729 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000730 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000731
732 ext->p = *p;
733 end = *p + ext->len;
734
735 /*
736 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
737 *
738 * Extension ::= SEQUENCE {
739 * extnID OBJECT IDENTIFIER,
740 * critical BOOLEAN DEFAULT FALSE,
741 * extnValue OCTET STRING }
742 */
743 if( ( ret = asn1_get_tag( p, end, &len,
744 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000745 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000746
747 if( end != *p + len )
Paul Bakker9d781402011-05-09 16:17:09 +0000748 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +0000749 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000750
Paul Bakkerd98030e2009-05-02 15:13:40 +0000751 return( 0 );
752}
753
754/*
755 * X.509 CRL v2 extensions (no extensions parsed yet.)
756 */
757static int x509_get_crl_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000758 const unsigned char *end,
759 x509_buf *ext )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000760{
Paul Bakker23986e52011-04-24 08:57:21 +0000761 int ret;
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000762 size_t len = 0;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000763
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000764 /* Get explicit tag */
765 if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000766 {
767 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
768 return( 0 );
769
770 return( ret );
771 }
772
773 while( *p < end )
774 {
775 if( ( ret = asn1_get_tag( p, end, &len,
776 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000777 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000778
779 *p += len;
780 }
781
782 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000783 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerd98030e2009-05-02 15:13:40 +0000784 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
785
786 return( 0 );
787}
788
Paul Bakkerb5a11ab2011-10-12 09:58:41 +0000789/*
790 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
791 */
792static int x509_get_crl_entry_ext( unsigned char **p,
793 const unsigned char *end,
794 x509_buf *ext )
795{
796 int ret;
797 size_t len = 0;
798
799 /* OPTIONAL */
800 if (end <= *p)
801 return( 0 );
802
803 ext->tag = **p;
804 ext->p = *p;
805
806 /*
807 * Get CRL-entry extension sequence header
808 * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
809 */
810 if( ( ret = asn1_get_tag( p, end, &ext->len,
811 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
812 {
813 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
814 {
815 ext->p = NULL;
816 return( 0 );
817 }
818 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
819 }
820
821 end = *p + ext->len;
822
823 if( end != *p + ext->len )
824 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
825 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
826
827 while( *p < end )
828 {
829 if( ( ret = asn1_get_tag( p, end, &len,
830 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
831 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
832
833 *p += len;
834 }
835
836 if( *p != end )
837 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
838 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
839
840 return( 0 );
841}
842
Paul Bakker74111d32011-01-15 16:57:55 +0000843static int x509_get_basic_constraints( unsigned char **p,
844 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000845 int *ca_istrue,
846 int *max_pathlen )
847{
Paul Bakker23986e52011-04-24 08:57:21 +0000848 int ret;
849 size_t len;
Paul Bakker74111d32011-01-15 16:57:55 +0000850
851 /*
852 * BasicConstraints ::= SEQUENCE {
853 * cA BOOLEAN DEFAULT FALSE,
854 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
855 */
Paul Bakker3cccddb2011-01-16 21:46:31 +0000856 *ca_istrue = 0; /* DEFAULT FALSE */
Paul Bakker74111d32011-01-15 16:57:55 +0000857 *max_pathlen = 0; /* endless */
858
859 if( ( ret = asn1_get_tag( p, end, &len,
860 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000861 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000862
863 if( *p == end )
864 return 0;
865
Paul Bakker3cccddb2011-01-16 21:46:31 +0000866 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000867 {
868 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker3cccddb2011-01-16 21:46:31 +0000869 ret = asn1_get_int( p, end, ca_istrue );
Paul Bakker74111d32011-01-15 16:57:55 +0000870
871 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000872 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000873
Paul Bakker3cccddb2011-01-16 21:46:31 +0000874 if( *ca_istrue != 0 )
875 *ca_istrue = 1;
Paul Bakker74111d32011-01-15 16:57:55 +0000876 }
877
878 if( *p == end )
879 return 0;
880
881 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000882 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000883
884 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000885 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000886 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
887
888 (*max_pathlen)++;
889
Paul Bakker74111d32011-01-15 16:57:55 +0000890 return 0;
891}
892
893static int x509_get_ns_cert_type( unsigned char **p,
894 const unsigned char *end,
895 unsigned char *ns_cert_type)
896{
897 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000898 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000899
900 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000901 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000902
903 if( bs.len != 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000904 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000905 POLARSSL_ERR_ASN1_INVALID_LENGTH );
906
907 /* Get actual bitstring */
908 *ns_cert_type = *bs.p;
909 return 0;
910}
911
912static int x509_get_key_usage( unsigned char **p,
913 const unsigned char *end,
914 unsigned char *key_usage)
915{
916 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000917 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000918
919 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000920 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000921
Paul Bakker94a67962012-08-23 13:03:52 +0000922 if( bs.len < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000923 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000924 POLARSSL_ERR_ASN1_INVALID_LENGTH );
925
926 /* Get actual bitstring */
927 *key_usage = *bs.p;
928 return 0;
929}
930
Paul Bakkerd98030e2009-05-02 15:13:40 +0000931/*
Paul Bakker74111d32011-01-15 16:57:55 +0000932 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
933 *
934 * KeyPurposeId ::= OBJECT IDENTIFIER
935 */
936static int x509_get_ext_key_usage( unsigned char **p,
937 const unsigned char *end,
938 x509_sequence *ext_key_usage)
939{
940 int ret;
941
942 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000943 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000944
945 /* Sequence length must be >= 1 */
946 if( ext_key_usage->buf.p == NULL )
Paul Bakker9d781402011-05-09 16:17:09 +0000947 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000948 POLARSSL_ERR_ASN1_INVALID_LENGTH );
949
950 return 0;
951}
952
953/*
Paul Bakkera8cd2392012-02-11 16:09:32 +0000954 * SubjectAltName ::= GeneralNames
955 *
956 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
957 *
958 * GeneralName ::= CHOICE {
959 * otherName [0] OtherName,
960 * rfc822Name [1] IA5String,
961 * dNSName [2] IA5String,
962 * x400Address [3] ORAddress,
963 * directoryName [4] Name,
964 * ediPartyName [5] EDIPartyName,
965 * uniformResourceIdentifier [6] IA5String,
966 * iPAddress [7] OCTET STRING,
967 * registeredID [8] OBJECT IDENTIFIER }
968 *
969 * OtherName ::= SEQUENCE {
970 * type-id OBJECT IDENTIFIER,
971 * value [0] EXPLICIT ANY DEFINED BY type-id }
972 *
973 * EDIPartyName ::= SEQUENCE {
974 * nameAssigner [0] DirectoryString OPTIONAL,
975 * partyName [1] DirectoryString }
976 *
977 * NOTE: PolarSSL only parses and uses dNSName at this point.
978 */
979static int x509_get_subject_alt_name( unsigned char **p,
980 const unsigned char *end,
981 x509_sequence *subject_alt_name )
982{
983 int ret;
984 size_t len, tag_len;
985 asn1_buf *buf;
986 unsigned char tag;
987 asn1_sequence *cur = subject_alt_name;
988
989 /* Get main sequence tag */
990 if( ( ret = asn1_get_tag( p, end, &len,
991 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
992 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
993
994 if( *p + len != end )
995 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
996 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
997
998 while( *p < end )
999 {
1000 if( ( end - *p ) < 1 )
1001 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
1002 POLARSSL_ERR_ASN1_OUT_OF_DATA );
1003
1004 tag = **p;
1005 (*p)++;
1006 if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 )
1007 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
1008
1009 if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC )
1010 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
1011 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
1012
1013 if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) )
1014 {
1015 *p += tag_len;
1016 continue;
1017 }
1018
1019 buf = &(cur->buf);
1020 buf->tag = tag;
1021 buf->p = *p;
1022 buf->len = tag_len;
1023 *p += buf->len;
1024
1025 /* Allocate and assign next pointer */
1026 if (*p < end)
1027 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001028 cur->next = (asn1_sequence *) polarssl_malloc(
Paul Bakkera8cd2392012-02-11 16:09:32 +00001029 sizeof( asn1_sequence ) );
1030
1031 if( cur->next == NULL )
1032 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
1033 POLARSSL_ERR_ASN1_MALLOC_FAILED );
1034
Paul Bakker535e97d2012-08-23 10:49:55 +00001035 memset( cur->next, 0, sizeof( asn1_sequence ) );
Paul Bakkera8cd2392012-02-11 16:09:32 +00001036 cur = cur->next;
1037 }
1038 }
1039
1040 /* Set final sequence entry's next pointer to NULL */
1041 cur->next = NULL;
1042
1043 if( *p != end )
1044 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
1045 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1046
1047 return( 0 );
1048}
1049
1050/*
Paul Bakker74111d32011-01-15 16:57:55 +00001051 * X.509 v3 extensions
1052 *
1053 * TODO: Perform all of the basic constraints tests required by the RFC
1054 * TODO: Set values for undetected extensions to a sane default?
1055 *
Paul Bakkerd98030e2009-05-02 15:13:40 +00001056 */
1057static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001058 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +00001059 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001060{
Paul Bakker23986e52011-04-24 08:57:21 +00001061 int ret;
1062 size_t len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001063 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001064
Paul Bakkerfbc09f32011-10-12 09:56:41 +00001065 if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001066 {
1067 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
1068 return( 0 );
1069
1070 return( ret );
1071 }
1072
Paul Bakker5121ce52009-01-03 21:22:43 +00001073 while( *p < end )
1074 {
Paul Bakker74111d32011-01-15 16:57:55 +00001075 /*
1076 * Extension ::= SEQUENCE {
1077 * extnID OBJECT IDENTIFIER,
1078 * critical BOOLEAN DEFAULT FALSE,
1079 * extnValue OCTET STRING }
1080 */
1081 x509_buf extn_oid = {0, 0, NULL};
1082 int is_critical = 0; /* DEFAULT FALSE */
Paul Bakkerc70b9822013-04-07 22:00:46 +02001083 int ext_type = 0;
Paul Bakker74111d32011-01-15 16:57:55 +00001084
Paul Bakker5121ce52009-01-03 21:22:43 +00001085 if( ( ret = asn1_get_tag( p, end, &len,
1086 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +00001087 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001088
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001089 end_ext_data = *p + len;
1090
Paul Bakker74111d32011-01-15 16:57:55 +00001091 /* Get extension ID */
1092 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +00001093
Paul Bakker74111d32011-01-15 16:57:55 +00001094 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +00001095 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001096
Paul Bakker74111d32011-01-15 16:57:55 +00001097 extn_oid.p = *p;
1098 *p += extn_oid.len;
1099
1100 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +00001101 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +00001102 POLARSSL_ERR_ASN1_OUT_OF_DATA );
1103
1104 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001105 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +00001106 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
Paul Bakker9d781402011-05-09 16:17:09 +00001107 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001108
Paul Bakker74111d32011-01-15 16:57:55 +00001109 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001110 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +00001111 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +00001112 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001113
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001114 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +00001115
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001116 if( end_ext_octet != end_ext_data )
Paul Bakker9d781402011-05-09 16:17:09 +00001117 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerc6ce8382009-07-27 21:34:45 +00001118 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001119
Paul Bakker74111d32011-01-15 16:57:55 +00001120 /*
1121 * Detect supported extensions
1122 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02001123 ret = oid_get_x509_ext_type( &extn_oid, &ext_type );
1124
1125 if( ret != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +00001126 {
1127 /* No parser found, skip extension */
1128 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +00001129
Paul Bakker5c721f92011-07-27 16:51:09 +00001130#if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
Paul Bakker74111d32011-01-15 16:57:55 +00001131 if( is_critical )
1132 {
1133 /* Data is marked as critical: fail */
Paul Bakker9d781402011-05-09 16:17:09 +00001134 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +00001135 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
1136 }
Paul Bakker5c721f92011-07-27 16:51:09 +00001137#endif
Paul Bakkerc70b9822013-04-07 22:00:46 +02001138 continue;
1139 }
1140
1141 crt->ext_types |= ext_type;
1142
1143 switch( ext_type )
1144 {
1145 case EXT_BASIC_CONSTRAINTS:
1146 /* Parse basic constraints */
1147 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
1148 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
1149 return ( ret );
1150 break;
1151
1152 case EXT_KEY_USAGE:
1153 /* Parse key usage */
1154 if( ( ret = x509_get_key_usage( p, end_ext_octet,
1155 &crt->key_usage ) ) != 0 )
1156 return ( ret );
1157 break;
1158
1159 case EXT_EXTENDED_KEY_USAGE:
1160 /* Parse extended key usage */
1161 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
1162 &crt->ext_key_usage ) ) != 0 )
1163 return ( ret );
1164 break;
1165
1166 case EXT_SUBJECT_ALT_NAME:
1167 /* Parse subject alt name */
1168 if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
1169 &crt->subject_alt_names ) ) != 0 )
1170 return ( ret );
1171 break;
1172
1173 case EXT_NS_CERT_TYPE:
1174 /* Parse netscape certificate type */
1175 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
1176 &crt->ns_cert_type ) ) != 0 )
1177 return ( ret );
1178 break;
1179
1180 default:
1181 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker74111d32011-01-15 16:57:55 +00001182 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001183 }
1184
1185 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +00001186 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +00001187 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001188
Paul Bakker5121ce52009-01-03 21:22:43 +00001189 return( 0 );
1190}
1191
1192/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001193 * X.509 CRL Entries
1194 */
1195static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001196 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001197 x509_crl_entry *entry )
1198{
Paul Bakker23986e52011-04-24 08:57:21 +00001199 int ret;
1200 size_t entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001201 x509_crl_entry *cur_entry = entry;
1202
1203 if( *p == end )
1204 return( 0 );
1205
Paul Bakker9be19372009-07-27 20:21:53 +00001206 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001207 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1208 {
1209 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
1210 return( 0 );
1211
1212 return( ret );
1213 }
1214
Paul Bakker9be19372009-07-27 20:21:53 +00001215 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001216
1217 while( *p < end )
1218 {
Paul Bakker23986e52011-04-24 08:57:21 +00001219 size_t len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001220 const unsigned char *end2;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001221
1222 if( ( ret = asn1_get_tag( p, end, &len2,
1223 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1224 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001225 return( ret );
1226 }
1227
Paul Bakker9be19372009-07-27 20:21:53 +00001228 cur_entry->raw.tag = **p;
1229 cur_entry->raw.p = *p;
1230 cur_entry->raw.len = len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001231 end2 = *p + len2;
Paul Bakker9be19372009-07-27 20:21:53 +00001232
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001233 if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001234 return( ret );
1235
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001236 if( ( ret = x509_get_time( p, end2, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001237 return( ret );
1238
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001239 if( ( ret = x509_get_crl_entry_ext( p, end2, &cur_entry->entry_ext ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001240 return( ret );
1241
Paul Bakker74111d32011-01-15 16:57:55 +00001242 if ( *p < end )
1243 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001244 cur_entry->next = polarssl_malloc( sizeof( x509_crl_entry ) );
Paul Bakkerb15b8512012-01-13 13:44:06 +00001245
1246 if( cur_entry->next == NULL )
1247 return( POLARSSL_ERR_X509_MALLOC_FAILED );
1248
Paul Bakkerd98030e2009-05-02 15:13:40 +00001249 cur_entry = cur_entry->next;
1250 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
1251 }
1252 }
1253
1254 return( 0 );
1255}
1256
Paul Bakkerc70b9822013-04-07 22:00:46 +02001257static int x509_get_sig_alg( const x509_buf *sig_oid, md_type_t *md_alg,
1258 pk_type_t *pk_alg )
Paul Bakker27d66162010-03-17 06:56:01 +00001259{
Paul Bakkerc70b9822013-04-07 22:00:46 +02001260 int ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg );
Paul Bakker27d66162010-03-17 06:56:01 +00001261
Paul Bakkerc70b9822013-04-07 22:00:46 +02001262 if( ret != 0 )
1263 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG + ret );
Paul Bakker27d66162010-03-17 06:56:01 +00001264
Paul Bakkerc70b9822013-04-07 22:00:46 +02001265 return( 0 );
Paul Bakker27d66162010-03-17 06:56:01 +00001266}
1267
Paul Bakkerd98030e2009-05-02 15:13:40 +00001268/*
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001269 * Parse and fill a single X.509 certificate in DER format
Paul Bakker5121ce52009-01-03 21:22:43 +00001270 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02001271static int x509parse_crt_der_core( x509_cert *crt, const unsigned char *buf,
1272 size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001273{
Paul Bakker23986e52011-04-24 08:57:21 +00001274 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001275 size_t len;
Paul Bakkerb00ca422012-09-25 12:10:00 +00001276 unsigned char *p, *end, *crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001277
Paul Bakker320a4b52009-03-28 18:52:39 +00001278 /*
1279 * Check for valid input
1280 */
1281 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001282 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker320a4b52009-03-28 18:52:39 +00001283
Paul Bakker6e339b52013-07-03 13:37:05 +02001284 p = (unsigned char *) polarssl_malloc( len = buflen );
Paul Bakker96743fc2011-02-12 14:30:57 +00001285
1286 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001287 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001288
1289 memcpy( p, buf, buflen );
1290
1291 buflen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001292
1293 crt->raw.p = p;
1294 crt->raw.len = len;
1295 end = p + len;
1296
1297 /*
1298 * Certificate ::= SEQUENCE {
1299 * tbsCertificate TBSCertificate,
1300 * signatureAlgorithm AlgorithmIdentifier,
1301 * signatureValue BIT STRING }
1302 */
1303 if( ( ret = asn1_get_tag( &p, end, &len,
1304 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1305 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001306 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001307 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001308 }
1309
Paul Bakkerb00ca422012-09-25 12:10:00 +00001310 if( len > (size_t) ( end - p ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001311 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001312 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001313 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001314 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001315 }
Paul Bakkerb00ca422012-09-25 12:10:00 +00001316 crt_end = p + len;
Paul Bakker42c65812013-06-24 19:21:59 +02001317
Paul Bakker5121ce52009-01-03 21:22:43 +00001318 /*
1319 * TBSCertificate ::= SEQUENCE {
1320 */
1321 crt->tbs.p = p;
1322
1323 if( ( ret = asn1_get_tag( &p, end, &len,
1324 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1325 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001326 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001327 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001328 }
1329
1330 end = p + len;
1331 crt->tbs.len = end - crt->tbs.p;
1332
1333 /*
1334 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1335 *
1336 * CertificateSerialNumber ::= INTEGER
1337 *
1338 * signature AlgorithmIdentifier
1339 */
Manuel Pégourié-Gonnarda1555132013-07-10 13:18:41 +02001340 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1341 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1342 ( ret = x509_get_alg_null( &p, end, &crt->sig_oid1 ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001343 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001344 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001345 return( ret );
1346 }
1347
1348 crt->version++;
1349
1350 if( crt->version > 3 )
1351 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001352 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001353 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001354 }
1355
Paul Bakkerc70b9822013-04-07 22:00:46 +02001356 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_md,
1357 &crt->sig_pk ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001358 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001359 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001360 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001361 }
1362
1363 /*
1364 * issuer Name
1365 */
1366 crt->issuer_raw.p = p;
1367
1368 if( ( ret = asn1_get_tag( &p, end, &len,
1369 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1370 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001371 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001372 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001373 }
1374
1375 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1376 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001377 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001378 return( ret );
1379 }
1380
1381 crt->issuer_raw.len = p - crt->issuer_raw.p;
1382
1383 /*
1384 * Validity ::= SEQUENCE {
1385 * notBefore Time,
1386 * notAfter Time }
1387 *
1388 */
1389 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1390 &crt->valid_to ) ) != 0 )
1391 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001392 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001393 return( ret );
1394 }
1395
1396 /*
1397 * subject Name
1398 */
1399 crt->subject_raw.p = p;
1400
1401 if( ( ret = asn1_get_tag( &p, end, &len,
1402 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1403 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001404 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001405 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001406 }
1407
Paul Bakkercefb3962012-06-27 11:51:09 +00001408 if( len && ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001409 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001410 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001411 return( ret );
1412 }
1413
1414 crt->subject_raw.len = p - crt->subject_raw.p;
1415
1416 /*
Manuel Pégourié-Gonnard20c12f62013-07-09 12:13:24 +02001417 * SubjectPublicKeyInfo
Paul Bakker5121ce52009-01-03 21:22:43 +00001418 */
Manuel Pégourié-Gonnard674b2242013-07-10 14:32:58 +02001419 if( ( ret = x509_get_pubkey( &p, end, &crt->pk ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001420 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001421 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001422 return( ret );
1423 }
1424
Paul Bakker5121ce52009-01-03 21:22:43 +00001425 /*
Manuel Pégourié-Gonnard674b2242013-07-10 14:32:58 +02001426 * Temporary hack for compatibility while transitioning to PK abstraction
1427 * (Cannot use rsa_wrap above since it would force RSA key type.)
1428 */
1429 if( crt->pk.type == POLARSSL_PK_RSA ) {
1430 memcpy( &crt->rsa, pk_rsa( crt->pk ), sizeof( rsa_context ) );
1431 free( crt->pk.data );
1432 crt->pk.data = &crt->rsa;
1433 crt->pk.dont_free = 1;
1434 }
1435
1436 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001437 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1438 * -- If present, version shall be v2 or v3
1439 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1440 * -- If present, version shall be v2 or v3
1441 * extensions [3] EXPLICIT Extensions OPTIONAL
1442 * -- If present, version shall be v3
1443 */
1444 if( crt->version == 2 || crt->version == 3 )
1445 {
1446 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1447 if( ret != 0 )
1448 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001449 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001450 return( ret );
1451 }
1452 }
1453
1454 if( crt->version == 2 || crt->version == 3 )
1455 {
1456 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1457 if( ret != 0 )
1458 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001459 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001460 return( ret );
1461 }
1462 }
1463
1464 if( crt->version == 3 )
1465 {
Paul Bakker74111d32011-01-15 16:57:55 +00001466 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001467 if( ret != 0 )
1468 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001469 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001470 return( ret );
1471 }
1472 }
1473
1474 if( p != end )
1475 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001476 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001477 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001478 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001479 }
1480
Paul Bakkerb00ca422012-09-25 12:10:00 +00001481 end = crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001482
1483 /*
Manuel Pégourié-Gonnard20c12f62013-07-09 12:13:24 +02001484 * }
1485 * -- end of TBSCertificate
1486 *
Paul Bakker5121ce52009-01-03 21:22:43 +00001487 * signatureAlgorithm AlgorithmIdentifier,
1488 * signatureValue BIT STRING
1489 */
Manuel Pégourié-Gonnarda1555132013-07-10 13:18:41 +02001490 if( ( ret = x509_get_alg_null( &p, end, &crt->sig_oid2 ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001491 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001492 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001493 return( ret );
1494 }
1495
Paul Bakker535e97d2012-08-23 10:49:55 +00001496 if( crt->sig_oid1.len != crt->sig_oid2.len ||
1497 memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001498 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001499 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001500 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001501 }
1502
1503 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1504 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001505 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001506 return( ret );
1507 }
1508
1509 if( p != end )
1510 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001511 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001512 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001513 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001514 }
1515
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001516 return( 0 );
1517}
1518
1519/*
Paul Bakker42c65812013-06-24 19:21:59 +02001520 * Parse one X.509 certificate in DER format from a buffer and add them to a
1521 * chained list
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001522 */
Paul Bakker42c65812013-06-24 19:21:59 +02001523int x509parse_crt_der( x509_cert *chain, const unsigned char *buf, size_t buflen )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001524{
Paul Bakker42c65812013-06-24 19:21:59 +02001525 int ret;
1526 x509_cert *crt = chain, *prev = NULL;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001527
1528 /*
1529 * Check for valid input
1530 */
1531 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001532 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001533
1534 while( crt->version != 0 && crt->next != NULL )
1535 {
1536 prev = crt;
1537 crt = crt->next;
1538 }
1539
1540 /*
1541 * Add new certificate on the end of the chain if needed.
1542 */
1543 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001544 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001545 crt->next = (x509_cert *) polarssl_malloc( sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001546
Paul Bakker7d06ad22009-05-02 15:53:56 +00001547 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001548 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker320a4b52009-03-28 18:52:39 +00001549
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001550 prev = crt;
Paul Bakker7d06ad22009-05-02 15:53:56 +00001551 crt = crt->next;
1552 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001553 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001554
Paul Bakker42c65812013-06-24 19:21:59 +02001555 if( ( ret = x509parse_crt_der_core( crt, buf, buflen ) ) != 0 )
1556 {
1557 if( prev )
1558 prev->next = NULL;
1559
1560 if( crt != chain )
Paul Bakker6e339b52013-07-03 13:37:05 +02001561 polarssl_free( crt );
Paul Bakker42c65812013-06-24 19:21:59 +02001562
1563 return( ret );
1564 }
1565
1566 return( 0 );
1567}
1568
1569/*
1570 * Parse one or more PEM certificates from a buffer and add them to the chained list
1571 */
1572int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
1573{
1574 int ret, success = 0, first_error = 0, total_failed = 0;
1575 int buf_format = X509_FORMAT_DER;
1576
1577 /*
1578 * Check for valid input
1579 */
1580 if( chain == NULL || buf == NULL )
1581 return( POLARSSL_ERR_X509_INVALID_INPUT );
1582
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001583 /*
1584 * Determine buffer content. Buffer contains either one DER certificate or
1585 * one or more PEM certificates.
1586 */
1587#if defined(POLARSSL_PEM_C)
Paul Bakker3c2122f2013-06-24 19:03:14 +02001588 if( strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001589 buf_format = X509_FORMAT_PEM;
1590#endif
1591
1592 if( buf_format == X509_FORMAT_DER )
Paul Bakker42c65812013-06-24 19:21:59 +02001593 return x509parse_crt_der( chain, buf, buflen );
1594
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001595#if defined(POLARSSL_PEM_C)
1596 if( buf_format == X509_FORMAT_PEM )
1597 {
1598 pem_context pem;
1599
1600 while( buflen > 0 )
1601 {
1602 size_t use_len;
1603 pem_init( &pem );
1604
1605 ret = pem_read_buffer( &pem,
1606 "-----BEGIN CERTIFICATE-----",
1607 "-----END CERTIFICATE-----",
1608 buf, NULL, 0, &use_len );
1609
1610 if( ret == 0 )
1611 {
1612 /*
1613 * Was PEM encoded
1614 */
1615 buflen -= use_len;
1616 buf += use_len;
1617 }
Paul Bakker5ed3b342013-06-24 19:05:46 +02001618 else if( ret == POLARSSL_ERR_PEM_BAD_INPUT_DATA )
1619 {
1620 return( ret );
1621 }
Paul Bakker00b28602013-06-24 13:02:41 +02001622 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001623 {
1624 pem_free( &pem );
1625
Paul Bakker5ed3b342013-06-24 19:05:46 +02001626 /*
1627 * PEM header and footer were found
1628 */
1629 buflen -= use_len;
1630 buf += use_len;
1631
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001632 if( first_error == 0 )
1633 first_error = ret;
1634
1635 continue;
1636 }
1637 else
1638 break;
1639
Paul Bakker42c65812013-06-24 19:21:59 +02001640 ret = x509parse_crt_der( chain, pem.buf, pem.buflen );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001641
1642 pem_free( &pem );
1643
1644 if( ret != 0 )
1645 {
1646 /*
Paul Bakker42c65812013-06-24 19:21:59 +02001647 * Quit parsing on a memory error
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001648 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001649 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001650 return( ret );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001651
1652 if( first_error == 0 )
1653 first_error = ret;
1654
Paul Bakker42c65812013-06-24 19:21:59 +02001655 total_failed++;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001656 continue;
1657 }
1658
1659 success = 1;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001660 }
1661 }
1662#endif
1663
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001664 if( success )
Paul Bakker69e095c2011-12-10 21:55:01 +00001665 return( total_failed );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001666 else if( first_error )
1667 return( first_error );
1668 else
1669 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001670}
1671
1672/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001673 * Parse one or more CRLs and add them to the chained list
1674 */
Paul Bakker23986e52011-04-24 08:57:21 +00001675int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001676{
Paul Bakker23986e52011-04-24 08:57:21 +00001677 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001678 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001679 unsigned char *p, *end;
1680 x509_crl *crl;
Paul Bakker96743fc2011-02-12 14:30:57 +00001681#if defined(POLARSSL_PEM_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00001682 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001683 pem_context pem;
1684#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001685
1686 crl = chain;
1687
1688 /*
1689 * Check for valid input
1690 */
1691 if( crl == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001692 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001693
1694 while( crl->version != 0 && crl->next != NULL )
1695 crl = crl->next;
1696
1697 /*
1698 * Add new CRL on the end of the chain if needed.
1699 */
1700 if ( crl->version != 0 && crl->next == NULL)
1701 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001702 crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001703
Paul Bakker7d06ad22009-05-02 15:53:56 +00001704 if( crl->next == NULL )
1705 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001706 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001707 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001708 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001709
Paul Bakker7d06ad22009-05-02 15:53:56 +00001710 crl = crl->next;
1711 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001712 }
1713
Paul Bakker96743fc2011-02-12 14:30:57 +00001714#if defined(POLARSSL_PEM_C)
1715 pem_init( &pem );
1716 ret = pem_read_buffer( &pem,
1717 "-----BEGIN X509 CRL-----",
1718 "-----END X509 CRL-----",
1719 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001720
Paul Bakker96743fc2011-02-12 14:30:57 +00001721 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001722 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001723 /*
1724 * Was PEM encoded
1725 */
1726 buflen -= use_len;
1727 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001728
1729 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001730 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001731 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001732 p = pem.buf;
1733 pem.buf = NULL;
1734 len = pem.buflen;
1735 pem_free( &pem );
1736 }
Paul Bakker00b28602013-06-24 13:02:41 +02001737 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker96743fc2011-02-12 14:30:57 +00001738 {
1739 pem_free( &pem );
1740 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001741 }
1742 else
1743 {
1744 /*
1745 * nope, copy the raw DER data
1746 */
Paul Bakker6e339b52013-07-03 13:37:05 +02001747 p = (unsigned char *) polarssl_malloc( len = buflen );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001748
1749 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001750 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001751
1752 memcpy( p, buf, buflen );
1753
1754 buflen = 0;
1755 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001756#else
Paul Bakker6e339b52013-07-03 13:37:05 +02001757 p = (unsigned char *) polarssl_malloc( len = buflen );
Paul Bakker96743fc2011-02-12 14:30:57 +00001758
1759 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001760 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001761
1762 memcpy( p, buf, buflen );
1763
1764 buflen = 0;
1765#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001766
1767 crl->raw.p = p;
1768 crl->raw.len = len;
1769 end = p + len;
1770
1771 /*
1772 * CertificateList ::= SEQUENCE {
1773 * tbsCertList TBSCertList,
1774 * signatureAlgorithm AlgorithmIdentifier,
1775 * signatureValue BIT STRING }
1776 */
1777 if( ( ret = asn1_get_tag( &p, end, &len,
1778 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1779 {
1780 x509_crl_free( crl );
1781 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1782 }
1783
Paul Bakker23986e52011-04-24 08:57:21 +00001784 if( len != (size_t) ( end - p ) )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001785 {
1786 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001787 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001788 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1789 }
1790
1791 /*
1792 * TBSCertList ::= SEQUENCE {
1793 */
1794 crl->tbs.p = p;
1795
1796 if( ( ret = asn1_get_tag( &p, end, &len,
1797 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1798 {
1799 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001800 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001801 }
1802
1803 end = p + len;
1804 crl->tbs.len = end - crl->tbs.p;
1805
1806 /*
1807 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1808 * -- if present, MUST be v2
1809 *
1810 * signature AlgorithmIdentifier
1811 */
Paul Bakker3329d1f2011-10-12 09:55:01 +00001812 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
Manuel Pégourié-Gonnarda1555132013-07-10 13:18:41 +02001813 ( ret = x509_get_alg_null( &p, end, &crl->sig_oid1 ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001814 {
1815 x509_crl_free( crl );
1816 return( ret );
1817 }
1818
1819 crl->version++;
1820
1821 if( crl->version > 2 )
1822 {
1823 x509_crl_free( crl );
1824 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1825 }
1826
Paul Bakkerc70b9822013-04-07 22:00:46 +02001827 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_md,
1828 &crl->sig_pk ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001829 {
1830 x509_crl_free( crl );
1831 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1832 }
1833
1834 /*
1835 * issuer Name
1836 */
1837 crl->issuer_raw.p = p;
1838
1839 if( ( ret = asn1_get_tag( &p, end, &len,
1840 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1841 {
1842 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001843 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001844 }
1845
1846 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1847 {
1848 x509_crl_free( crl );
1849 return( ret );
1850 }
1851
1852 crl->issuer_raw.len = p - crl->issuer_raw.p;
1853
1854 /*
1855 * thisUpdate Time
1856 * nextUpdate Time OPTIONAL
1857 */
Paul Bakker91200182010-02-18 21:26:15 +00001858 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001859 {
1860 x509_crl_free( crl );
1861 return( ret );
1862 }
1863
Paul Bakker91200182010-02-18 21:26:15 +00001864 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001865 {
Paul Bakker9d781402011-05-09 16:17:09 +00001866 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001867 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker9d781402011-05-09 16:17:09 +00001868 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001869 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001870 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001871 x509_crl_free( crl );
1872 return( ret );
1873 }
1874 }
1875
1876 /*
1877 * revokedCertificates SEQUENCE OF SEQUENCE {
1878 * userCertificate CertificateSerialNumber,
1879 * revocationDate Time,
1880 * crlEntryExtensions Extensions OPTIONAL
1881 * -- if present, MUST be v2
1882 * } OPTIONAL
1883 */
1884 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1885 {
1886 x509_crl_free( crl );
1887 return( ret );
1888 }
1889
1890 /*
1891 * crlExtensions EXPLICIT Extensions OPTIONAL
1892 * -- if present, MUST be v2
1893 */
1894 if( crl->version == 2 )
1895 {
1896 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1897
1898 if( ret != 0 )
1899 {
1900 x509_crl_free( crl );
1901 return( ret );
1902 }
1903 }
1904
1905 if( p != end )
1906 {
1907 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001908 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001909 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1910 }
1911
1912 end = crl->raw.p + crl->raw.len;
1913
1914 /*
1915 * signatureAlgorithm AlgorithmIdentifier,
1916 * signatureValue BIT STRING
1917 */
Manuel Pégourié-Gonnarda1555132013-07-10 13:18:41 +02001918 if( ( ret = x509_get_alg_null( &p, end, &crl->sig_oid2 ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001919 {
1920 x509_crl_free( crl );
1921 return( ret );
1922 }
1923
Paul Bakker535e97d2012-08-23 10:49:55 +00001924 if( crl->sig_oid1.len != crl->sig_oid2.len ||
1925 memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001926 {
1927 x509_crl_free( crl );
1928 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1929 }
1930
1931 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1932 {
1933 x509_crl_free( crl );
1934 return( ret );
1935 }
1936
1937 if( p != end )
1938 {
1939 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001940 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001941 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1942 }
1943
1944 if( buflen > 0 )
1945 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001946 crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001947
Paul Bakker7d06ad22009-05-02 15:53:56 +00001948 if( crl->next == NULL )
1949 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001950 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001951 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001952 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001953
Paul Bakker7d06ad22009-05-02 15:53:56 +00001954 crl = crl->next;
1955 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001956
1957 return( x509parse_crl( crl, buf, buflen ) );
1958 }
1959
1960 return( 0 );
1961}
1962
Paul Bakker335db3f2011-04-25 15:28:35 +00001963#if defined(POLARSSL_FS_IO)
Paul Bakkerd98030e2009-05-02 15:13:40 +00001964/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001965 * Load all data from a file into a given buffer.
1966 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02001967static int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001968{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001969 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001970
Paul Bakkerd98030e2009-05-02 15:13:40 +00001971 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001972 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001973
Paul Bakkerd98030e2009-05-02 15:13:40 +00001974 fseek( f, 0, SEEK_END );
1975 *n = (size_t) ftell( f );
1976 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001977
Paul Bakker6e339b52013-07-03 13:37:05 +02001978 if( ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
Paul Bakkerf6a19bd2013-05-14 13:26:51 +02001979 {
1980 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +00001981 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerf6a19bd2013-05-14 13:26:51 +02001982 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001983
Paul Bakkerd98030e2009-05-02 15:13:40 +00001984 if( fread( *buf, 1, *n, f ) != *n )
1985 {
1986 fclose( f );
Paul Bakker6e339b52013-07-03 13:37:05 +02001987 polarssl_free( *buf );
Paul Bakker69e095c2011-12-10 21:55:01 +00001988 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001989 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001990
Paul Bakkerd98030e2009-05-02 15:13:40 +00001991 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001992
Paul Bakkerd98030e2009-05-02 15:13:40 +00001993 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001994
Paul Bakkerd98030e2009-05-02 15:13:40 +00001995 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001996}
1997
1998/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001999 * Load one or more certificates and add them to the chained list
2000 */
Paul Bakker69e095c2011-12-10 21:55:01 +00002001int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00002002{
2003 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002004 size_t n;
2005 unsigned char *buf;
2006
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02002007 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00002008 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002009
Paul Bakker69e095c2011-12-10 21:55:01 +00002010 ret = x509parse_crt( chain, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002011
2012 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02002013 polarssl_free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00002014
2015 return( ret );
2016}
2017
Paul Bakker8d914582012-06-04 12:46:42 +00002018int x509parse_crtpath( x509_cert *chain, const char *path )
2019{
2020 int ret = 0;
2021#if defined(_WIN32)
Paul Bakker3338b792012-10-01 21:13:10 +00002022 int w_ret;
2023 WCHAR szDir[MAX_PATH];
2024 char filename[MAX_PATH];
2025 char *p;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002026 int len = strlen( path );
Paul Bakker3338b792012-10-01 21:13:10 +00002027
Paul Bakker97872ac2012-11-02 12:53:26 +00002028 WIN32_FIND_DATAW file_data;
Paul Bakker8d914582012-06-04 12:46:42 +00002029 HANDLE hFind;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002030
2031 if( len > MAX_PATH - 3 )
2032 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker8d914582012-06-04 12:46:42 +00002033
Paul Bakker3338b792012-10-01 21:13:10 +00002034 memset( szDir, 0, sizeof(szDir) );
2035 memset( filename, 0, MAX_PATH );
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002036 memcpy( filename, path, len );
2037 filename[len++] = '\\';
2038 p = filename + len;
2039 filename[len++] = '*';
Paul Bakker3338b792012-10-01 21:13:10 +00002040
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002041 w_ret = MultiByteToWideChar( CP_ACP, 0, path, len, szDir, MAX_PATH - 3 );
Paul Bakker8d914582012-06-04 12:46:42 +00002042
Paul Bakker97872ac2012-11-02 12:53:26 +00002043 hFind = FindFirstFileW( szDir, &file_data );
Paul Bakker8d914582012-06-04 12:46:42 +00002044 if (hFind == INVALID_HANDLE_VALUE)
2045 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
2046
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002047 len = MAX_PATH - len;
Paul Bakker8d914582012-06-04 12:46:42 +00002048 do
2049 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002050 memset( p, 0, len );
Paul Bakker3338b792012-10-01 21:13:10 +00002051
Paul Bakkere4791f32012-06-04 21:29:15 +00002052 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
Paul Bakker8d914582012-06-04 12:46:42 +00002053 continue;
2054
Paul Bakker3338b792012-10-01 21:13:10 +00002055 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
2056 lstrlenW(file_data.cFileName),
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002057 p, len - 1,
2058 NULL, NULL );
Paul Bakker8d914582012-06-04 12:46:42 +00002059
Paul Bakker3338b792012-10-01 21:13:10 +00002060 w_ret = x509parse_crtfile( chain, filename );
2061 if( w_ret < 0 )
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002062 ret++;
2063 else
2064 ret += w_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00002065 }
Paul Bakker97872ac2012-11-02 12:53:26 +00002066 while( FindNextFileW( hFind, &file_data ) != 0 );
Paul Bakker8d914582012-06-04 12:46:42 +00002067
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002068 if (GetLastError() != ERROR_NO_MORE_FILES)
2069 ret = POLARSSL_ERR_X509_FILE_IO_ERROR;
Paul Bakker8d914582012-06-04 12:46:42 +00002070
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00002071cleanup:
Paul Bakker8d914582012-06-04 12:46:42 +00002072 FindClose( hFind );
2073#else
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002074 int t_ret, i;
2075 struct stat sb;
2076 struct dirent entry, *result = NULL;
Paul Bakker8d914582012-06-04 12:46:42 +00002077 char entry_name[255];
2078 DIR *dir = opendir( path );
2079
2080 if( dir == NULL)
2081 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
2082
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002083 while( ( t_ret = readdir_r( dir, &entry, &result ) ) == 0 )
Paul Bakker8d914582012-06-04 12:46:42 +00002084 {
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002085 if( result == NULL )
2086 break;
2087
2088 snprintf( entry_name, sizeof(entry_name), "%s/%s", path, entry.d_name );
2089
2090 i = stat( entry_name, &sb );
2091
2092 if( i == -1 )
2093 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
2094
2095 if( !S_ISREG( sb.st_mode ) )
Paul Bakker8d914582012-06-04 12:46:42 +00002096 continue;
2097
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002098 // Ignore parse errors
2099 //
Paul Bakker8d914582012-06-04 12:46:42 +00002100 t_ret = x509parse_crtfile( chain, entry_name );
2101 if( t_ret < 0 )
Paul Bakker2c8cdd22013-06-24 19:22:42 +02002102 ret++;
2103 else
2104 ret += t_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00002105 }
2106 closedir( dir );
2107#endif
2108
2109 return( ret );
2110}
2111
Paul Bakkerd98030e2009-05-02 15:13:40 +00002112/*
2113 * Load one or more CRLs and add them to the chained list
2114 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002115int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002116{
2117 int ret;
2118 size_t n;
2119 unsigned char *buf;
2120
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02002121 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00002122 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002123
Paul Bakker27fdf462011-06-09 13:55:13 +00002124 ret = x509parse_crl( chain, buf, n );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002125
2126 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02002127 polarssl_free( buf );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002128
2129 return( ret );
2130}
2131
Paul Bakker5121ce52009-01-03 21:22:43 +00002132/*
Paul Bakker335db3f2011-04-25 15:28:35 +00002133 * Load and parse a private RSA key
2134 */
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002135int x509parse_keyfile_rsa( rsa_context *rsa, const char *path, const char *pwd )
Paul Bakker335db3f2011-04-25 15:28:35 +00002136{
2137 int ret;
2138 size_t n;
2139 unsigned char *buf;
2140
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02002141 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00002142 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002143
2144 if( pwd == NULL )
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002145 ret = x509parse_key_rsa( rsa, buf, n, NULL, 0 );
Paul Bakker335db3f2011-04-25 15:28:35 +00002146 else
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002147 ret = x509parse_key_rsa( rsa, buf, n,
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02002148 (const unsigned char *) pwd, strlen( pwd ) );
Paul Bakker335db3f2011-04-25 15:28:35 +00002149
2150 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02002151 polarssl_free( buf );
Paul Bakker335db3f2011-04-25 15:28:35 +00002152
2153 return( ret );
2154}
2155
2156/*
2157 * Load and parse a public RSA key
2158 */
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002159int x509parse_public_keyfile_rsa( rsa_context *rsa, const char *path )
Paul Bakker335db3f2011-04-25 15:28:35 +00002160{
2161 int ret;
2162 size_t n;
2163 unsigned char *buf;
2164
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02002165 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00002166 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002167
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002168 ret = x509parse_public_key_rsa( rsa, buf, n );
Paul Bakker335db3f2011-04-25 15:28:35 +00002169
2170 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02002171 polarssl_free( buf );
Paul Bakker335db3f2011-04-25 15:28:35 +00002172
2173 return( ret );
2174}
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002175
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002176/*
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002177 * Load and parse a private key
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002178 */
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002179int x509parse_keyfile( pk_context *ctx,
2180 const char *path, const char *pwd )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002181{
2182 int ret;
2183 size_t n;
2184 unsigned char *buf;
2185
2186 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2187 return( ret );
2188
2189 if( pwd == NULL )
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002190 ret = x509parse_key( ctx, buf, n, NULL, 0 );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002191 else
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002192 ret = x509parse_key( ctx, buf, n,
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002193 (const unsigned char *) pwd, strlen( pwd ) );
2194
2195 memset( buf, 0, n + 1 );
2196 free( buf );
2197
2198 return( ret );
2199}
2200
2201/*
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002202 * Load and parse a public key
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002203 */
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002204int x509parse_public_keyfile( pk_context *ctx, const char *path )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002205{
2206 int ret;
2207 size_t n;
2208 unsigned char *buf;
2209
2210 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2211 return( ret );
2212
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002213 ret = x509parse_public_key( ctx, buf, n );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002214
2215 memset( buf, 0, n + 1 );
2216 free( buf );
2217
2218 return( ret );
2219}
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002220
Paul Bakker335db3f2011-04-25 15:28:35 +00002221#endif /* POLARSSL_FS_IO */
2222
2223/*
Paul Bakkere2f50402013-06-24 19:00:59 +02002224 * Parse a PKCS#1 encoded private RSA key
Paul Bakker5121ce52009-01-03 21:22:43 +00002225 */
Paul Bakkere2f50402013-06-24 19:00:59 +02002226static int x509parse_key_pkcs1_der( rsa_context *rsa,
2227 const unsigned char *key,
2228 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +00002229{
Paul Bakker23986e52011-04-24 08:57:21 +00002230 int ret;
2231 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00002232 unsigned char *p, *end;
Paul Bakkered56b222011-07-13 11:26:43 +00002233
Paul Bakker96743fc2011-02-12 14:30:57 +00002234 p = (unsigned char *) key;
Paul Bakker96743fc2011-02-12 14:30:57 +00002235 end = p + keylen;
2236
Paul Bakker5121ce52009-01-03 21:22:43 +00002237 /*
Paul Bakkere2f50402013-06-24 19:00:59 +02002238 * This function parses the RSAPrivateKey (PKCS#1)
Paul Bakkered56b222011-07-13 11:26:43 +00002239 *
Paul Bakker5121ce52009-01-03 21:22:43 +00002240 * RSAPrivateKey ::= SEQUENCE {
2241 * version Version,
2242 * modulus INTEGER, -- n
2243 * publicExponent INTEGER, -- e
2244 * privateExponent INTEGER, -- d
2245 * prime1 INTEGER, -- p
2246 * prime2 INTEGER, -- q
2247 * exponent1 INTEGER, -- d mod (p-1)
2248 * exponent2 INTEGER, -- d mod (q-1)
2249 * coefficient INTEGER, -- (inverse of q) mod p
2250 * otherPrimeInfos OtherPrimeInfos OPTIONAL
2251 * }
2252 */
2253 if( ( ret = asn1_get_tag( &p, end, &len,
2254 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2255 {
Paul Bakker9d781402011-05-09 16:17:09 +00002256 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002257 }
2258
2259 end = p + len;
2260
2261 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2262 {
Paul Bakker9d781402011-05-09 16:17:09 +00002263 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002264 }
2265
2266 if( rsa->ver != 0 )
2267 {
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002268 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00002269 }
2270
2271 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
2272 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
2273 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
2274 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
2275 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
2276 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
2277 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
2278 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
2279 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002280 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002281 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002282 }
2283
2284 rsa->len = mpi_size( &rsa->N );
2285
2286 if( p != end )
2287 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002288 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002289 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00002290 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002291 }
2292
2293 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2294 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002295 rsa_free( rsa );
2296 return( ret );
2297 }
2298
Paul Bakkere2f50402013-06-24 19:00:59 +02002299 return( 0 );
2300}
2301
2302/*
2303 * Parse an unencrypted PKCS#8 encoded private RSA key
2304 */
2305static int x509parse_key_pkcs8_unencrypted_der(
2306 rsa_context *rsa,
2307 const unsigned char *key,
2308 size_t keylen )
2309{
2310 int ret;
2311 size_t len;
2312 unsigned char *p, *end;
Manuel Pégourié-Gonnarda1555132013-07-10 13:18:41 +02002313 x509_buf alg_params;
Paul Bakkere2f50402013-06-24 19:00:59 +02002314 pk_type_t pk_alg = POLARSSL_PK_NONE;
2315
2316 p = (unsigned char *) key;
2317 end = p + keylen;
2318
2319 /*
2320 * This function parses the PrivatKeyInfo object (PKCS#8)
2321 *
2322 * PrivateKeyInfo ::= SEQUENCE {
2323 * version Version,
2324 * algorithm AlgorithmIdentifier,
2325 * PrivateKey BIT STRING
2326 * }
2327 *
2328 * AlgorithmIdentifier ::= SEQUENCE {
2329 * algorithm OBJECT IDENTIFIER,
2330 * parameters ANY DEFINED BY algorithm OPTIONAL
2331 * }
2332 *
2333 * The PrivateKey BIT STRING is a PKCS#1 RSAPrivateKey
2334 */
2335 if( ( ret = asn1_get_tag( &p, end, &len,
2336 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2337 {
2338 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2339 }
2340
2341 end = p + len;
2342
2343 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2344 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2345
2346 if( rsa->ver != 0 )
2347 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2348
Manuel Pégourié-Gonnarda1555132013-07-10 13:18:41 +02002349 if( ( ret = x509_get_pk_alg( &p, end, &pk_alg, &alg_params ) ) != 0 )
Paul Bakkere2f50402013-06-24 19:00:59 +02002350 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2351
2352 /*
Manuel Pégourié-Gonnarda1555132013-07-10 13:18:41 +02002353 * We explicitly want RSA keys only
Paul Bakkere2f50402013-06-24 19:00:59 +02002354 */
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002355 if (pk_alg != POLARSSL_PK_RSA )
2356 return( POLARSSL_ERR_X509_CERT_INVALID_ALG );
2357
Paul Bakkere2f50402013-06-24 19:00:59 +02002358 /*
2359 * Get the OCTET STRING and parse the PKCS#1 format inside
2360 */
2361 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2362 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2363
2364 if( ( end - p ) < 1 )
2365 {
2366 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
2367 POLARSSL_ERR_ASN1_OUT_OF_DATA );
2368 }
2369
2370 end = p + len;
2371
2372 if( ( ret = x509parse_key_pkcs1_der( rsa, p, end - p ) ) != 0 )
2373 return( ret );
2374
2375 return( 0 );
2376}
2377
2378/*
Manuel Pégourié-Gonnarda5d99742013-07-04 11:08:31 +02002379 * Decrypt the content of a PKCS#8 EncryptedPrivateKeyInfo
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002380 */
Manuel Pégourié-Gonnarda5d99742013-07-04 11:08:31 +02002381static int x509parse_pkcs8_decrypt( unsigned char *buf, size_t buflen,
2382 size_t *used_len,
2383 const unsigned char *key, size_t keylen,
2384 const unsigned char *pwd, size_t pwdlen )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002385{
2386 int ret;
2387 size_t len;
Paul Bakkerf8d018a2013-06-29 12:16:17 +02002388 unsigned char *p, *end;
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002389 x509_buf pbe_alg_oid, pbe_params;
Paul Bakker7749a222013-06-28 17:28:20 +02002390#if defined(POLARSSL_PKCS12_C)
2391 cipher_type_t cipher_alg;
2392 md_type_t md_alg;
2393#endif
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002394
Manuel Pégourié-Gonnarda5d99742013-07-04 11:08:31 +02002395 memset(buf, 0, buflen);
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002396
2397 p = (unsigned char *) key;
2398 end = p + keylen;
2399
Paul Bakker28144de2013-06-24 19:28:55 +02002400 if( pwdlen == 0 )
2401 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
2402
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002403 /*
2404 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
2405 *
2406 * EncryptedPrivateKeyInfo ::= SEQUENCE {
2407 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
2408 * encryptedData EncryptedData
2409 * }
2410 *
2411 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
2412 *
2413 * EncryptedData ::= OCTET STRING
2414 *
2415 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
2416 */
2417 if( ( ret = asn1_get_tag( &p, end, &len,
2418 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2419 {
2420 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2421 }
2422
2423 end = p + len;
2424
Paul Bakkerf8d018a2013-06-29 12:16:17 +02002425 if( ( ret = asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002426 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002427
2428 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2429 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2430
Manuel Pégourié-Gonnarda5d99742013-07-04 11:08:31 +02002431 if( len > buflen )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002432 return( POLARSSL_ERR_X509_INVALID_INPUT );
2433
2434 /*
2435 * Decrypt EncryptedData with appropriate PDE
2436 */
Paul Bakker38b50d72013-06-24 19:33:27 +02002437#if defined(POLARSSL_PKCS12_C)
Paul Bakker7749a222013-06-28 17:28:20 +02002438 if( oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002439 {
Paul Bakker38b50d72013-06-24 19:33:27 +02002440 if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
Paul Bakker7749a222013-06-28 17:28:20 +02002441 cipher_alg, md_alg,
Paul Bakker38b50d72013-06-24 19:33:27 +02002442 pwd, pwdlen, p, len, buf ) ) != 0 )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002443 {
Paul Bakker38b50d72013-06-24 19:33:27 +02002444 if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH )
2445 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2446
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002447 return( ret );
2448 }
2449 }
2450 else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) )
2451 {
2452 if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params,
2453 PKCS12_PBE_DECRYPT,
2454 pwd, pwdlen,
2455 p, len, buf ) ) != 0 )
2456 {
2457 return( ret );
2458 }
Paul Bakker38b50d72013-06-24 19:33:27 +02002459
2460 // Best guess for password mismatch when using RC4. If first tag is
2461 // not ASN1_CONSTRUCTED | ASN1_SEQUENCE
2462 //
2463 if( *buf != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
2464 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002465 }
Paul Bakker38b50d72013-06-24 19:33:27 +02002466 else
2467#endif /* POLARSSL_PKCS12_C */
Paul Bakker28144de2013-06-24 19:28:55 +02002468#if defined(POLARSSL_PKCS5_C)
Paul Bakker38b50d72013-06-24 19:33:27 +02002469 if( OID_CMP( OID_PKCS5_PBES2, &pbe_alg_oid ) )
Paul Bakker28144de2013-06-24 19:28:55 +02002470 {
2471 if( ( ret = pkcs5_pbes2( &pbe_params, PKCS5_DECRYPT, pwd, pwdlen,
2472 p, len, buf ) ) != 0 )
2473 {
2474 if( ret == POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH )
2475 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2476
2477 return( ret );
2478 }
2479 }
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002480 else
Paul Bakker38b50d72013-06-24 19:33:27 +02002481#endif /* POLARSSL_PKCS5_C */
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002482 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
2483
Manuel Pégourié-Gonnarda5d99742013-07-04 11:08:31 +02002484 *used_len = len;
2485 return( 0 );
2486}
2487
2488/*
2489 * Parse an encrypted PKCS#8 encoded private RSA key
2490 */
2491static int x509parse_key_pkcs8_encrypted_der(
2492 rsa_context *rsa,
2493 const unsigned char *key, size_t keylen,
2494 const unsigned char *pwd, size_t pwdlen )
2495{
2496 int ret;
2497 unsigned char buf[2048];
2498 size_t len = 0;
2499
2500 if( ( ret = x509parse_pkcs8_decrypt( buf, sizeof( buf ), &len,
2501 key, keylen, pwd, pwdlen ) ) != 0 )
2502 {
2503 return( ret );
2504 }
2505
2506 return( x509parse_key_pkcs8_unencrypted_der( rsa, buf, len ) );
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002507}
2508
2509/*
Paul Bakkere2f50402013-06-24 19:00:59 +02002510 * Parse a private RSA key
2511 */
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002512int x509parse_key_rsa( rsa_context *rsa,
2513 const unsigned char *key, size_t keylen,
2514 const unsigned char *pwd, size_t pwdlen )
Paul Bakkere2f50402013-06-24 19:00:59 +02002515{
2516 int ret;
2517
Paul Bakker96743fc2011-02-12 14:30:57 +00002518#if defined(POLARSSL_PEM_C)
Paul Bakkere2f50402013-06-24 19:00:59 +02002519 size_t len;
2520 pem_context pem;
2521
2522 pem_init( &pem );
2523 ret = pem_read_buffer( &pem,
2524 "-----BEGIN RSA PRIVATE KEY-----",
2525 "-----END RSA PRIVATE KEY-----",
2526 key, pwd, pwdlen, &len );
2527 if( ret == 0 )
2528 {
2529 if( ( ret = x509parse_key_pkcs1_der( rsa, pem.buf, pem.buflen ) ) != 0 )
2530 {
2531 rsa_free( rsa );
2532 }
2533
2534 pem_free( &pem );
2535 return( ret );
2536 }
Paul Bakkera4232a72013-06-24 19:32:25 +02002537 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
2538 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2539 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
2540 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
Paul Bakkere2f50402013-06-24 19:00:59 +02002541 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkere2f50402013-06-24 19:00:59 +02002542 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002543
2544 ret = pem_read_buffer( &pem,
2545 "-----BEGIN PRIVATE KEY-----",
2546 "-----END PRIVATE KEY-----",
2547 key, NULL, 0, &len );
2548 if( ret == 0 )
2549 {
2550 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa,
2551 pem.buf, pem.buflen ) ) != 0 )
2552 {
2553 rsa_free( rsa );
2554 }
2555
2556 pem_free( &pem );
2557 return( ret );
2558 }
2559 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkere2f50402013-06-24 19:00:59 +02002560 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002561
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002562 ret = pem_read_buffer( &pem,
2563 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
2564 "-----END ENCRYPTED PRIVATE KEY-----",
2565 key, NULL, 0, &len );
2566 if( ret == 0 )
2567 {
2568 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa,
2569 pem.buf, pem.buflen,
2570 pwd, pwdlen ) ) != 0 )
2571 {
2572 rsa_free( rsa );
2573 }
2574
2575 pem_free( &pem );
2576 return( ret );
2577 }
2578 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002579 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002580#else
2581 ((void) pwd);
2582 ((void) pwdlen);
2583#endif /* POLARSSL_PEM_C */
2584
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002585 /*
2586 * At this point we only know it's not a PEM formatted key. Could be any
2587 * of the known DER encoded private key formats
2588 *
2589 * We try the different DER format parsers to see if one passes without
2590 * error
2591 */
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002592 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa, key, keylen,
2593 pwd, pwdlen ) ) == 0 )
Paul Bakkere2f50402013-06-24 19:00:59 +02002594 {
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002595 return( 0 );
Paul Bakkere2f50402013-06-24 19:00:59 +02002596 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002597
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002598 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002599
2600 if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH )
2601 {
2602 return( ret );
2603 }
2604
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002605 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa, key, keylen ) ) == 0 )
2606 return( 0 );
2607
2608 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002609
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002610 if( ( ret = x509parse_key_pkcs1_der( rsa, key, keylen ) ) == 0 )
2611 return( 0 );
2612
2613 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002614
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002615 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00002616}
2617
2618/*
Paul Bakker53019ae2011-03-25 13:58:48 +00002619 * Parse a public RSA key
2620 */
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002621int x509parse_public_key_rsa( rsa_context *rsa,
2622 const unsigned char *key, size_t keylen )
Paul Bakker53019ae2011-03-25 13:58:48 +00002623{
Manuel Pégourié-Gonnard244569f2013-07-10 09:46:30 +02002624 pk_context pk_ctx;
Paul Bakker53019ae2011-03-25 13:58:48 +00002625
Manuel Pégourié-Gonnard244569f2013-07-10 09:46:30 +02002626 pk_init( &pk_ctx );
2627 pk_wrap_rsa( &pk_ctx, rsa );
Paul Bakker53019ae2011-03-25 13:58:48 +00002628
Manuel Pégourié-Gonnard244569f2013-07-10 09:46:30 +02002629 return( x509parse_public_key( &pk_ctx, key, keylen ) );
Paul Bakker53019ae2011-03-25 13:58:48 +00002630}
2631
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002632#if defined(POLARSSL_ECP_C)
2633/*
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002634 * Parse a SEC1 encoded private EC key
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002635 */
2636static int x509parse_key_sec1_der( ecp_keypair *eck,
2637 const unsigned char *key,
2638 size_t keylen )
2639{
2640 int ret;
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002641 int version;
2642 size_t len;
2643 ecp_group_id grp_id;
2644 unsigned char *p = (unsigned char *) key;
2645 unsigned char *end = p + keylen;
Manuel Pégourié-Gonnard5b18fb02013-07-10 16:07:25 +02002646 unsigned char *end2;
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002647
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002648 /*
2649 * RFC 5915, orf SEC1 Appendix C.4
2650 *
2651 * ECPrivateKey ::= SEQUENCE {
2652 * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
2653 * privateKey OCTET STRING,
2654 * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
2655 * publicKey [1] BIT STRING OPTIONAL
2656 * }
2657 */
2658 if( ( ret = asn1_get_tag( &p, end, &len,
2659 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2660 {
2661 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2662 }
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002663
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002664 end = p + len;
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002665
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002666 if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 )
2667 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002668
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002669 if( version != 1 )
2670 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION );
2671
2672 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2673 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2674
2675 if( ( ret = mpi_read_binary( &eck->d, p, len ) ) != 0 )
2676 {
2677 ecp_keypair_free( eck );
2678 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2679 }
2680
2681 p += len;
2682
2683 /*
2684 * Is 'parameters' present?
2685 */
2686 if( ( ret = asn1_get_tag( &p, end, &len,
2687 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) == 0 )
2688 {
2689 if( ( ret = x509_get_ecparams( &p, p + len, &grp_id) ) != 0 )
2690 return( ret );
2691
Manuel Pégourié-Gonnardd4ec21d2013-07-04 12:04:57 +02002692 /*
2693 * If we're wrapped in a bigger structure (eg PKCS#8), grp may have been
2694 * defined externally. In this case, make sure both definitions match.
2695 */
2696 if( eck->grp.id != 0 )
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002697 {
Manuel Pégourié-Gonnardd4ec21d2013-07-04 12:04:57 +02002698 if( eck->grp.id != grp_id )
2699 {
2700 ecp_keypair_free( eck );
2701 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2702 }
2703 }
2704 else
2705 {
2706 if( ( ret = ecp_use_known_dp( &eck->grp, grp_id ) ) != 0 )
2707 {
2708 ecp_keypair_free( eck );
2709 return( ret );
2710 }
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002711 }
2712 }
2713 else if ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
2714 {
2715 ecp_keypair_free( eck );
2716 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2717 }
2718
2719 /*
2720 * Is 'publickey' present?
2721 */
2722 if( ( ret = asn1_get_tag( &p, end, &len,
2723 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 )
2724 {
Manuel Pégourié-Gonnard5b18fb02013-07-10 16:07:25 +02002725 end2 = p + len;
2726
2727 if( ( ret = x509_get_subpubkey_ec( &p, end2, &eck->grp, &eck->Q ) )
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002728 != 0 )
2729 {
2730 ecp_keypair_free( eck );
2731 return( ret );
2732 }
2733
Manuel Pégourié-Gonnard5b18fb02013-07-10 16:07:25 +02002734 if( p != end2 )
2735 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
2736 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002737 }
2738 else if ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
2739 {
2740 ecp_keypair_free( eck );
2741 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2742 }
2743
Manuel Pégourié-Gonnardde44a4a2013-07-09 16:05:52 +02002744 if( ( ret = ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 )
Manuel Pégourié-Gonnarde3663422013-07-03 18:56:37 +02002745 {
2746 ecp_keypair_free( eck );
2747 return( ret );
2748 }
2749
2750 return 0;
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002751}
2752
2753/*
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002754 * Parse an unencrypted PKCS#8 encoded private EC key
2755 */
2756static int x509parse_key_pkcs8_unencrypted_der_ec(
2757 ecp_keypair *eck,
2758 const unsigned char* key,
2759 size_t keylen )
2760{
2761 int ret, version;
2762 size_t len;
Manuel Pégourié-Gonnard0a64e8f2013-07-08 18:26:18 +02002763 x509_buf alg_params;
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002764 ecp_group_id grp_id;
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002765 unsigned char *p = (unsigned char *) key;
2766 unsigned char *end = p + keylen;
2767 pk_type_t pk_alg = POLARSSL_PK_NONE;
2768
2769 /*
2770 * This function parses the PrivatKeyInfo object (PKCS#8 v1.2 = RFC 5208)
2771 *
2772 * PrivateKeyInfo ::= SEQUENCE {
2773 * version Version,
2774 * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
2775 * privateKey PrivateKey,
2776 * attributes [0] IMPLICIT Attributes OPTIONAL }
2777 *
2778 * Version ::= INTEGER
2779 * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
2780 * PrivateKey ::= OCTET STRING
2781 *
2782 * The PrivateKey OCTET STRING is a SEC1 ECPrivateKey
2783 */
2784
2785 if( ( ret = asn1_get_tag( &p, end, &len,
2786 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2787 {
2788 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2789 }
2790
2791 end = p + len;
2792
2793 if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 )
2794 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2795
2796 if( version != 0 )
2797 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2798
Manuel Pégourié-Gonnard7a287c42013-07-10 12:55:08 +02002799 if( ( ret = x509_get_pk_alg( &p, end, &pk_alg, &alg_params ) ) != 0 )
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002800 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2801
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002802 if( pk_alg != POLARSSL_PK_ECKEY && pk_alg != POLARSSL_PK_ECKEY_DH )
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002803 return( POLARSSL_ERR_X509_CERT_INVALID_ALG );
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002804
2805 if( pk_alg == POLARSSL_PK_ECKEY_DH )
2806 eck->alg = POLARSSL_ECP_KEY_ALG_ECDH;
2807
Manuel Pégourié-Gonnard0a64e8f2013-07-08 18:26:18 +02002808 if( ( ret = x509_ecparams_get_grp_id( &alg_params, &grp_id ) ) != 0 )
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002809 {
2810 ecp_keypair_free( eck );
2811 return( ret );
2812 }
2813
2814 if( ( ret = ecp_use_known_dp( &eck->grp, grp_id ) ) != 0 )
2815 {
2816 ecp_keypair_free( eck );
2817 return( ret );
2818 }
2819
2820 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2821 {
2822 ecp_keypair_free( eck );
2823 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2824 }
2825
2826 if( ( ret = x509parse_key_sec1_der( eck, p, len ) ) != 0 )
2827 {
2828 ecp_keypair_free( eck );
2829 return( ret );
2830 }
2831
Manuel Pégourié-Gonnardde44a4a2013-07-09 16:05:52 +02002832 if( ( ret = ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 )
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002833 {
2834 ecp_keypair_free( eck );
2835 return( ret );
2836 }
2837
2838 return 0;
2839}
2840
2841/*
2842 * Parse an encrypted PKCS#8 encoded private EC key
2843 */
2844static int x509parse_key_pkcs8_encrypted_der_ec(
2845 ecp_keypair *eck,
Manuel Pégourié-Gonnard9c1cf452013-07-04 11:20:24 +02002846 const unsigned char *key, size_t keylen,
2847 const unsigned char *pwd, size_t pwdlen )
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002848{
2849 int ret;
Manuel Pégourié-Gonnard9c1cf452013-07-04 11:20:24 +02002850 unsigned char buf[2048];
2851 size_t len = 0;
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002852
Manuel Pégourié-Gonnard9c1cf452013-07-04 11:20:24 +02002853 if( ( ret = x509parse_pkcs8_decrypt( buf, sizeof( buf ), &len,
2854 key, keylen, pwd, pwdlen ) ) != 0 )
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002855 {
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002856 return( ret );
2857 }
2858
Manuel Pégourié-Gonnard9c1cf452013-07-04 11:20:24 +02002859 return( x509parse_key_pkcs8_unencrypted_der_ec( eck, buf, len ) );
Manuel Pégourié-Gonnard416fa8f2013-07-04 10:46:23 +02002860}
2861
2862/*
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002863 * Parse a private EC key
2864 */
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002865static int x509parse_key_ec( ecp_keypair *eck,
2866 const unsigned char *key, size_t keylen,
2867 const unsigned char *pwd, size_t pwdlen )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002868{
2869 int ret;
2870
2871#if defined(POLARSSL_PEM_C)
2872 size_t len;
2873 pem_context pem;
2874
2875 pem_init( &pem );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002876 ret = pem_read_buffer( &pem,
2877 "-----BEGIN EC PRIVATE KEY-----",
2878 "-----END EC PRIVATE KEY-----",
2879 key, pwd, pwdlen, &len );
2880 if( ret == 0 )
2881 {
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002882 if( ( ret = x509parse_key_sec1_der( eck, pem.buf, pem.buflen ) ) != 0 )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002883 {
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002884 ecp_keypair_free( eck );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002885 }
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002886
2887 pem_free( &pem );
2888 return( ret );
2889 }
2890 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
2891 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2892 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
2893 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
2894 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2895 return( ret );
2896
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002897 ret = pem_read_buffer( &pem,
2898 "-----BEGIN PRIVATE KEY-----",
2899 "-----END PRIVATE KEY-----",
2900 key, NULL, 0, &len );
2901 if( ret == 0 )
2902 {
2903 if( ( ret = x509parse_key_pkcs8_unencrypted_der_ec( eck,
2904 pem.buf, pem.buflen ) ) != 0 )
2905 {
2906 ecp_keypair_free( eck );
2907 }
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002908
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002909 pem_free( &pem );
2910 return( ret );
2911 }
2912 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2913 return( ret );
2914
2915 ret = pem_read_buffer( &pem,
2916 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
2917 "-----END ENCRYPTED PRIVATE KEY-----",
2918 key, NULL, 0, &len );
2919 if( ret == 0 )
2920 {
2921 if( ( ret = x509parse_key_pkcs8_encrypted_der_ec( eck,
2922 pem.buf, pem.buflen,
2923 pwd, pwdlen ) ) != 0 )
2924 {
2925 ecp_keypair_free( eck );
2926 }
2927
2928 pem_free( &pem );
2929 return( ret );
2930 }
2931 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2932 return( ret );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002933#else
2934 ((void) pwd);
2935 ((void) pwdlen);
2936#endif /* POLARSSL_PEM_C */
2937
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002938 /*
2939 * At this point we only know it's not a PEM formatted key. Could be any
2940 * of the known DER encoded private key formats
2941 *
2942 * We try the different DER format parsers to see if one passes without
2943 * error
2944 */
2945 if( ( ret = x509parse_key_pkcs8_encrypted_der_ec( eck, key, keylen,
2946 pwd, pwdlen ) ) == 0 )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002947 {
2948 return( 0 );
2949 }
2950
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002951 ecp_keypair_free( eck );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002952
2953 if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH )
2954 {
2955 return( ret );
2956 }
2957
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002958 if( ( ret = x509parse_key_pkcs8_unencrypted_der_ec( eck,
2959 key, keylen ) ) == 0 )
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002960 return( 0 );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002961
Manuel Pégourié-Gonnard15e8b822013-07-03 11:56:37 +02002962 ecp_keypair_free( eck );
2963
2964 if( ( ret = x509parse_key_sec1_der( eck, key, keylen ) ) == 0 )
2965 return( 0 );
2966
2967 ecp_keypair_free( eck );
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002968
2969 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
2970}
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002971#endif /* defined(POLARSSL_ECP_C) */
2972
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002973/*
2974 * Parse a private key
2975 */
2976int x509parse_key( pk_context *ctx,
2977 const unsigned char *key, size_t keylen,
2978 const unsigned char *pwd, size_t pwdlen )
2979{
2980 int ret;
2981
2982 if ( ( ret = pk_set_type( ctx, POLARSSL_PK_RSA ) ) != 0 )
2983 return( ret );
2984
2985 if( ( ret = x509parse_key_rsa( ctx->data, key, keylen, pwd, pwdlen ) )
2986 == 0 )
2987 {
2988 return( 0 );
2989 }
2990
Manuel Pégourié-Gonnard374e4b82013-07-09 10:21:34 +02002991 pk_free( ctx );
2992
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02002993 if ( ( ret = pk_set_type( ctx, POLARSSL_PK_ECKEY ) ) != 0 )
2994 return( ret );
2995
2996 if( ( ret = x509parse_key_ec( ctx->data, key, keylen, pwd, pwdlen ) ) == 0 )
2997 {
2998 return( 0 );
2999 }
3000
Manuel Pégourié-Gonnard374e4b82013-07-09 10:21:34 +02003001 pk_free( ctx );
3002
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02003003 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
3004}
3005
3006/*
3007 * Parse a public key
3008 */
3009int x509parse_public_key( pk_context *ctx,
3010 const unsigned char *key, size_t keylen )
3011{
3012 int ret;
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +02003013 unsigned char *p;
3014#if defined(POLARSSL_PEM_C)
3015 size_t len;
3016 pem_context pem;
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02003017
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +02003018 pem_init( &pem );
3019 ret = pem_read_buffer( &pem,
3020 "-----BEGIN PUBLIC KEY-----",
3021 "-----END PUBLIC KEY-----",
3022 key, NULL, 0, &len );
3023
3024 if( ret == 0 )
3025 {
3026 /*
3027 * Was PEM encoded
3028 */
3029 key = pem.buf;
3030 keylen = pem.buflen;
3031 }
3032 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
3033 {
3034 pem_free( &pem );
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02003035 return( ret );
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +02003036 }
3037#endif
3038 p = (unsigned char *) key;
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02003039
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +02003040 ret = x509_get_pubkey( &p, p + keylen, ctx );
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02003041
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +02003042#if defined(POLARSSL_PEM_C)
3043 pem_free( &pem );
3044#endif
Manuel Pégourié-Gonnard374e4b82013-07-09 10:21:34 +02003045
Manuel Pégourié-Gonnard4fa04762013-07-09 13:10:49 +02003046 return( ret );
Manuel Pégourié-Gonnard88380992013-07-04 14:09:57 +02003047}
3048
Paul Bakkereaa89f82011-04-04 21:36:15 +00003049#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00003050/*
Paul Bakker1b57b062011-01-06 15:48:19 +00003051 * Parse DHM parameters
3052 */
Paul Bakker23986e52011-04-24 08:57:21 +00003053int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
Paul Bakker1b57b062011-01-06 15:48:19 +00003054{
Paul Bakker23986e52011-04-24 08:57:21 +00003055 int ret;
3056 size_t len;
Paul Bakker1b57b062011-01-06 15:48:19 +00003057 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00003058#if defined(POLARSSL_PEM_C)
3059 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00003060
Paul Bakker96743fc2011-02-12 14:30:57 +00003061 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00003062
Paul Bakker96743fc2011-02-12 14:30:57 +00003063 ret = pem_read_buffer( &pem,
3064 "-----BEGIN DH PARAMETERS-----",
3065 "-----END DH PARAMETERS-----",
3066 dhmin, NULL, 0, &dhminlen );
3067
3068 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003069 {
Paul Bakker96743fc2011-02-12 14:30:57 +00003070 /*
3071 * Was PEM encoded
3072 */
3073 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00003074 }
Paul Bakker00b28602013-06-24 13:02:41 +02003075 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00003076 {
Paul Bakker96743fc2011-02-12 14:30:57 +00003077 pem_free( &pem );
3078 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00003079 }
3080
Paul Bakker96743fc2011-02-12 14:30:57 +00003081 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
3082#else
3083 p = (unsigned char *) dhmin;
3084#endif
3085 end = p + dhminlen;
3086
Paul Bakker1b57b062011-01-06 15:48:19 +00003087 memset( dhm, 0, sizeof( dhm_context ) );
3088
Paul Bakker1b57b062011-01-06 15:48:19 +00003089 /*
3090 * DHParams ::= SEQUENCE {
3091 * prime INTEGER, -- P
3092 * generator INTEGER, -- g
3093 * }
3094 */
3095 if( ( ret = asn1_get_tag( &p, end, &len,
3096 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
3097 {
Paul Bakker96743fc2011-02-12 14:30:57 +00003098#if defined(POLARSSL_PEM_C)
3099 pem_free( &pem );
3100#endif
Paul Bakker9d781402011-05-09 16:17:09 +00003101 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00003102 }
3103
3104 end = p + len;
3105
3106 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
3107 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
3108 {
Paul Bakker96743fc2011-02-12 14:30:57 +00003109#if defined(POLARSSL_PEM_C)
3110 pem_free( &pem );
3111#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00003112 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00003113 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00003114 }
3115
3116 if( p != end )
3117 {
Paul Bakker96743fc2011-02-12 14:30:57 +00003118#if defined(POLARSSL_PEM_C)
3119 pem_free( &pem );
3120#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00003121 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00003122 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker1b57b062011-01-06 15:48:19 +00003123 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
3124 }
3125
Paul Bakker96743fc2011-02-12 14:30:57 +00003126#if defined(POLARSSL_PEM_C)
3127 pem_free( &pem );
3128#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00003129
3130 return( 0 );
3131}
3132
Paul Bakker335db3f2011-04-25 15:28:35 +00003133#if defined(POLARSSL_FS_IO)
Paul Bakker1b57b062011-01-06 15:48:19 +00003134/*
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02003135 * Load and parse DHM parameters
Paul Bakker1b57b062011-01-06 15:48:19 +00003136 */
3137int x509parse_dhmfile( dhm_context *dhm, const char *path )
3138{
3139 int ret;
3140 size_t n;
3141 unsigned char *buf;
3142
Paul Bakker69e095c2011-12-10 21:55:01 +00003143 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
3144 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00003145
Paul Bakker27fdf462011-06-09 13:55:13 +00003146 ret = x509parse_dhm( dhm, buf, n );
Paul Bakker1b57b062011-01-06 15:48:19 +00003147
3148 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02003149 polarssl_free( buf );
Paul Bakker1b57b062011-01-06 15:48:19 +00003150
3151 return( ret );
3152}
Paul Bakker335db3f2011-04-25 15:28:35 +00003153#endif /* POLARSSL_FS_IO */
Paul Bakkereaa89f82011-04-04 21:36:15 +00003154#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00003155
Paul Bakker5121ce52009-01-03 21:22:43 +00003156#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00003157#include <stdarg.h>
3158
3159#if !defined vsnprintf
3160#define vsnprintf _vsnprintf
3161#endif // vsnprintf
3162
3163/*
3164 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
3165 * Result value is not size of buffer needed, but -1 if no fit is possible.
3166 *
3167 * This fuction tries to 'fix' this by at least suggesting enlarging the
3168 * size by 20.
3169 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02003170static int compat_snprintf(char *str, size_t size, const char *format, ...)
Paul Bakkerd98030e2009-05-02 15:13:40 +00003171{
3172 va_list ap;
3173 int res = -1;
3174
3175 va_start( ap, format );
3176
3177 res = vsnprintf( str, size, format, ap );
3178
3179 va_end( ap );
3180
3181 // No quick fix possible
3182 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00003183 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003184
3185 return res;
3186}
3187
3188#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00003189#endif
3190
Paul Bakkerd98030e2009-05-02 15:13:40 +00003191#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
3192
3193#define SAFE_SNPRINTF() \
3194{ \
3195 if( ret == -1 ) \
3196 return( -1 ); \
3197 \
Paul Bakker23986e52011-04-24 08:57:21 +00003198 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00003199 p[n - 1] = '\0'; \
3200 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
3201 } \
3202 \
Paul Bakker23986e52011-04-24 08:57:21 +00003203 n -= (unsigned int) ret; \
3204 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00003205}
3206
Paul Bakker5121ce52009-01-03 21:22:43 +00003207/*
3208 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00003209 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00003210 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003211int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00003212{
Paul Bakker23986e52011-04-24 08:57:21 +00003213 int ret;
3214 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00003215 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00003216 const x509_name *name;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003217 const char *short_name = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003218 char s[128], *p;
3219
3220 memset( s, 0, sizeof( s ) );
3221
3222 name = dn;
3223 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003224 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00003225
3226 while( name != NULL )
3227 {
Paul Bakkercefb3962012-06-27 11:51:09 +00003228 if( !name->oid.p )
3229 {
3230 name = name->next;
3231 continue;
3232 }
3233
Paul Bakker74111d32011-01-15 16:57:55 +00003234 if( name != dn )
3235 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00003236 ret = snprintf( p, n, ", " );
3237 SAFE_SNPRINTF();
3238 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003239
Paul Bakkerc70b9822013-04-07 22:00:46 +02003240 ret = oid_get_attr_short_name( &name->oid, &short_name );
Paul Bakker5121ce52009-01-03 21:22:43 +00003241
Paul Bakkerc70b9822013-04-07 22:00:46 +02003242 if( ret == 0 )
3243 ret = snprintf( p, n, "%s=", short_name );
Paul Bakker5121ce52009-01-03 21:22:43 +00003244 else
Paul Bakkerd98030e2009-05-02 15:13:40 +00003245 ret = snprintf( p, n, "\?\?=" );
Paul Bakkerc70b9822013-04-07 22:00:46 +02003246 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003247
3248 for( i = 0; i < name->val.len; i++ )
3249 {
Paul Bakker27fdf462011-06-09 13:55:13 +00003250 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003251 break;
3252
3253 c = name->val.p[i];
3254 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
3255 s[i] = '?';
3256 else s[i] = c;
3257 }
3258 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00003259 ret = snprintf( p, n, "%s", s );
Paul Bakkerc70b9822013-04-07 22:00:46 +02003260 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003261 name = name->next;
3262 }
3263
Paul Bakker23986e52011-04-24 08:57:21 +00003264 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003265}
3266
3267/*
Paul Bakkerdd476992011-01-16 21:34:59 +00003268 * Store the serial in printable form into buf; no more
3269 * than size characters will be written
3270 */
3271int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
3272{
Paul Bakker23986e52011-04-24 08:57:21 +00003273 int ret;
3274 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00003275 char *p;
3276
3277 p = buf;
3278 n = size;
3279
3280 nr = ( serial->len <= 32 )
Paul Bakker03c7c252011-11-25 12:37:37 +00003281 ? serial->len : 28;
Paul Bakkerdd476992011-01-16 21:34:59 +00003282
3283 for( i = 0; i < nr; i++ )
3284 {
Paul Bakker93048802011-12-05 14:38:06 +00003285 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003286 continue;
3287
Paul Bakkerdd476992011-01-16 21:34:59 +00003288 ret = snprintf( p, n, "%02X%s",
3289 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
3290 SAFE_SNPRINTF();
3291 }
3292
Paul Bakker03c7c252011-11-25 12:37:37 +00003293 if( nr != serial->len )
3294 {
3295 ret = snprintf( p, n, "...." );
3296 SAFE_SNPRINTF();
3297 }
3298
Paul Bakker23986e52011-04-24 08:57:21 +00003299 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00003300}
3301
3302/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00003303 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00003304 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003305int x509parse_cert_info( char *buf, size_t size, const char *prefix,
3306 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00003307{
Paul Bakker23986e52011-04-24 08:57:21 +00003308 int ret;
3309 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003310 char *p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003311 const char *desc = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003312
3313 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003314 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00003315
Paul Bakkerd98030e2009-05-02 15:13:40 +00003316 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00003317 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003318 SAFE_SNPRINTF();
3319 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00003320 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003321 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003322
Paul Bakkerdd476992011-01-16 21:34:59 +00003323 ret = x509parse_serial_gets( p, n, &crt->serial);
3324 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003325
Paul Bakkerd98030e2009-05-02 15:13:40 +00003326 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
3327 SAFE_SNPRINTF();
3328 ret = x509parse_dn_gets( p, n, &crt->issuer );
3329 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003330
Paul Bakkerd98030e2009-05-02 15:13:40 +00003331 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
3332 SAFE_SNPRINTF();
3333 ret = x509parse_dn_gets( p, n, &crt->subject );
3334 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003335
Paul Bakkerd98030e2009-05-02 15:13:40 +00003336 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00003337 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3338 crt->valid_from.year, crt->valid_from.mon,
3339 crt->valid_from.day, crt->valid_from.hour,
3340 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003341 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003342
Paul Bakkerd98030e2009-05-02 15:13:40 +00003343 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00003344 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3345 crt->valid_to.year, crt->valid_to.mon,
3346 crt->valid_to.day, crt->valid_to.hour,
3347 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003348 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003349
Paul Bakkerc70b9822013-04-07 22:00:46 +02003350 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003351 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003352
Paul Bakkerc70b9822013-04-07 22:00:46 +02003353 ret = oid_get_sig_alg_desc( &crt->sig_oid1, &desc );
3354 if( ret != 0 )
3355 ret = snprintf( p, n, "???" );
3356 else
3357 ret = snprintf( p, n, desc );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003358 SAFE_SNPRINTF();
3359
Manuel Pégourié-Gonnard360a5832013-07-10 14:56:36 +02003360 switch( crt->pk.type )
3361 {
3362 case POLARSSL_PK_NONE:
3363 case POLARSSL_PK_ECDSA:
3364 ret = snprintf(p, n, "\n%sPK type looks wrong!", prefix);
3365 break;
3366
3367 case POLARSSL_PK_RSA:
3368 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
3369 (int) pk_rsa( crt->pk )->N.n * (int) sizeof( t_uint ) * 8 );
3370 break;
3371
3372 case POLARSSL_PK_ECKEY:
3373 case POLARSSL_PK_ECKEY_DH:
3374 ret = snprintf( p, n, "\n%sEC key size : %d bits\n", prefix,
3375 (int) pk_ec( crt->pk )->grp.pbits );
3376 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00003377 SAFE_SNPRINTF();
3378
Paul Bakker23986e52011-04-24 08:57:21 +00003379 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003380}
3381
Paul Bakker74111d32011-01-15 16:57:55 +00003382/*
3383 * Return an informational string describing the given OID
3384 */
3385const char *x509_oid_get_description( x509_buf *oid )
3386{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003387 const char *desc = NULL;
3388 int ret;
Paul Bakker74111d32011-01-15 16:57:55 +00003389
Paul Bakkerc70b9822013-04-07 22:00:46 +02003390 ret = oid_get_extended_key_usage( oid, &desc );
Paul Bakker74111d32011-01-15 16:57:55 +00003391
Paul Bakkerc70b9822013-04-07 22:00:46 +02003392 if( ret != 0 )
3393 return( NULL );
Paul Bakker74111d32011-01-15 16:57:55 +00003394
Paul Bakkerc70b9822013-04-07 22:00:46 +02003395 return( desc );
Paul Bakker74111d32011-01-15 16:57:55 +00003396}
3397
3398/* Return the x.y.z.... style numeric string for the given OID */
3399int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
3400{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003401 return oid_get_numeric_string( buf, size, oid );
Paul Bakker74111d32011-01-15 16:57:55 +00003402}
3403
Paul Bakkerd98030e2009-05-02 15:13:40 +00003404/*
3405 * Return an informational string about the CRL.
3406 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003407int x509parse_crl_info( char *buf, size_t size, const char *prefix,
3408 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003409{
Paul Bakker23986e52011-04-24 08:57:21 +00003410 int ret;
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003411 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003412 char *p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003413 const char *desc;
Paul Bakkerff60ee62010-03-16 21:09:09 +00003414 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003415
3416 p = buf;
3417 n = size;
3418
3419 ret = snprintf( p, n, "%sCRL version : %d",
3420 prefix, crl->version );
3421 SAFE_SNPRINTF();
3422
3423 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
3424 SAFE_SNPRINTF();
3425 ret = x509parse_dn_gets( p, n, &crl->issuer );
3426 SAFE_SNPRINTF();
3427
3428 ret = snprintf( p, n, "\n%sthis update : " \
3429 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3430 crl->this_update.year, crl->this_update.mon,
3431 crl->this_update.day, crl->this_update.hour,
3432 crl->this_update.min, crl->this_update.sec );
3433 SAFE_SNPRINTF();
3434
3435 ret = snprintf( p, n, "\n%snext update : " \
3436 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3437 crl->next_update.year, crl->next_update.mon,
3438 crl->next_update.day, crl->next_update.hour,
3439 crl->next_update.min, crl->next_update.sec );
3440 SAFE_SNPRINTF();
3441
3442 entry = &crl->entry;
3443
3444 ret = snprintf( p, n, "\n%sRevoked certificates:",
3445 prefix );
3446 SAFE_SNPRINTF();
3447
Paul Bakker9be19372009-07-27 20:21:53 +00003448 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003449 {
3450 ret = snprintf( p, n, "\n%sserial number: ",
3451 prefix );
3452 SAFE_SNPRINTF();
3453
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003454 ret = x509parse_serial_gets( p, n, &entry->serial);
3455 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003456
Paul Bakkerd98030e2009-05-02 15:13:40 +00003457 ret = snprintf( p, n, " revocation date: " \
3458 "%04d-%02d-%02d %02d:%02d:%02d",
3459 entry->revocation_date.year, entry->revocation_date.mon,
3460 entry->revocation_date.day, entry->revocation_date.hour,
3461 entry->revocation_date.min, entry->revocation_date.sec );
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003462 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003463
3464 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003465 }
3466
Paul Bakkerc70b9822013-04-07 22:00:46 +02003467 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003468 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003469
Paul Bakkerc70b9822013-04-07 22:00:46 +02003470 ret = oid_get_sig_alg_desc( &crl->sig_oid1, &desc );
3471 if( ret != 0 )
3472 ret = snprintf( p, n, "???" );
3473 else
3474 ret = snprintf( p, n, desc );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003475 SAFE_SNPRINTF();
3476
Paul Bakker1e27bb22009-07-19 20:25:25 +00003477 ret = snprintf( p, n, "\n" );
3478 SAFE_SNPRINTF();
3479
Paul Bakker23986e52011-04-24 08:57:21 +00003480 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003481}
3482
3483/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00003484 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00003485 */
Paul Bakkerfa9b1002013-07-03 15:31:03 +02003486#if defined(POLARSSL_HAVE_TIME)
Paul Bakkerff60ee62010-03-16 21:09:09 +00003487int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00003488{
Paul Bakkercce9d772011-11-18 14:26:47 +00003489 int year, mon, day;
3490 int hour, min, sec;
3491
3492#if defined(_WIN32)
3493 SYSTEMTIME st;
3494
3495 GetLocalTime(&st);
3496
3497 year = st.wYear;
3498 mon = st.wMonth;
3499 day = st.wDay;
3500 hour = st.wHour;
3501 min = st.wMinute;
3502 sec = st.wSecond;
3503#else
Paul Bakker5121ce52009-01-03 21:22:43 +00003504 struct tm *lt;
3505 time_t tt;
3506
3507 tt = time( NULL );
3508 lt = localtime( &tt );
3509
Paul Bakkercce9d772011-11-18 14:26:47 +00003510 year = lt->tm_year + 1900;
3511 mon = lt->tm_mon + 1;
3512 day = lt->tm_mday;
3513 hour = lt->tm_hour;
3514 min = lt->tm_min;
3515 sec = lt->tm_sec;
3516#endif
3517
3518 if( year > to->year )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003519 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003520
Paul Bakkercce9d772011-11-18 14:26:47 +00003521 if( year == to->year &&
3522 mon > to->mon )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003523 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003524
Paul Bakkercce9d772011-11-18 14:26:47 +00003525 if( year == to->year &&
3526 mon == to->mon &&
3527 day > to->day )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003528 return( 1 );
3529
Paul Bakkercce9d772011-11-18 14:26:47 +00003530 if( year == to->year &&
3531 mon == to->mon &&
3532 day == to->day &&
3533 hour > to->hour )
Paul Bakkerb6194992011-01-16 21:40:22 +00003534 return( 1 );
3535
Paul Bakkercce9d772011-11-18 14:26:47 +00003536 if( year == to->year &&
3537 mon == to->mon &&
3538 day == to->day &&
3539 hour == to->hour &&
3540 min > to->min )
Paul Bakkerb6194992011-01-16 21:40:22 +00003541 return( 1 );
3542
Paul Bakkercce9d772011-11-18 14:26:47 +00003543 if( year == to->year &&
3544 mon == to->mon &&
3545 day == to->day &&
3546 hour == to->hour &&
3547 min == to->min &&
3548 sec > to->sec )
Paul Bakkerb6194992011-01-16 21:40:22 +00003549 return( 1 );
3550
Paul Bakker40ea7de2009-05-03 10:18:48 +00003551 return( 0 );
3552}
Paul Bakkerfa9b1002013-07-03 15:31:03 +02003553#else /* POLARSSL_HAVE_TIME */
3554int x509parse_time_expired( const x509_time *to )
3555{
3556 ((void) to);
3557 return( 0 );
3558}
3559#endif /* POLARSSL_HAVE_TIME */
Paul Bakker40ea7de2009-05-03 10:18:48 +00003560
3561/*
3562 * Return 1 if the certificate is revoked, or 0 otherwise.
3563 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003564int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003565{
Paul Bakkerff60ee62010-03-16 21:09:09 +00003566 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00003567
3568 while( cur != NULL && cur->serial.len != 0 )
3569 {
Paul Bakkera056efc2011-01-16 21:38:35 +00003570 if( crt->serial.len == cur->serial.len &&
3571 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003572 {
3573 if( x509parse_time_expired( &cur->revocation_date ) )
3574 return( 1 );
3575 }
3576
3577 cur = cur->next;
3578 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003579
3580 return( 0 );
3581}
3582
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003583/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00003584 * Check that the given certificate is valid accoring to the CRL.
3585 */
3586static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
3587 x509_crl *crl_list)
3588{
3589 int flags = 0;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003590 unsigned char hash[POLARSSL_MD_MAX_SIZE];
3591 const md_info_t *md_info;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003592
Paul Bakker915275b2012-09-28 07:10:55 +00003593 if( ca == NULL )
3594 return( flags );
3595
Paul Bakker76fd75a2011-01-16 21:12:10 +00003596 /*
3597 * TODO: What happens if no CRL is present?
3598 * Suggestion: Revocation state should be unknown if no CRL is present.
3599 * For backwards compatibility this is not yet implemented.
3600 */
3601
Paul Bakker915275b2012-09-28 07:10:55 +00003602 while( crl_list != NULL )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003603 {
Paul Bakker915275b2012-09-28 07:10:55 +00003604 if( crl_list->version == 0 ||
3605 crl_list->issuer_raw.len != ca->subject_raw.len ||
Paul Bakker76fd75a2011-01-16 21:12:10 +00003606 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
3607 crl_list->issuer_raw.len ) != 0 )
3608 {
3609 crl_list = crl_list->next;
3610 continue;
3611 }
3612
3613 /*
3614 * Check if CRL is correctly signed by the trusted CA
3615 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02003616 md_info = md_info_from_type( crl_list->sig_md );
3617 if( md_info == NULL )
3618 {
3619 /*
3620 * Cannot check 'unknown' hash
3621 */
3622 flags |= BADCRL_NOT_TRUSTED;
3623 break;
3624 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00003625
Paul Bakkerc70b9822013-04-07 22:00:46 +02003626 md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
Paul Bakker76fd75a2011-01-16 21:12:10 +00003627
Paul Bakkerc70b9822013-04-07 22:00:46 +02003628 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, crl_list->sig_md,
Paul Bakker76fd75a2011-01-16 21:12:10 +00003629 0, hash, crl_list->sig.p ) == 0 )
3630 {
3631 /*
3632 * CRL is not trusted
3633 */
3634 flags |= BADCRL_NOT_TRUSTED;
3635 break;
3636 }
3637
3638 /*
3639 * Check for validity of CRL (Do not drop out)
3640 */
3641 if( x509parse_time_expired( &crl_list->next_update ) )
3642 flags |= BADCRL_EXPIRED;
3643
3644 /*
3645 * Check if certificate is revoked
3646 */
3647 if( x509parse_revoked(crt, crl_list) )
3648 {
3649 flags |= BADCERT_REVOKED;
3650 break;
3651 }
3652
3653 crl_list = crl_list->next;
3654 }
3655 return flags;
3656}
3657
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02003658static int x509_wildcard_verify( const char *cn, x509_buf *name )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003659{
3660 size_t i;
3661 size_t cn_idx = 0;
3662
Paul Bakker57b12982012-02-11 17:38:38 +00003663 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003664 return( 0 );
3665
3666 for( i = 0; i < strlen( cn ); ++i )
3667 {
3668 if( cn[i] == '.' )
3669 {
3670 cn_idx = i;
3671 break;
3672 }
3673 }
3674
3675 if( cn_idx == 0 )
3676 return( 0 );
3677
Paul Bakker535e97d2012-08-23 10:49:55 +00003678 if( strlen( cn ) - cn_idx == name->len - 1 &&
3679 memcmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003680 {
3681 return( 1 );
3682 }
3683
3684 return( 0 );
3685}
3686
Paul Bakker915275b2012-09-28 07:10:55 +00003687static int x509parse_verify_top(
3688 x509_cert *child, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003689 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003690 int (*f_vrfy)(void *, x509_cert *, int, int *),
3691 void *p_vrfy )
3692{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003693 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003694 int ca_flags = 0, check_path_cnt = path_cnt + 1;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003695 unsigned char hash[POLARSSL_MD_MAX_SIZE];
3696 const md_info_t *md_info;
Paul Bakker915275b2012-09-28 07:10:55 +00003697
3698 if( x509parse_time_expired( &child->valid_to ) )
3699 *flags |= BADCERT_EXPIRED;
3700
3701 /*
3702 * Child is the top of the chain. Check against the trust_ca list.
3703 */
3704 *flags |= BADCERT_NOT_TRUSTED;
3705
3706 while( trust_ca != NULL )
3707 {
3708 if( trust_ca->version == 0 ||
3709 child->issuer_raw.len != trust_ca->subject_raw.len ||
3710 memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
3711 child->issuer_raw.len ) != 0 )
3712 {
3713 trust_ca = trust_ca->next;
3714 continue;
3715 }
3716
Paul Bakker9a736322012-11-14 12:39:52 +00003717 /*
3718 * Reduce path_len to check against if top of the chain is
3719 * the same as the trusted CA
3720 */
3721 if( child->subject_raw.len == trust_ca->subject_raw.len &&
3722 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3723 child->issuer_raw.len ) == 0 )
3724 {
3725 check_path_cnt--;
3726 }
3727
Paul Bakker915275b2012-09-28 07:10:55 +00003728 if( trust_ca->max_pathlen > 0 &&
Paul Bakker9a736322012-11-14 12:39:52 +00003729 trust_ca->max_pathlen < check_path_cnt )
Paul Bakker915275b2012-09-28 07:10:55 +00003730 {
3731 trust_ca = trust_ca->next;
3732 continue;
3733 }
3734
Paul Bakkerc70b9822013-04-07 22:00:46 +02003735 md_info = md_info_from_type( child->sig_md );
3736 if( md_info == NULL )
3737 {
3738 /*
3739 * Cannot check 'unknown' hash
3740 */
3741 continue;
3742 }
Paul Bakker915275b2012-09-28 07:10:55 +00003743
Paul Bakkerc70b9822013-04-07 22:00:46 +02003744 md( md_info, child->tbs.p, child->tbs.len, hash );
Paul Bakker915275b2012-09-28 07:10:55 +00003745
Paul Bakkerc70b9822013-04-07 22:00:46 +02003746 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, child->sig_md,
Paul Bakker915275b2012-09-28 07:10:55 +00003747 0, hash, child->sig.p ) != 0 )
3748 {
3749 trust_ca = trust_ca->next;
3750 continue;
3751 }
3752
3753 /*
3754 * Top of chain is signed by a trusted CA
3755 */
3756 *flags &= ~BADCERT_NOT_TRUSTED;
3757 break;
3758 }
3759
Paul Bakker9a736322012-11-14 12:39:52 +00003760 /*
Paul Bakker3497d8c2012-11-24 11:53:17 +01003761 * If top of chain is not the same as the trusted CA send a verify request
3762 * to the callback for any issues with validity and CRL presence for the
3763 * trusted CA certificate.
Paul Bakker9a736322012-11-14 12:39:52 +00003764 */
3765 if( trust_ca != NULL &&
3766 ( child->subject_raw.len != trust_ca->subject_raw.len ||
3767 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3768 child->issuer_raw.len ) != 0 ) )
Paul Bakker915275b2012-09-28 07:10:55 +00003769 {
3770 /* Check trusted CA's CRL for then chain's top crt */
3771 *flags |= x509parse_verifycrl( child, trust_ca, ca_crl );
3772
3773 if( x509parse_time_expired( &trust_ca->valid_to ) )
3774 ca_flags |= BADCERT_EXPIRED;
3775
Paul Bakker915275b2012-09-28 07:10:55 +00003776 if( NULL != f_vrfy )
3777 {
Paul Bakker9a736322012-11-14 12:39:52 +00003778 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003779 return( ret );
3780 }
3781 }
3782
3783 /* Call callback on top cert */
3784 if( NULL != f_vrfy )
3785 {
Paul Bakker9a736322012-11-14 12:39:52 +00003786 if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003787 return( ret );
3788 }
3789
Paul Bakker915275b2012-09-28 07:10:55 +00003790 *flags |= ca_flags;
3791
3792 return( 0 );
3793}
3794
3795static int x509parse_verify_child(
3796 x509_cert *child, x509_cert *parent, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003797 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003798 int (*f_vrfy)(void *, x509_cert *, int, int *),
3799 void *p_vrfy )
3800{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003801 int ret;
Paul Bakker915275b2012-09-28 07:10:55 +00003802 int parent_flags = 0;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003803 unsigned char hash[POLARSSL_MD_MAX_SIZE];
Paul Bakker915275b2012-09-28 07:10:55 +00003804 x509_cert *grandparent;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003805 const md_info_t *md_info;
Paul Bakker915275b2012-09-28 07:10:55 +00003806
3807 if( x509parse_time_expired( &child->valid_to ) )
3808 *flags |= BADCERT_EXPIRED;
3809
Paul Bakkerc70b9822013-04-07 22:00:46 +02003810 md_info = md_info_from_type( child->sig_md );
3811 if( md_info == NULL )
3812 {
3813 /*
3814 * Cannot check 'unknown' hash
3815 */
Paul Bakker915275b2012-09-28 07:10:55 +00003816 *flags |= BADCERT_NOT_TRUSTED;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003817 }
3818 else
3819 {
3820 md( md_info, child->tbs.p, child->tbs.len, hash );
3821
3822 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, child->sig_md, 0, hash,
3823 child->sig.p ) != 0 )
3824 *flags |= BADCERT_NOT_TRUSTED;
3825 }
3826
Paul Bakker915275b2012-09-28 07:10:55 +00003827 /* Check trusted CA's CRL for the given crt */
3828 *flags |= x509parse_verifycrl(child, parent, ca_crl);
3829
3830 grandparent = parent->next;
3831
3832 while( grandparent != NULL )
3833 {
3834 if( grandparent->version == 0 ||
3835 grandparent->ca_istrue == 0 ||
3836 parent->issuer_raw.len != grandparent->subject_raw.len ||
3837 memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
3838 parent->issuer_raw.len ) != 0 )
3839 {
3840 grandparent = grandparent->next;
3841 continue;
3842 }
3843 break;
3844 }
3845
Paul Bakker915275b2012-09-28 07:10:55 +00003846 if( grandparent != NULL )
3847 {
3848 /*
3849 * Part of the chain
3850 */
Paul Bakker9a736322012-11-14 12:39:52 +00003851 ret = x509parse_verify_child( parent, grandparent, trust_ca, ca_crl, path_cnt + 1, &parent_flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003852 if( ret != 0 )
3853 return( ret );
3854 }
3855 else
3856 {
Paul Bakker9a736322012-11-14 12:39:52 +00003857 ret = x509parse_verify_top( parent, trust_ca, ca_crl, path_cnt + 1, &parent_flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003858 if( ret != 0 )
3859 return( ret );
3860 }
3861
3862 /* child is verified to be a child of the parent, call verify callback */
3863 if( NULL != f_vrfy )
Paul Bakker9a736322012-11-14 12:39:52 +00003864 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003865 return( ret );
Paul Bakker915275b2012-09-28 07:10:55 +00003866
3867 *flags |= parent_flags;
3868
3869 return( 0 );
3870}
3871
Paul Bakker76fd75a2011-01-16 21:12:10 +00003872/*
Paul Bakker5121ce52009-01-03 21:22:43 +00003873 * Verify the certificate validity
3874 */
3875int x509parse_verify( x509_cert *crt,
3876 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00003877 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003878 const char *cn, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003879 int (*f_vrfy)(void *, x509_cert *, int, int *),
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003880 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00003881{
Paul Bakker23986e52011-04-24 08:57:21 +00003882 size_t cn_len;
Paul Bakker915275b2012-09-28 07:10:55 +00003883 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003884 int pathlen = 0;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003885 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00003886 x509_name *name;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003887 x509_sequence *cur = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003888
Paul Bakker40ea7de2009-05-03 10:18:48 +00003889 *flags = 0;
3890
Paul Bakker5121ce52009-01-03 21:22:43 +00003891 if( cn != NULL )
3892 {
3893 name = &crt->subject;
3894 cn_len = strlen( cn );
3895
Paul Bakker4d2c1242012-05-10 14:12:46 +00003896 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
Paul Bakker5121ce52009-01-03 21:22:43 +00003897 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00003898 cur = &crt->subject_alt_names;
3899
3900 while( cur != NULL )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003901 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003902 if( cur->buf.len == cn_len &&
3903 memcmp( cn, cur->buf.p, cn_len ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003904 break;
3905
Paul Bakker535e97d2012-08-23 10:49:55 +00003906 if( cur->buf.len > 2 &&
3907 memcmp( cur->buf.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003908 x509_wildcard_verify( cn, &cur->buf ) )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003909 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003910
Paul Bakker4d2c1242012-05-10 14:12:46 +00003911 cur = cur->next;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003912 }
3913
3914 if( cur == NULL )
3915 *flags |= BADCERT_CN_MISMATCH;
3916 }
Paul Bakker4d2c1242012-05-10 14:12:46 +00003917 else
3918 {
3919 while( name != NULL )
3920 {
Paul Bakkerc70b9822013-04-07 22:00:46 +02003921 if( OID_CMP( OID_AT_CN, &name->oid ) )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003922 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003923 if( name->val.len == cn_len &&
3924 memcmp( name->val.p, cn, cn_len ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003925 break;
3926
Paul Bakker535e97d2012-08-23 10:49:55 +00003927 if( name->val.len > 2 &&
3928 memcmp( name->val.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003929 x509_wildcard_verify( cn, &name->val ) )
3930 break;
3931 }
3932
3933 name = name->next;
3934 }
3935
3936 if( name == NULL )
3937 *flags |= BADCERT_CN_MISMATCH;
3938 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003939 }
3940
Paul Bakker5121ce52009-01-03 21:22:43 +00003941 /*
Paul Bakker915275b2012-09-28 07:10:55 +00003942 * Iterate upwards in the given cert chain, to find our crt parent.
3943 * Ignore any upper cert with CA != TRUE.
Paul Bakker5121ce52009-01-03 21:22:43 +00003944 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003945 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003946
Paul Bakker76fd75a2011-01-16 21:12:10 +00003947 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003948 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003949 if( parent->ca_istrue == 0 ||
3950 crt->issuer_raw.len != parent->subject_raw.len ||
3951 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00003952 crt->issuer_raw.len ) != 0 )
3953 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003954 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003955 continue;
3956 }
Paul Bakker915275b2012-09-28 07:10:55 +00003957 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003958 }
3959
Paul Bakker915275b2012-09-28 07:10:55 +00003960 if( parent != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003961 {
Paul Bakker915275b2012-09-28 07:10:55 +00003962 /*
3963 * Part of the chain
3964 */
Paul Bakker9a736322012-11-14 12:39:52 +00003965 ret = x509parse_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003966 if( ret != 0 )
3967 return( ret );
3968 }
3969 else
Paul Bakker74111d32011-01-15 16:57:55 +00003970 {
Paul Bakker9a736322012-11-14 12:39:52 +00003971 ret = x509parse_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003972 if( ret != 0 )
3973 return( ret );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003974 }
Paul Bakker915275b2012-09-28 07:10:55 +00003975
3976 if( *flags != 0 )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003977 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003978
Paul Bakker5121ce52009-01-03 21:22:43 +00003979 return( 0 );
3980}
3981
3982/*
3983 * Unallocate all certificate data
3984 */
3985void x509_free( x509_cert *crt )
3986{
3987 x509_cert *cert_cur = crt;
3988 x509_cert *cert_prv;
3989 x509_name *name_cur;
3990 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00003991 x509_sequence *seq_cur;
3992 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00003993
3994 if( crt == NULL )
3995 return;
3996
3997 do
3998 {
Manuel Pégourié-Gonnard674b2242013-07-10 14:32:58 +02003999 pk_free( &cert_cur->pk );
Paul Bakker5121ce52009-01-03 21:22:43 +00004000 rsa_free( &cert_cur->rsa );
4001
4002 name_cur = cert_cur->issuer.next;
4003 while( name_cur != NULL )
4004 {
4005 name_prv = name_cur;
4006 name_cur = name_cur->next;
4007 memset( name_prv, 0, sizeof( x509_name ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02004008 polarssl_free( name_prv );
Paul Bakker5121ce52009-01-03 21:22:43 +00004009 }
4010
4011 name_cur = cert_cur->subject.next;
4012 while( name_cur != NULL )
4013 {
4014 name_prv = name_cur;
4015 name_cur = name_cur->next;
4016 memset( name_prv, 0, sizeof( x509_name ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02004017 polarssl_free( name_prv );
Paul Bakker5121ce52009-01-03 21:22:43 +00004018 }
4019
Paul Bakker74111d32011-01-15 16:57:55 +00004020 seq_cur = cert_cur->ext_key_usage.next;
4021 while( seq_cur != NULL )
4022 {
4023 seq_prv = seq_cur;
4024 seq_cur = seq_cur->next;
4025 memset( seq_prv, 0, sizeof( x509_sequence ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02004026 polarssl_free( seq_prv );
Paul Bakker74111d32011-01-15 16:57:55 +00004027 }
4028
Paul Bakker8afa70d2012-02-11 18:42:45 +00004029 seq_cur = cert_cur->subject_alt_names.next;
4030 while( seq_cur != NULL )
4031 {
4032 seq_prv = seq_cur;
4033 seq_cur = seq_cur->next;
4034 memset( seq_prv, 0, sizeof( x509_sequence ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02004035 polarssl_free( seq_prv );
Paul Bakker8afa70d2012-02-11 18:42:45 +00004036 }
4037
Paul Bakker5121ce52009-01-03 21:22:43 +00004038 if( cert_cur->raw.p != NULL )
4039 {
4040 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
Paul Bakker6e339b52013-07-03 13:37:05 +02004041 polarssl_free( cert_cur->raw.p );
Paul Bakker5121ce52009-01-03 21:22:43 +00004042 }
4043
4044 cert_cur = cert_cur->next;
4045 }
4046 while( cert_cur != NULL );
4047
4048 cert_cur = crt;
4049 do
4050 {
4051 cert_prv = cert_cur;
4052 cert_cur = cert_cur->next;
4053
4054 memset( cert_prv, 0, sizeof( x509_cert ) );
4055 if( cert_prv != crt )
Paul Bakker6e339b52013-07-03 13:37:05 +02004056 polarssl_free( cert_prv );
Paul Bakker5121ce52009-01-03 21:22:43 +00004057 }
4058 while( cert_cur != NULL );
4059}
4060
Paul Bakkerd98030e2009-05-02 15:13:40 +00004061/*
4062 * Unallocate all CRL data
4063 */
4064void x509_crl_free( x509_crl *crl )
4065{
4066 x509_crl *crl_cur = crl;
4067 x509_crl *crl_prv;
4068 x509_name *name_cur;
4069 x509_name *name_prv;
4070 x509_crl_entry *entry_cur;
4071 x509_crl_entry *entry_prv;
4072
4073 if( crl == NULL )
4074 return;
4075
4076 do
4077 {
4078 name_cur = crl_cur->issuer.next;
4079 while( name_cur != NULL )
4080 {
4081 name_prv = name_cur;
4082 name_cur = name_cur->next;
4083 memset( name_prv, 0, sizeof( x509_name ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02004084 polarssl_free( name_prv );
Paul Bakkerd98030e2009-05-02 15:13:40 +00004085 }
4086
4087 entry_cur = crl_cur->entry.next;
4088 while( entry_cur != NULL )
4089 {
4090 entry_prv = entry_cur;
4091 entry_cur = entry_cur->next;
4092 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02004093 polarssl_free( entry_prv );
Paul Bakkerd98030e2009-05-02 15:13:40 +00004094 }
4095
4096 if( crl_cur->raw.p != NULL )
4097 {
4098 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
Paul Bakker6e339b52013-07-03 13:37:05 +02004099 polarssl_free( crl_cur->raw.p );
Paul Bakkerd98030e2009-05-02 15:13:40 +00004100 }
4101
4102 crl_cur = crl_cur->next;
4103 }
4104 while( crl_cur != NULL );
4105
4106 crl_cur = crl;
4107 do
4108 {
4109 crl_prv = crl_cur;
4110 crl_cur = crl_cur->next;
4111
4112 memset( crl_prv, 0, sizeof( x509_crl ) );
4113 if( crl_prv != crl )
Paul Bakker6e339b52013-07-03 13:37:05 +02004114 polarssl_free( crl_prv );
Paul Bakkerd98030e2009-05-02 15:13:40 +00004115 }
4116 while( crl_cur != NULL );
4117}
4118
Paul Bakker40e46942009-01-03 21:51:57 +00004119#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00004120
Paul Bakker40e46942009-01-03 21:51:57 +00004121#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00004122
4123/*
4124 * Checkup routine
4125 */
4126int x509_self_test( int verbose )
4127{
Paul Bakker5690efc2011-05-26 13:16:06 +00004128#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00004129 int ret;
4130 int flags;
4131 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00004132 x509_cert cacert;
4133 x509_cert clicert;
4134 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00004135#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00004136 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00004137#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00004138
4139 if( verbose != 0 )
4140 printf( " X.509 certificate load: " );
4141
4142 memset( &clicert, 0, sizeof( x509_cert ) );
4143
Paul Bakker3c2122f2013-06-24 19:03:14 +02004144 ret = x509parse_crt( &clicert, (const unsigned char *) test_cli_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00004145 strlen( test_cli_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00004146 if( ret != 0 )
4147 {
4148 if( verbose != 0 )
4149 printf( "failed\n" );
4150
4151 return( ret );
4152 }
4153
4154 memset( &cacert, 0, sizeof( x509_cert ) );
4155
Paul Bakker3c2122f2013-06-24 19:03:14 +02004156 ret = x509parse_crt( &cacert, (const unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00004157 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00004158 if( ret != 0 )
4159 {
4160 if( verbose != 0 )
4161 printf( "failed\n" );
4162
4163 return( ret );
4164 }
4165
4166 if( verbose != 0 )
4167 printf( "passed\n X.509 private key load: " );
4168
4169 i = strlen( test_ca_key );
4170 j = strlen( test_ca_pwd );
4171
Paul Bakker66b78b22011-03-25 14:22:50 +00004172 rsa_init( &rsa, RSA_PKCS_V15, 0 );
4173
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02004174 if( ( ret = x509parse_key_rsa( &rsa,
Paul Bakker3c2122f2013-06-24 19:03:14 +02004175 (const unsigned char *) test_ca_key, i,
4176 (const unsigned char *) test_ca_pwd, j ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00004177 {
4178 if( verbose != 0 )
4179 printf( "failed\n" );
4180
4181 return( ret );
4182 }
4183
4184 if( verbose != 0 )
4185 printf( "passed\n X.509 signature verify: ");
4186
Paul Bakker23986e52011-04-24 08:57:21 +00004187 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00004188 if( ret != 0 )
4189 {
Paul Bakker23986e52011-04-24 08:57:21 +00004190 printf("%02x", flags);
Paul Bakker5121ce52009-01-03 21:22:43 +00004191 if( verbose != 0 )
4192 printf( "failed\n" );
4193
4194 return( ret );
4195 }
4196
Paul Bakker5690efc2011-05-26 13:16:06 +00004197#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00004198 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00004199 printf( "passed\n X.509 DHM parameter load: " );
4200
4201 i = strlen( test_dhm_params );
4202 j = strlen( test_ca_pwd );
4203
Paul Bakker3c2122f2013-06-24 19:03:14 +02004204 if( ( ret = x509parse_dhm( &dhm, (const unsigned char *) test_dhm_params, i ) ) != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00004205 {
4206 if( verbose != 0 )
4207 printf( "failed\n" );
4208
4209 return( ret );
4210 }
4211
4212 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00004213 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00004214#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00004215
4216 x509_free( &cacert );
4217 x509_free( &clicert );
4218 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00004219#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00004220 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00004221#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00004222
4223 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00004224#else
4225 ((void) verbose);
4226 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
4227#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00004228}
4229
4230#endif
4231
4232#endif