blob: b51881a9a7bc2a2243380dc512d0a808fc91847f [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * X.509 certificate and private key decoding
3 *
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02004 * Copyright (C) 2006-2013, Brainspark B.V.
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
Paul Bakker84f12b72010-07-18 10:13:04 +00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakkerb96f1542010-07-18 20:36:00 +00008 *
Paul Bakker77b385e2009-07-28 17:23:11 +00009 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +000010 *
Paul Bakker5121ce52009-01-03 21:22:43 +000011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25/*
Paul Bakkerad8d3542012-02-16 15:28:14 +000026 * The ITU-T X.509 standard defines a certificate format for PKI.
Paul Bakker5121ce52009-01-03 21:22:43 +000027 *
Paul Bakker5121ce52009-01-03 21:22:43 +000028 * http://www.ietf.org/rfc/rfc3279.txt
Paul Bakkerad8d3542012-02-16 15:28:14 +000029 * http://www.ietf.org/rfc/rfc3280.txt
Paul Bakker5121ce52009-01-03 21:22:43 +000030 *
31 * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
32 *
33 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
34 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
35 */
36
Paul Bakker40e46942009-01-03 21:51:57 +000037#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000038
Paul Bakker40e46942009-01-03 21:51:57 +000039#if defined(POLARSSL_X509_PARSE_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000040
Paul Bakker40e46942009-01-03 21:51:57 +000041#include "polarssl/x509.h"
Paul Bakkerefc30292011-11-10 14:43:23 +000042#include "polarssl/asn1.h"
Paul Bakkerc70b9822013-04-07 22:00:46 +020043#include "polarssl/oid.h"
Paul Bakker96743fc2011-02-12 14:30:57 +000044#include "polarssl/pem.h"
Paul Bakker1b57b062011-01-06 15:48:19 +000045#include "polarssl/dhm.h"
Paul Bakker28144de2013-06-24 19:28:55 +020046#if defined(POLARSSL_PKCS5_C)
47#include "polarssl/pkcs5.h"
48#endif
Paul Bakker38b50d72013-06-24 19:33:27 +020049#if defined(POLARSSL_PKCS12_C)
50#include "polarssl/pkcs12.h"
51#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000052
Paul Bakker6e339b52013-07-03 13:37:05 +020053#if defined(POLARSSL_MEMORY_C)
54#include "polarssl/memory.h"
55#else
56#define polarssl_malloc malloc
57#define polarssl_free free
58#endif
59
Paul Bakker5121ce52009-01-03 21:22:43 +000060#include <string.h>
61#include <stdlib.h>
Paul Bakker4f229e52011-12-04 22:11:35 +000062#if defined(_WIN32)
Paul Bakkercce9d772011-11-18 14:26:47 +000063#include <windows.h>
64#else
Paul Bakker5121ce52009-01-03 21:22:43 +000065#include <time.h>
Paul Bakkercce9d772011-11-18 14:26:47 +000066#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000067
Paul Bakker335db3f2011-04-25 15:28:35 +000068#if defined(POLARSSL_FS_IO)
69#include <stdio.h>
Paul Bakker4a2bd0d2012-11-02 11:06:08 +000070#if !defined(_WIN32)
Paul Bakker8d914582012-06-04 12:46:42 +000071#include <sys/types.h>
Paul Bakker2c8cdd22013-06-24 19:22:42 +020072#include <sys/stat.h>
Paul Bakker8d914582012-06-04 12:46:42 +000073#include <dirent.h>
74#endif
Paul Bakker335db3f2011-04-25 15:28:35 +000075#endif
76
Paul Bakker5121ce52009-01-03 21:22:43 +000077/*
Paul Bakker5121ce52009-01-03 21:22:43 +000078 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
79 */
80static int x509_get_version( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +000081 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +000082 int *ver )
83{
Paul Bakker23986e52011-04-24 08:57:21 +000084 int ret;
85 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +000086
87 if( ( ret = asn1_get_tag( p, end, &len,
88 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
89 {
Paul Bakker40e46942009-01-03 21:51:57 +000090 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +000091 {
92 *ver = 0;
93 return( 0 );
94 }
Paul Bakker5121ce52009-01-03 21:22:43 +000095
96 return( ret );
97 }
98
99 end = *p + len;
100
101 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000102 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000103
104 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000105 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION +
Paul Bakker40e46942009-01-03 21:51:57 +0000106 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000107
108 return( 0 );
109}
110
111/*
Paul Bakkerfae618f2011-10-12 11:53:52 +0000112 * Version ::= INTEGER { v1(0), v2(1) }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000113 */
114static int x509_crl_get_version( unsigned char **p,
115 const unsigned char *end,
116 int *ver )
117{
118 int ret;
119
120 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
121 {
122 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +0000123 {
124 *ver = 0;
125 return( 0 );
126 }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000127
128 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
129 }
130
131 return( 0 );
132}
133
134/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000135 * CertificateSerialNumber ::= INTEGER
136 */
137static int x509_get_serial( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000138 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000139 x509_buf *serial )
140{
141 int ret;
142
143 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000144 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000145 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000146
147 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
148 **p != ASN1_INTEGER )
Paul Bakker9d781402011-05-09 16:17:09 +0000149 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000150 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000151
152 serial->tag = *(*p)++;
153
154 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000155 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000156
157 serial->p = *p;
158 *p += serial->len;
159
160 return( 0 );
161}
162
163/*
164 * AlgorithmIdentifier ::= SEQUENCE {
165 * algorithm OBJECT IDENTIFIER,
166 * parameters ANY DEFINED BY algorithm OPTIONAL }
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +0200167 *
168 * If params_end is NULL, then parameters must be absent or ANS.1 NULL
Paul Bakker5121ce52009-01-03 21:22:43 +0000169 */
170static int x509_get_alg( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000171 const unsigned char *end,
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +0200172 x509_buf *alg, const unsigned char **params_end )
Paul Bakker5121ce52009-01-03 21:22:43 +0000173{
Paul Bakker23986e52011-04-24 08:57:21 +0000174 int ret;
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +0200175 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000176
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +0200177 if( params_end == NULL ) {
178 if( ( ret = asn1_get_alg_null( p, end, alg ) ) != 0 )
179 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
180
181 return( 0 );
182 }
183
184 /* TODO: use asn1_get_alg */
185 if( ( ret = asn1_get_tag( p, end, &len,
186 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
187 {
188 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
189 }
190
191 end = *p + len;
192 alg->tag = **p;
193
194 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000195 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000196
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +0200197 alg->p = *p;
198 *p += alg->len;
199
200 *params_end = end;
Paul Bakker5121ce52009-01-03 21:22:43 +0000201 return( 0 );
202}
203
204/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000205 * AttributeTypeAndValue ::= SEQUENCE {
206 * type AttributeType,
207 * value AttributeValue }
208 *
209 * AttributeType ::= OBJECT IDENTIFIER
210 *
211 * AttributeValue ::= ANY DEFINED BY AttributeType
212 */
Paul Bakker400ff6f2011-02-20 10:40:16 +0000213static int x509_get_attr_type_value( unsigned char **p,
214 const unsigned char *end,
215 x509_name *cur )
Paul Bakker5121ce52009-01-03 21:22:43 +0000216{
Paul Bakker23986e52011-04-24 08:57:21 +0000217 int ret;
218 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000219 x509_buf *oid;
220 x509_buf *val;
221
222 if( ( ret = asn1_get_tag( p, end, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000223 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000224 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000225
Paul Bakker5121ce52009-01-03 21:22:43 +0000226 oid = &cur->oid;
227 oid->tag = **p;
228
229 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000230 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000231
232 oid->p = *p;
233 *p += oid->len;
234
235 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000236 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000237 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000238
239 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
240 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
241 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker9d781402011-05-09 16:17:09 +0000242 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000243 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000244
245 val = &cur->val;
246 val->tag = *(*p)++;
247
248 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000249 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000250
251 val->p = *p;
252 *p += val->len;
253
254 cur->next = NULL;
255
Paul Bakker400ff6f2011-02-20 10:40:16 +0000256 return( 0 );
257}
258
259/*
260 * RelativeDistinguishedName ::=
261 * SET OF AttributeTypeAndValue
262 *
263 * AttributeTypeAndValue ::= SEQUENCE {
264 * type AttributeType,
265 * value AttributeValue }
266 *
267 * AttributeType ::= OBJECT IDENTIFIER
268 *
269 * AttributeValue ::= ANY DEFINED BY AttributeType
270 */
271static int x509_get_name( unsigned char **p,
272 const unsigned char *end,
273 x509_name *cur )
274{
Paul Bakker23986e52011-04-24 08:57:21 +0000275 int ret;
276 size_t len;
Paul Bakker400ff6f2011-02-20 10:40:16 +0000277 const unsigned char *end2;
278 x509_name *use;
279
280 if( ( ret = asn1_get_tag( p, end, &len,
281 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000282 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000283
284 end2 = end;
285 end = *p + len;
286 use = cur;
287
288 do
289 {
290 if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
291 return( ret );
292
293 if( *p != end )
294 {
Paul Bakker6e339b52013-07-03 13:37:05 +0200295 use->next = (x509_name *) polarssl_malloc(
Paul Bakker400ff6f2011-02-20 10:40:16 +0000296 sizeof( x509_name ) );
297
298 if( use->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000299 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000300
301 memset( use->next, 0, sizeof( x509_name ) );
302
303 use = use->next;
304 }
305 }
306 while( *p != end );
Paul Bakker5121ce52009-01-03 21:22:43 +0000307
308 /*
309 * recurse until end of SEQUENCE is reached
310 */
311 if( *p == end2 )
312 return( 0 );
313
Paul Bakker6e339b52013-07-03 13:37:05 +0200314 cur->next = (x509_name *) polarssl_malloc(
Paul Bakker5121ce52009-01-03 21:22:43 +0000315 sizeof( x509_name ) );
316
317 if( cur->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000318 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000319
Paul Bakker430ffbe2012-05-01 08:14:20 +0000320 memset( cur->next, 0, sizeof( x509_name ) );
321
Paul Bakker5121ce52009-01-03 21:22:43 +0000322 return( x509_get_name( p, end2, cur->next ) );
323}
324
325/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000326 * Time ::= CHOICE {
327 * utcTime UTCTime,
328 * generalTime GeneralizedTime }
329 */
Paul Bakker91200182010-02-18 21:26:15 +0000330static int x509_get_time( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000331 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000332 x509_time *time )
333{
Paul Bakker23986e52011-04-24 08:57:21 +0000334 int ret;
335 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000336 char date[64];
Paul Bakker91200182010-02-18 21:26:15 +0000337 unsigned char tag;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000338
Paul Bakker91200182010-02-18 21:26:15 +0000339 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000340 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
341 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000342
Paul Bakker91200182010-02-18 21:26:15 +0000343 tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000344
Paul Bakker91200182010-02-18 21:26:15 +0000345 if ( tag == ASN1_UTC_TIME )
346 {
347 (*p)++;
348 ret = asn1_get_len( p, end, &len );
349
350 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000351 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000352
Paul Bakker91200182010-02-18 21:26:15 +0000353 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000354 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
355 len : sizeof( date ) - 1 );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000356
Paul Bakker91200182010-02-18 21:26:15 +0000357 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
358 &time->year, &time->mon, &time->day,
359 &time->hour, &time->min, &time->sec ) < 5 )
360 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000361
Paul Bakker400ff6f2011-02-20 10:40:16 +0000362 time->year += 100 * ( time->year < 50 );
Paul Bakker91200182010-02-18 21:26:15 +0000363 time->year += 1900;
364
365 *p += len;
366
367 return( 0 );
368 }
369 else if ( tag == ASN1_GENERALIZED_TIME )
370 {
371 (*p)++;
372 ret = asn1_get_len( p, end, &len );
373
374 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000375 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker91200182010-02-18 21:26:15 +0000376
377 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000378 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
379 len : sizeof( date ) - 1 );
Paul Bakker91200182010-02-18 21:26:15 +0000380
381 if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
382 &time->year, &time->mon, &time->day,
383 &time->hour, &time->min, &time->sec ) < 5 )
384 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
385
386 *p += len;
387
388 return( 0 );
389 }
390 else
Paul Bakker9d781402011-05-09 16:17:09 +0000391 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000392}
393
394
395/*
396 * Validity ::= SEQUENCE {
397 * notBefore Time,
398 * notAfter Time }
399 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000400static int x509_get_dates( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000401 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000402 x509_time *from,
403 x509_time *to )
404{
Paul Bakker23986e52011-04-24 08:57:21 +0000405 int ret;
406 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000407
408 if( ( ret = asn1_get_tag( p, end, &len,
409 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000410 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000411
412 end = *p + len;
413
Paul Bakker91200182010-02-18 21:26:15 +0000414 if( ( ret = x509_get_time( p, end, from ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000415 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000416
Paul Bakker91200182010-02-18 21:26:15 +0000417 if( ( ret = x509_get_time( p, end, to ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000418 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000419
420 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000421 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker40e46942009-01-03 21:51:57 +0000422 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000423
424 return( 0 );
425}
426
427/*
428 * SubjectPublicKeyInfo ::= SEQUENCE {
429 * algorithm AlgorithmIdentifier,
430 * subjectPublicKey BIT STRING }
431 */
432static int x509_get_pubkey( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000433 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000434 x509_buf *pk_alg_oid,
435 mpi *N, mpi *E )
436{
Paul Bakkerc70b9822013-04-07 22:00:46 +0200437 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000438 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000439 unsigned char *end2;
Paul Bakkerc70b9822013-04-07 22:00:46 +0200440 pk_type_t pk_alg = POLARSSL_PK_NONE;
Paul Bakker5121ce52009-01-03 21:22:43 +0000441
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200442 if( ( ret = asn1_get_alg_null( p, end, pk_alg_oid ) ) != 0 )
443 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000444
445 /*
446 * only RSA public keys handled at this time
447 */
Paul Bakkerc70b9822013-04-07 22:00:46 +0200448 if( oid_get_pk_alg( pk_alg_oid, &pk_alg ) != 0 )
Paul Bakkered56b222011-07-13 11:26:43 +0000449 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000450
451 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000452 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000453
454 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000455 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000456 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000457
458 end2 = *p + len;
459
460 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000461 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000462
463 /*
464 * RSAPublicKey ::= SEQUENCE {
465 * modulus INTEGER, -- n
466 * publicExponent INTEGER -- e
467 * }
468 */
469 if( ( ret = asn1_get_tag( p, end2, &len,
470 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000471 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000472
473 if( *p + len != end2 )
Paul Bakker9d781402011-05-09 16:17:09 +0000474 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000475 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000476
477 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
478 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000479 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000480
481 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000482 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000483 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000484
485 return( 0 );
486}
487
488static int x509_get_sig( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000489 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000490 x509_buf *sig )
491{
Paul Bakker23986e52011-04-24 08:57:21 +0000492 int ret;
493 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000494
Paul Bakker8afa70d2012-02-11 18:42:45 +0000495 if( ( end - *p ) < 1 )
496 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE +
497 POLARSSL_ERR_ASN1_OUT_OF_DATA );
498
Paul Bakker5121ce52009-01-03 21:22:43 +0000499 sig->tag = **p;
500
501 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000502 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000503
Paul Bakker74111d32011-01-15 16:57:55 +0000504
Paul Bakker5121ce52009-01-03 21:22:43 +0000505 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000506 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000507
508 sig->len = len;
509 sig->p = *p;
510
511 *p += len;
512
513 return( 0 );
514}
515
516/*
517 * X.509 v2/v3 unique identifier (not parsed)
518 */
519static int x509_get_uid( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000520 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000521 x509_buf *uid, int n )
522{
523 int ret;
524
525 if( *p == end )
526 return( 0 );
527
528 uid->tag = **p;
529
530 if( ( ret = asn1_get_tag( p, end, &uid->len,
531 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
532 {
Paul Bakker40e46942009-01-03 21:51:57 +0000533 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000534 return( 0 );
535
536 return( ret );
537 }
538
539 uid->p = *p;
540 *p += uid->len;
541
542 return( 0 );
543}
544
545/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000546 * X.509 Extensions (No parsing of extensions, pointer should
547 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000548 */
549static int x509_get_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000550 const unsigned char *end,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000551 x509_buf *ext, int tag )
Paul Bakker5121ce52009-01-03 21:22:43 +0000552{
Paul Bakker23986e52011-04-24 08:57:21 +0000553 int ret;
554 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000555
556 if( *p == end )
557 return( 0 );
558
559 ext->tag = **p;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000560
Paul Bakker5121ce52009-01-03 21:22:43 +0000561 if( ( ret = asn1_get_tag( p, end, &ext->len,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000562 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000563 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000564
565 ext->p = *p;
566 end = *p + ext->len;
567
568 /*
569 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
570 *
571 * Extension ::= SEQUENCE {
572 * extnID OBJECT IDENTIFIER,
573 * critical BOOLEAN DEFAULT FALSE,
574 * extnValue OCTET STRING }
575 */
576 if( ( ret = asn1_get_tag( p, end, &len,
577 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000578 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000579
580 if( end != *p + len )
Paul Bakker9d781402011-05-09 16:17:09 +0000581 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +0000582 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000583
Paul Bakkerd98030e2009-05-02 15:13:40 +0000584 return( 0 );
585}
586
587/*
588 * X.509 CRL v2 extensions (no extensions parsed yet.)
589 */
590static int x509_get_crl_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000591 const unsigned char *end,
592 x509_buf *ext )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000593{
Paul Bakker23986e52011-04-24 08:57:21 +0000594 int ret;
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000595 size_t len = 0;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000596
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000597 /* Get explicit tag */
598 if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000599 {
600 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
601 return( 0 );
602
603 return( ret );
604 }
605
606 while( *p < end )
607 {
608 if( ( ret = asn1_get_tag( p, end, &len,
609 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000610 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000611
612 *p += len;
613 }
614
615 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000616 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerd98030e2009-05-02 15:13:40 +0000617 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
618
619 return( 0 );
620}
621
Paul Bakkerb5a11ab2011-10-12 09:58:41 +0000622/*
623 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
624 */
625static int x509_get_crl_entry_ext( unsigned char **p,
626 const unsigned char *end,
627 x509_buf *ext )
628{
629 int ret;
630 size_t len = 0;
631
632 /* OPTIONAL */
633 if (end <= *p)
634 return( 0 );
635
636 ext->tag = **p;
637 ext->p = *p;
638
639 /*
640 * Get CRL-entry extension sequence header
641 * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
642 */
643 if( ( ret = asn1_get_tag( p, end, &ext->len,
644 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
645 {
646 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
647 {
648 ext->p = NULL;
649 return( 0 );
650 }
651 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
652 }
653
654 end = *p + ext->len;
655
656 if( end != *p + ext->len )
657 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
658 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
659
660 while( *p < end )
661 {
662 if( ( ret = asn1_get_tag( p, end, &len,
663 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
664 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
665
666 *p += len;
667 }
668
669 if( *p != end )
670 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
671 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
672
673 return( 0 );
674}
675
Paul Bakker74111d32011-01-15 16:57:55 +0000676static int x509_get_basic_constraints( unsigned char **p,
677 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000678 int *ca_istrue,
679 int *max_pathlen )
680{
Paul Bakker23986e52011-04-24 08:57:21 +0000681 int ret;
682 size_t len;
Paul Bakker74111d32011-01-15 16:57:55 +0000683
684 /*
685 * BasicConstraints ::= SEQUENCE {
686 * cA BOOLEAN DEFAULT FALSE,
687 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
688 */
Paul Bakker3cccddb2011-01-16 21:46:31 +0000689 *ca_istrue = 0; /* DEFAULT FALSE */
Paul Bakker74111d32011-01-15 16:57:55 +0000690 *max_pathlen = 0; /* endless */
691
692 if( ( ret = asn1_get_tag( p, end, &len,
693 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000694 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000695
696 if( *p == end )
697 return 0;
698
Paul Bakker3cccddb2011-01-16 21:46:31 +0000699 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000700 {
701 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker3cccddb2011-01-16 21:46:31 +0000702 ret = asn1_get_int( p, end, ca_istrue );
Paul Bakker74111d32011-01-15 16:57:55 +0000703
704 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000705 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000706
Paul Bakker3cccddb2011-01-16 21:46:31 +0000707 if( *ca_istrue != 0 )
708 *ca_istrue = 1;
Paul Bakker74111d32011-01-15 16:57:55 +0000709 }
710
711 if( *p == end )
712 return 0;
713
714 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000715 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000716
717 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000718 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000719 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
720
721 (*max_pathlen)++;
722
Paul Bakker74111d32011-01-15 16:57:55 +0000723 return 0;
724}
725
726static int x509_get_ns_cert_type( unsigned char **p,
727 const unsigned char *end,
728 unsigned char *ns_cert_type)
729{
730 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000731 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000732
733 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000734 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000735
736 if( bs.len != 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000737 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000738 POLARSSL_ERR_ASN1_INVALID_LENGTH );
739
740 /* Get actual bitstring */
741 *ns_cert_type = *bs.p;
742 return 0;
743}
744
745static int x509_get_key_usage( unsigned char **p,
746 const unsigned char *end,
747 unsigned char *key_usage)
748{
749 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000750 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000751
752 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000753 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000754
Paul Bakker94a67962012-08-23 13:03:52 +0000755 if( bs.len < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000756 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000757 POLARSSL_ERR_ASN1_INVALID_LENGTH );
758
759 /* Get actual bitstring */
760 *key_usage = *bs.p;
761 return 0;
762}
763
Paul Bakkerd98030e2009-05-02 15:13:40 +0000764/*
Paul Bakker74111d32011-01-15 16:57:55 +0000765 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
766 *
767 * KeyPurposeId ::= OBJECT IDENTIFIER
768 */
769static int x509_get_ext_key_usage( unsigned char **p,
770 const unsigned char *end,
771 x509_sequence *ext_key_usage)
772{
773 int ret;
774
775 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000776 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000777
778 /* Sequence length must be >= 1 */
779 if( ext_key_usage->buf.p == NULL )
Paul Bakker9d781402011-05-09 16:17:09 +0000780 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000781 POLARSSL_ERR_ASN1_INVALID_LENGTH );
782
783 return 0;
784}
785
786/*
Paul Bakkera8cd2392012-02-11 16:09:32 +0000787 * SubjectAltName ::= GeneralNames
788 *
789 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
790 *
791 * GeneralName ::= CHOICE {
792 * otherName [0] OtherName,
793 * rfc822Name [1] IA5String,
794 * dNSName [2] IA5String,
795 * x400Address [3] ORAddress,
796 * directoryName [4] Name,
797 * ediPartyName [5] EDIPartyName,
798 * uniformResourceIdentifier [6] IA5String,
799 * iPAddress [7] OCTET STRING,
800 * registeredID [8] OBJECT IDENTIFIER }
801 *
802 * OtherName ::= SEQUENCE {
803 * type-id OBJECT IDENTIFIER,
804 * value [0] EXPLICIT ANY DEFINED BY type-id }
805 *
806 * EDIPartyName ::= SEQUENCE {
807 * nameAssigner [0] DirectoryString OPTIONAL,
808 * partyName [1] DirectoryString }
809 *
810 * NOTE: PolarSSL only parses and uses dNSName at this point.
811 */
812static int x509_get_subject_alt_name( unsigned char **p,
813 const unsigned char *end,
814 x509_sequence *subject_alt_name )
815{
816 int ret;
817 size_t len, tag_len;
818 asn1_buf *buf;
819 unsigned char tag;
820 asn1_sequence *cur = subject_alt_name;
821
822 /* Get main sequence tag */
823 if( ( ret = asn1_get_tag( p, end, &len,
824 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
825 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
826
827 if( *p + len != end )
828 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
829 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
830
831 while( *p < end )
832 {
833 if( ( end - *p ) < 1 )
834 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
835 POLARSSL_ERR_ASN1_OUT_OF_DATA );
836
837 tag = **p;
838 (*p)++;
839 if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 )
840 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
841
842 if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC )
843 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
844 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
845
846 if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) )
847 {
848 *p += tag_len;
849 continue;
850 }
851
852 buf = &(cur->buf);
853 buf->tag = tag;
854 buf->p = *p;
855 buf->len = tag_len;
856 *p += buf->len;
857
858 /* Allocate and assign next pointer */
859 if (*p < end)
860 {
Paul Bakker6e339b52013-07-03 13:37:05 +0200861 cur->next = (asn1_sequence *) polarssl_malloc(
Paul Bakkera8cd2392012-02-11 16:09:32 +0000862 sizeof( asn1_sequence ) );
863
864 if( cur->next == NULL )
865 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
866 POLARSSL_ERR_ASN1_MALLOC_FAILED );
867
Paul Bakker535e97d2012-08-23 10:49:55 +0000868 memset( cur->next, 0, sizeof( asn1_sequence ) );
Paul Bakkera8cd2392012-02-11 16:09:32 +0000869 cur = cur->next;
870 }
871 }
872
873 /* Set final sequence entry's next pointer to NULL */
874 cur->next = NULL;
875
876 if( *p != end )
877 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
878 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
879
880 return( 0 );
881}
882
883/*
Paul Bakker74111d32011-01-15 16:57:55 +0000884 * X.509 v3 extensions
885 *
886 * TODO: Perform all of the basic constraints tests required by the RFC
887 * TODO: Set values for undetected extensions to a sane default?
888 *
Paul Bakkerd98030e2009-05-02 15:13:40 +0000889 */
890static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000891 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000892 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000893{
Paul Bakker23986e52011-04-24 08:57:21 +0000894 int ret;
895 size_t len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000896 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000897
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000898 if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000899 {
900 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
901 return( 0 );
902
903 return( ret );
904 }
905
Paul Bakker5121ce52009-01-03 21:22:43 +0000906 while( *p < end )
907 {
Paul Bakker74111d32011-01-15 16:57:55 +0000908 /*
909 * Extension ::= SEQUENCE {
910 * extnID OBJECT IDENTIFIER,
911 * critical BOOLEAN DEFAULT FALSE,
912 * extnValue OCTET STRING }
913 */
914 x509_buf extn_oid = {0, 0, NULL};
915 int is_critical = 0; /* DEFAULT FALSE */
Paul Bakkerc70b9822013-04-07 22:00:46 +0200916 int ext_type = 0;
Paul Bakker74111d32011-01-15 16:57:55 +0000917
Paul Bakker5121ce52009-01-03 21:22:43 +0000918 if( ( ret = asn1_get_tag( p, end, &len,
919 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000920 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000921
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000922 end_ext_data = *p + len;
923
Paul Bakker74111d32011-01-15 16:57:55 +0000924 /* Get extension ID */
925 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000926
Paul Bakker74111d32011-01-15 16:57:55 +0000927 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000928 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000929
Paul Bakker74111d32011-01-15 16:57:55 +0000930 extn_oid.p = *p;
931 *p += extn_oid.len;
932
933 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000934 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000935 POLARSSL_ERR_ASN1_OUT_OF_DATA );
936
937 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000938 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000939 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
Paul Bakker9d781402011-05-09 16:17:09 +0000940 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000941
Paul Bakker74111d32011-01-15 16:57:55 +0000942 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000943 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000944 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000945 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000946
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000947 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000948
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000949 if( end_ext_octet != end_ext_data )
Paul Bakker9d781402011-05-09 16:17:09 +0000950 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000951 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000952
Paul Bakker74111d32011-01-15 16:57:55 +0000953 /*
954 * Detect supported extensions
955 */
Paul Bakkerc70b9822013-04-07 22:00:46 +0200956 ret = oid_get_x509_ext_type( &extn_oid, &ext_type );
957
958 if( ret != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000959 {
960 /* No parser found, skip extension */
961 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +0000962
Paul Bakker5c721f92011-07-27 16:51:09 +0000963#if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
Paul Bakker74111d32011-01-15 16:57:55 +0000964 if( is_critical )
965 {
966 /* Data is marked as critical: fail */
Paul Bakker9d781402011-05-09 16:17:09 +0000967 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000968 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
969 }
Paul Bakker5c721f92011-07-27 16:51:09 +0000970#endif
Paul Bakkerc70b9822013-04-07 22:00:46 +0200971 continue;
972 }
973
974 crt->ext_types |= ext_type;
975
976 switch( ext_type )
977 {
978 case EXT_BASIC_CONSTRAINTS:
979 /* Parse basic constraints */
980 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
981 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
982 return ( ret );
983 break;
984
985 case EXT_KEY_USAGE:
986 /* Parse key usage */
987 if( ( ret = x509_get_key_usage( p, end_ext_octet,
988 &crt->key_usage ) ) != 0 )
989 return ( ret );
990 break;
991
992 case EXT_EXTENDED_KEY_USAGE:
993 /* Parse extended key usage */
994 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
995 &crt->ext_key_usage ) ) != 0 )
996 return ( ret );
997 break;
998
999 case EXT_SUBJECT_ALT_NAME:
1000 /* Parse subject alt name */
1001 if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
1002 &crt->subject_alt_names ) ) != 0 )
1003 return ( ret );
1004 break;
1005
1006 case EXT_NS_CERT_TYPE:
1007 /* Parse netscape certificate type */
1008 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
1009 &crt->ns_cert_type ) ) != 0 )
1010 return ( ret );
1011 break;
1012
1013 default:
1014 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker74111d32011-01-15 16:57:55 +00001015 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001016 }
1017
1018 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +00001019 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +00001020 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001021
Paul Bakker5121ce52009-01-03 21:22:43 +00001022 return( 0 );
1023}
1024
1025/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001026 * X.509 CRL Entries
1027 */
1028static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001029 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001030 x509_crl_entry *entry )
1031{
Paul Bakker23986e52011-04-24 08:57:21 +00001032 int ret;
1033 size_t entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001034 x509_crl_entry *cur_entry = entry;
1035
1036 if( *p == end )
1037 return( 0 );
1038
Paul Bakker9be19372009-07-27 20:21:53 +00001039 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001040 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1041 {
1042 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
1043 return( 0 );
1044
1045 return( ret );
1046 }
1047
Paul Bakker9be19372009-07-27 20:21:53 +00001048 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001049
1050 while( *p < end )
1051 {
Paul Bakker23986e52011-04-24 08:57:21 +00001052 size_t len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001053 const unsigned char *end2;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001054
1055 if( ( ret = asn1_get_tag( p, end, &len2,
1056 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1057 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001058 return( ret );
1059 }
1060
Paul Bakker9be19372009-07-27 20:21:53 +00001061 cur_entry->raw.tag = **p;
1062 cur_entry->raw.p = *p;
1063 cur_entry->raw.len = len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001064 end2 = *p + len2;
Paul Bakker9be19372009-07-27 20:21:53 +00001065
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001066 if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001067 return( ret );
1068
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001069 if( ( ret = x509_get_time( p, end2, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001070 return( ret );
1071
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001072 if( ( ret = x509_get_crl_entry_ext( p, end2, &cur_entry->entry_ext ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001073 return( ret );
1074
Paul Bakker74111d32011-01-15 16:57:55 +00001075 if ( *p < end )
1076 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001077 cur_entry->next = polarssl_malloc( sizeof( x509_crl_entry ) );
Paul Bakkerb15b8512012-01-13 13:44:06 +00001078
1079 if( cur_entry->next == NULL )
1080 return( POLARSSL_ERR_X509_MALLOC_FAILED );
1081
Paul Bakkerd98030e2009-05-02 15:13:40 +00001082 cur_entry = cur_entry->next;
1083 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
1084 }
1085 }
1086
1087 return( 0 );
1088}
1089
Paul Bakkerc70b9822013-04-07 22:00:46 +02001090static int x509_get_sig_alg( const x509_buf *sig_oid, md_type_t *md_alg,
1091 pk_type_t *pk_alg )
Paul Bakker27d66162010-03-17 06:56:01 +00001092{
Paul Bakkerc70b9822013-04-07 22:00:46 +02001093 int ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg );
Paul Bakker27d66162010-03-17 06:56:01 +00001094
Paul Bakkerc70b9822013-04-07 22:00:46 +02001095 if( ret != 0 )
1096 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG + ret );
Paul Bakker27d66162010-03-17 06:56:01 +00001097
Paul Bakkerc70b9822013-04-07 22:00:46 +02001098 return( 0 );
Paul Bakker27d66162010-03-17 06:56:01 +00001099}
1100
Paul Bakkerd98030e2009-05-02 15:13:40 +00001101/*
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001102 * Parse and fill a single X.509 certificate in DER format
Paul Bakker5121ce52009-01-03 21:22:43 +00001103 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02001104static int x509parse_crt_der_core( x509_cert *crt, const unsigned char *buf,
1105 size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001106{
Paul Bakker23986e52011-04-24 08:57:21 +00001107 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001108 size_t len;
Paul Bakkerb00ca422012-09-25 12:10:00 +00001109 unsigned char *p, *end, *crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001110
Paul Bakker320a4b52009-03-28 18:52:39 +00001111 /*
1112 * Check for valid input
1113 */
1114 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001115 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker320a4b52009-03-28 18:52:39 +00001116
Paul Bakker6e339b52013-07-03 13:37:05 +02001117 p = (unsigned char *) polarssl_malloc( len = buflen );
Paul Bakker96743fc2011-02-12 14:30:57 +00001118
1119 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001120 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001121
1122 memcpy( p, buf, buflen );
1123
1124 buflen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001125
1126 crt->raw.p = p;
1127 crt->raw.len = len;
1128 end = p + len;
1129
1130 /*
1131 * Certificate ::= SEQUENCE {
1132 * tbsCertificate TBSCertificate,
1133 * signatureAlgorithm AlgorithmIdentifier,
1134 * signatureValue BIT STRING }
1135 */
1136 if( ( ret = asn1_get_tag( &p, end, &len,
1137 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1138 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001139 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001140 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001141 }
1142
Paul Bakkerb00ca422012-09-25 12:10:00 +00001143 if( len > (size_t) ( end - p ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001144 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001145 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001146 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001147 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001148 }
Paul Bakkerb00ca422012-09-25 12:10:00 +00001149 crt_end = p + len;
Paul Bakker42c65812013-06-24 19:21:59 +02001150
Paul Bakker5121ce52009-01-03 21:22:43 +00001151 /*
1152 * TBSCertificate ::= SEQUENCE {
1153 */
1154 crt->tbs.p = p;
1155
1156 if( ( ret = asn1_get_tag( &p, end, &len,
1157 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1158 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001159 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001160 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001161 }
1162
1163 end = p + len;
1164 crt->tbs.len = end - crt->tbs.p;
1165
1166 /*
1167 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1168 *
1169 * CertificateSerialNumber ::= INTEGER
1170 *
1171 * signature AlgorithmIdentifier
1172 */
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +02001173 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1174 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1175 ( ret = x509_get_alg( &p, end, &crt->sig_oid1, NULL ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001176 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001177 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001178 return( ret );
1179 }
1180
1181 crt->version++;
1182
1183 if( crt->version > 3 )
1184 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001185 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001186 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001187 }
1188
Paul Bakkerc70b9822013-04-07 22:00:46 +02001189 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_md,
1190 &crt->sig_pk ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001191 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001192 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001193 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001194 }
1195
1196 /*
1197 * issuer Name
1198 */
1199 crt->issuer_raw.p = p;
1200
1201 if( ( ret = asn1_get_tag( &p, end, &len,
1202 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1203 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001204 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001205 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001206 }
1207
1208 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1209 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001210 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001211 return( ret );
1212 }
1213
1214 crt->issuer_raw.len = p - crt->issuer_raw.p;
1215
1216 /*
1217 * Validity ::= SEQUENCE {
1218 * notBefore Time,
1219 * notAfter Time }
1220 *
1221 */
1222 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1223 &crt->valid_to ) ) != 0 )
1224 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001225 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001226 return( ret );
1227 }
1228
1229 /*
1230 * subject Name
1231 */
1232 crt->subject_raw.p = p;
1233
1234 if( ( ret = asn1_get_tag( &p, end, &len,
1235 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1236 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001237 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001238 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001239 }
1240
Paul Bakkercefb3962012-06-27 11:51:09 +00001241 if( len && ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001242 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001243 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001244 return( ret );
1245 }
1246
1247 crt->subject_raw.len = p - crt->subject_raw.p;
1248
1249 /*
1250 * SubjectPublicKeyInfo ::= SEQUENCE
1251 * algorithm AlgorithmIdentifier,
1252 * subjectPublicKey BIT STRING }
1253 */
1254 if( ( ret = asn1_get_tag( &p, end, &len,
1255 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1256 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001257 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001258 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001259 }
1260
1261 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1262 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1263 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001264 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001265 return( ret );
1266 }
1267
1268 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1269 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001270 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001271 return( ret );
1272 }
1273
1274 crt->rsa.len = mpi_size( &crt->rsa.N );
1275
1276 /*
1277 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1278 * -- If present, version shall be v2 or v3
1279 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1280 * -- If present, version shall be v2 or v3
1281 * extensions [3] EXPLICIT Extensions OPTIONAL
1282 * -- If present, version shall be v3
1283 */
1284 if( crt->version == 2 || crt->version == 3 )
1285 {
1286 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1287 if( ret != 0 )
1288 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001289 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001290 return( ret );
1291 }
1292 }
1293
1294 if( crt->version == 2 || crt->version == 3 )
1295 {
1296 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1297 if( ret != 0 )
1298 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001299 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001300 return( ret );
1301 }
1302 }
1303
1304 if( crt->version == 3 )
1305 {
Paul Bakker74111d32011-01-15 16:57:55 +00001306 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001307 if( ret != 0 )
1308 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001309 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001310 return( ret );
1311 }
1312 }
1313
1314 if( p != end )
1315 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001316 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001317 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001318 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001319 }
1320
Paul Bakkerb00ca422012-09-25 12:10:00 +00001321 end = crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001322
1323 /*
1324 * signatureAlgorithm AlgorithmIdentifier,
1325 * signatureValue BIT STRING
1326 */
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +02001327 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2, NULL ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001328 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001329 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001330 return( ret );
1331 }
1332
Paul Bakker535e97d2012-08-23 10:49:55 +00001333 if( crt->sig_oid1.len != crt->sig_oid2.len ||
1334 memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001335 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001336 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001337 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001338 }
1339
1340 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1341 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001342 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001343 return( ret );
1344 }
1345
1346 if( p != end )
1347 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001348 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001349 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001350 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001351 }
1352
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001353 return( 0 );
1354}
1355
1356/*
Paul Bakker42c65812013-06-24 19:21:59 +02001357 * Parse one X.509 certificate in DER format from a buffer and add them to a
1358 * chained list
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001359 */
Paul Bakker42c65812013-06-24 19:21:59 +02001360int x509parse_crt_der( x509_cert *chain, const unsigned char *buf, size_t buflen )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001361{
Paul Bakker42c65812013-06-24 19:21:59 +02001362 int ret;
1363 x509_cert *crt = chain, *prev = NULL;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001364
1365 /*
1366 * Check for valid input
1367 */
1368 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001369 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001370
1371 while( crt->version != 0 && crt->next != NULL )
1372 {
1373 prev = crt;
1374 crt = crt->next;
1375 }
1376
1377 /*
1378 * Add new certificate on the end of the chain if needed.
1379 */
1380 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001381 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001382 crt->next = (x509_cert *) polarssl_malloc( sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001383
Paul Bakker7d06ad22009-05-02 15:53:56 +00001384 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001385 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker320a4b52009-03-28 18:52:39 +00001386
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001387 prev = crt;
Paul Bakker7d06ad22009-05-02 15:53:56 +00001388 crt = crt->next;
1389 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001390 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001391
Paul Bakker42c65812013-06-24 19:21:59 +02001392 if( ( ret = x509parse_crt_der_core( crt, buf, buflen ) ) != 0 )
1393 {
1394 if( prev )
1395 prev->next = NULL;
1396
1397 if( crt != chain )
Paul Bakker6e339b52013-07-03 13:37:05 +02001398 polarssl_free( crt );
Paul Bakker42c65812013-06-24 19:21:59 +02001399
1400 return( ret );
1401 }
1402
1403 return( 0 );
1404}
1405
1406/*
1407 * Parse one or more PEM certificates from a buffer and add them to the chained list
1408 */
1409int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
1410{
1411 int ret, success = 0, first_error = 0, total_failed = 0;
1412 int buf_format = X509_FORMAT_DER;
1413
1414 /*
1415 * Check for valid input
1416 */
1417 if( chain == NULL || buf == NULL )
1418 return( POLARSSL_ERR_X509_INVALID_INPUT );
1419
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001420 /*
1421 * Determine buffer content. Buffer contains either one DER certificate or
1422 * one or more PEM certificates.
1423 */
1424#if defined(POLARSSL_PEM_C)
Paul Bakker3c2122f2013-06-24 19:03:14 +02001425 if( strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001426 buf_format = X509_FORMAT_PEM;
1427#endif
1428
1429 if( buf_format == X509_FORMAT_DER )
Paul Bakker42c65812013-06-24 19:21:59 +02001430 return x509parse_crt_der( chain, buf, buflen );
1431
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001432#if defined(POLARSSL_PEM_C)
1433 if( buf_format == X509_FORMAT_PEM )
1434 {
1435 pem_context pem;
1436
1437 while( buflen > 0 )
1438 {
1439 size_t use_len;
1440 pem_init( &pem );
1441
1442 ret = pem_read_buffer( &pem,
1443 "-----BEGIN CERTIFICATE-----",
1444 "-----END CERTIFICATE-----",
1445 buf, NULL, 0, &use_len );
1446
1447 if( ret == 0 )
1448 {
1449 /*
1450 * Was PEM encoded
1451 */
1452 buflen -= use_len;
1453 buf += use_len;
1454 }
Paul Bakker5ed3b342013-06-24 19:05:46 +02001455 else if( ret == POLARSSL_ERR_PEM_BAD_INPUT_DATA )
1456 {
1457 return( ret );
1458 }
Paul Bakker00b28602013-06-24 13:02:41 +02001459 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001460 {
1461 pem_free( &pem );
1462
Paul Bakker5ed3b342013-06-24 19:05:46 +02001463 /*
1464 * PEM header and footer were found
1465 */
1466 buflen -= use_len;
1467 buf += use_len;
1468
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001469 if( first_error == 0 )
1470 first_error = ret;
1471
1472 continue;
1473 }
1474 else
1475 break;
1476
Paul Bakker42c65812013-06-24 19:21:59 +02001477 ret = x509parse_crt_der( chain, pem.buf, pem.buflen );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001478
1479 pem_free( &pem );
1480
1481 if( ret != 0 )
1482 {
1483 /*
Paul Bakker42c65812013-06-24 19:21:59 +02001484 * Quit parsing on a memory error
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001485 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001486 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001487 return( ret );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001488
1489 if( first_error == 0 )
1490 first_error = ret;
1491
Paul Bakker42c65812013-06-24 19:21:59 +02001492 total_failed++;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001493 continue;
1494 }
1495
1496 success = 1;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001497 }
1498 }
1499#endif
1500
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001501 if( success )
Paul Bakker69e095c2011-12-10 21:55:01 +00001502 return( total_failed );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001503 else if( first_error )
1504 return( first_error );
1505 else
1506 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001507}
1508
1509/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001510 * Parse one or more CRLs and add them to the chained list
1511 */
Paul Bakker23986e52011-04-24 08:57:21 +00001512int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001513{
Paul Bakker23986e52011-04-24 08:57:21 +00001514 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001515 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001516 unsigned char *p, *end;
1517 x509_crl *crl;
Paul Bakker96743fc2011-02-12 14:30:57 +00001518#if defined(POLARSSL_PEM_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00001519 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001520 pem_context pem;
1521#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001522
1523 crl = chain;
1524
1525 /*
1526 * Check for valid input
1527 */
1528 if( crl == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001529 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001530
1531 while( crl->version != 0 && crl->next != NULL )
1532 crl = crl->next;
1533
1534 /*
1535 * Add new CRL on the end of the chain if needed.
1536 */
1537 if ( crl->version != 0 && crl->next == NULL)
1538 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001539 crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001540
Paul Bakker7d06ad22009-05-02 15:53:56 +00001541 if( crl->next == NULL )
1542 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001543 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001544 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001545 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001546
Paul Bakker7d06ad22009-05-02 15:53:56 +00001547 crl = crl->next;
1548 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001549 }
1550
Paul Bakker96743fc2011-02-12 14:30:57 +00001551#if defined(POLARSSL_PEM_C)
1552 pem_init( &pem );
1553 ret = pem_read_buffer( &pem,
1554 "-----BEGIN X509 CRL-----",
1555 "-----END X509 CRL-----",
1556 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001557
Paul Bakker96743fc2011-02-12 14:30:57 +00001558 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001559 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001560 /*
1561 * Was PEM encoded
1562 */
1563 buflen -= use_len;
1564 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001565
1566 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001567 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001568 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001569 p = pem.buf;
1570 pem.buf = NULL;
1571 len = pem.buflen;
1572 pem_free( &pem );
1573 }
Paul Bakker00b28602013-06-24 13:02:41 +02001574 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker96743fc2011-02-12 14:30:57 +00001575 {
1576 pem_free( &pem );
1577 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001578 }
1579 else
1580 {
1581 /*
1582 * nope, copy the raw DER data
1583 */
Paul Bakker6e339b52013-07-03 13:37:05 +02001584 p = (unsigned char *) polarssl_malloc( len = buflen );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001585
1586 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001587 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001588
1589 memcpy( p, buf, buflen );
1590
1591 buflen = 0;
1592 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001593#else
Paul Bakker6e339b52013-07-03 13:37:05 +02001594 p = (unsigned char *) polarssl_malloc( len = buflen );
Paul Bakker96743fc2011-02-12 14:30:57 +00001595
1596 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001597 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001598
1599 memcpy( p, buf, buflen );
1600
1601 buflen = 0;
1602#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001603
1604 crl->raw.p = p;
1605 crl->raw.len = len;
1606 end = p + len;
1607
1608 /*
1609 * CertificateList ::= SEQUENCE {
1610 * tbsCertList TBSCertList,
1611 * signatureAlgorithm AlgorithmIdentifier,
1612 * signatureValue BIT STRING }
1613 */
1614 if( ( ret = asn1_get_tag( &p, end, &len,
1615 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1616 {
1617 x509_crl_free( crl );
1618 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1619 }
1620
Paul Bakker23986e52011-04-24 08:57:21 +00001621 if( len != (size_t) ( end - p ) )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001622 {
1623 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001624 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001625 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1626 }
1627
1628 /*
1629 * TBSCertList ::= SEQUENCE {
1630 */
1631 crl->tbs.p = p;
1632
1633 if( ( ret = asn1_get_tag( &p, end, &len,
1634 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1635 {
1636 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001637 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001638 }
1639
1640 end = p + len;
1641 crl->tbs.len = end - crl->tbs.p;
1642
1643 /*
1644 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1645 * -- if present, MUST be v2
1646 *
1647 * signature AlgorithmIdentifier
1648 */
Paul Bakker3329d1f2011-10-12 09:55:01 +00001649 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +02001650 ( ret = x509_get_alg( &p, end, &crl->sig_oid1, NULL ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001651 {
1652 x509_crl_free( crl );
1653 return( ret );
1654 }
1655
1656 crl->version++;
1657
1658 if( crl->version > 2 )
1659 {
1660 x509_crl_free( crl );
1661 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1662 }
1663
Paul Bakkerc70b9822013-04-07 22:00:46 +02001664 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_md,
1665 &crl->sig_pk ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001666 {
1667 x509_crl_free( crl );
1668 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1669 }
1670
1671 /*
1672 * issuer Name
1673 */
1674 crl->issuer_raw.p = p;
1675
1676 if( ( ret = asn1_get_tag( &p, end, &len,
1677 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1678 {
1679 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001680 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001681 }
1682
1683 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1684 {
1685 x509_crl_free( crl );
1686 return( ret );
1687 }
1688
1689 crl->issuer_raw.len = p - crl->issuer_raw.p;
1690
1691 /*
1692 * thisUpdate Time
1693 * nextUpdate Time OPTIONAL
1694 */
Paul Bakker91200182010-02-18 21:26:15 +00001695 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001696 {
1697 x509_crl_free( crl );
1698 return( ret );
1699 }
1700
Paul Bakker91200182010-02-18 21:26:15 +00001701 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001702 {
Paul Bakker9d781402011-05-09 16:17:09 +00001703 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001704 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker9d781402011-05-09 16:17:09 +00001705 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001706 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001707 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001708 x509_crl_free( crl );
1709 return( ret );
1710 }
1711 }
1712
1713 /*
1714 * revokedCertificates SEQUENCE OF SEQUENCE {
1715 * userCertificate CertificateSerialNumber,
1716 * revocationDate Time,
1717 * crlEntryExtensions Extensions OPTIONAL
1718 * -- if present, MUST be v2
1719 * } OPTIONAL
1720 */
1721 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1722 {
1723 x509_crl_free( crl );
1724 return( ret );
1725 }
1726
1727 /*
1728 * crlExtensions EXPLICIT Extensions OPTIONAL
1729 * -- if present, MUST be v2
1730 */
1731 if( crl->version == 2 )
1732 {
1733 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1734
1735 if( ret != 0 )
1736 {
1737 x509_crl_free( crl );
1738 return( ret );
1739 }
1740 }
1741
1742 if( p != end )
1743 {
1744 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001745 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001746 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1747 }
1748
1749 end = crl->raw.p + crl->raw.len;
1750
1751 /*
1752 * signatureAlgorithm AlgorithmIdentifier,
1753 * signatureValue BIT STRING
1754 */
Manuel Pégourié-Gonnard444b4272013-07-01 15:27:48 +02001755 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2, NULL ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001756 {
1757 x509_crl_free( crl );
1758 return( ret );
1759 }
1760
Paul Bakker535e97d2012-08-23 10:49:55 +00001761 if( crl->sig_oid1.len != crl->sig_oid2.len ||
1762 memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001763 {
1764 x509_crl_free( crl );
1765 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1766 }
1767
1768 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1769 {
1770 x509_crl_free( crl );
1771 return( ret );
1772 }
1773
1774 if( p != end )
1775 {
1776 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001777 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001778 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1779 }
1780
1781 if( buflen > 0 )
1782 {
Paul Bakker6e339b52013-07-03 13:37:05 +02001783 crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001784
Paul Bakker7d06ad22009-05-02 15:53:56 +00001785 if( crl->next == NULL )
1786 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001787 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001788 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001789 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001790
Paul Bakker7d06ad22009-05-02 15:53:56 +00001791 crl = crl->next;
1792 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001793
1794 return( x509parse_crl( crl, buf, buflen ) );
1795 }
1796
1797 return( 0 );
1798}
1799
Paul Bakker335db3f2011-04-25 15:28:35 +00001800#if defined(POLARSSL_FS_IO)
Paul Bakkerd98030e2009-05-02 15:13:40 +00001801/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001802 * Load all data from a file into a given buffer.
1803 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02001804static int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001805{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001806 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001807
Paul Bakkerd98030e2009-05-02 15:13:40 +00001808 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001809 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001810
Paul Bakkerd98030e2009-05-02 15:13:40 +00001811 fseek( f, 0, SEEK_END );
1812 *n = (size_t) ftell( f );
1813 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001814
Paul Bakker6e339b52013-07-03 13:37:05 +02001815 if( ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
Paul Bakkerf6a19bd2013-05-14 13:26:51 +02001816 {
1817 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +00001818 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerf6a19bd2013-05-14 13:26:51 +02001819 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001820
Paul Bakkerd98030e2009-05-02 15:13:40 +00001821 if( fread( *buf, 1, *n, f ) != *n )
1822 {
1823 fclose( f );
Paul Bakker6e339b52013-07-03 13:37:05 +02001824 polarssl_free( *buf );
Paul Bakker69e095c2011-12-10 21:55:01 +00001825 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001826 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001827
Paul Bakkerd98030e2009-05-02 15:13:40 +00001828 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001829
Paul Bakkerd98030e2009-05-02 15:13:40 +00001830 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001831
Paul Bakkerd98030e2009-05-02 15:13:40 +00001832 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001833}
1834
1835/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001836 * Load one or more certificates and add them to the chained list
1837 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001838int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001839{
1840 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001841 size_t n;
1842 unsigned char *buf;
1843
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02001844 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00001845 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001846
Paul Bakker69e095c2011-12-10 21:55:01 +00001847 ret = x509parse_crt( chain, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001848
1849 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02001850 polarssl_free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001851
1852 return( ret );
1853}
1854
Paul Bakker8d914582012-06-04 12:46:42 +00001855int x509parse_crtpath( x509_cert *chain, const char *path )
1856{
1857 int ret = 0;
1858#if defined(_WIN32)
Paul Bakker3338b792012-10-01 21:13:10 +00001859 int w_ret;
1860 WCHAR szDir[MAX_PATH];
1861 char filename[MAX_PATH];
1862 char *p;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001863 int len = strlen( path );
Paul Bakker3338b792012-10-01 21:13:10 +00001864
Paul Bakker97872ac2012-11-02 12:53:26 +00001865 WIN32_FIND_DATAW file_data;
Paul Bakker8d914582012-06-04 12:46:42 +00001866 HANDLE hFind;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001867
1868 if( len > MAX_PATH - 3 )
1869 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker8d914582012-06-04 12:46:42 +00001870
Paul Bakker3338b792012-10-01 21:13:10 +00001871 memset( szDir, 0, sizeof(szDir) );
1872 memset( filename, 0, MAX_PATH );
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001873 memcpy( filename, path, len );
1874 filename[len++] = '\\';
1875 p = filename + len;
1876 filename[len++] = '*';
Paul Bakker3338b792012-10-01 21:13:10 +00001877
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001878 w_ret = MultiByteToWideChar( CP_ACP, 0, path, len, szDir, MAX_PATH - 3 );
Paul Bakker8d914582012-06-04 12:46:42 +00001879
Paul Bakker97872ac2012-11-02 12:53:26 +00001880 hFind = FindFirstFileW( szDir, &file_data );
Paul Bakker8d914582012-06-04 12:46:42 +00001881 if (hFind == INVALID_HANDLE_VALUE)
1882 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1883
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001884 len = MAX_PATH - len;
Paul Bakker8d914582012-06-04 12:46:42 +00001885 do
1886 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001887 memset( p, 0, len );
Paul Bakker3338b792012-10-01 21:13:10 +00001888
Paul Bakkere4791f32012-06-04 21:29:15 +00001889 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
Paul Bakker8d914582012-06-04 12:46:42 +00001890 continue;
1891
Paul Bakker3338b792012-10-01 21:13:10 +00001892 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
1893 lstrlenW(file_data.cFileName),
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001894 p, len - 1,
1895 NULL, NULL );
Paul Bakker8d914582012-06-04 12:46:42 +00001896
Paul Bakker3338b792012-10-01 21:13:10 +00001897 w_ret = x509parse_crtfile( chain, filename );
1898 if( w_ret < 0 )
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001899 ret++;
1900 else
1901 ret += w_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001902 }
Paul Bakker97872ac2012-11-02 12:53:26 +00001903 while( FindNextFileW( hFind, &file_data ) != 0 );
Paul Bakker8d914582012-06-04 12:46:42 +00001904
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001905 if (GetLastError() != ERROR_NO_MORE_FILES)
1906 ret = POLARSSL_ERR_X509_FILE_IO_ERROR;
Paul Bakker8d914582012-06-04 12:46:42 +00001907
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001908cleanup:
Paul Bakker8d914582012-06-04 12:46:42 +00001909 FindClose( hFind );
1910#else
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001911 int t_ret, i;
1912 struct stat sb;
1913 struct dirent entry, *result = NULL;
Paul Bakker8d914582012-06-04 12:46:42 +00001914 char entry_name[255];
1915 DIR *dir = opendir( path );
1916
1917 if( dir == NULL)
1918 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1919
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001920 while( ( t_ret = readdir_r( dir, &entry, &result ) ) == 0 )
Paul Bakker8d914582012-06-04 12:46:42 +00001921 {
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001922 if( result == NULL )
1923 break;
1924
1925 snprintf( entry_name, sizeof(entry_name), "%s/%s", path, entry.d_name );
1926
1927 i = stat( entry_name, &sb );
1928
1929 if( i == -1 )
1930 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1931
1932 if( !S_ISREG( sb.st_mode ) )
Paul Bakker8d914582012-06-04 12:46:42 +00001933 continue;
1934
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001935 // Ignore parse errors
1936 //
Paul Bakker8d914582012-06-04 12:46:42 +00001937 t_ret = x509parse_crtfile( chain, entry_name );
1938 if( t_ret < 0 )
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001939 ret++;
1940 else
1941 ret += t_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001942 }
1943 closedir( dir );
1944#endif
1945
1946 return( ret );
1947}
1948
Paul Bakkerd98030e2009-05-02 15:13:40 +00001949/*
1950 * Load one or more CRLs and add them to the chained list
1951 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001952int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001953{
1954 int ret;
1955 size_t n;
1956 unsigned char *buf;
1957
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02001958 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00001959 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001960
Paul Bakker27fdf462011-06-09 13:55:13 +00001961 ret = x509parse_crl( chain, buf, n );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001962
1963 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02001964 polarssl_free( buf );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001965
1966 return( ret );
1967}
1968
Paul Bakker5121ce52009-01-03 21:22:43 +00001969/*
Paul Bakker335db3f2011-04-25 15:28:35 +00001970 * Load and parse a private RSA key
1971 */
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02001972int x509parse_keyfile_rsa( rsa_context *rsa, const char *path, const char *pwd )
Paul Bakker335db3f2011-04-25 15:28:35 +00001973{
1974 int ret;
1975 size_t n;
1976 unsigned char *buf;
1977
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02001978 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00001979 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00001980
1981 if( pwd == NULL )
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02001982 ret = x509parse_key_rsa( rsa, buf, n, NULL, 0 );
Paul Bakker335db3f2011-04-25 15:28:35 +00001983 else
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02001984 ret = x509parse_key_rsa( rsa, buf, n,
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02001985 (const unsigned char *) pwd, strlen( pwd ) );
Paul Bakker335db3f2011-04-25 15:28:35 +00001986
1987 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02001988 polarssl_free( buf );
Paul Bakker335db3f2011-04-25 15:28:35 +00001989
1990 return( ret );
1991}
1992
1993/*
1994 * Load and parse a public RSA key
1995 */
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02001996int x509parse_public_keyfile_rsa( rsa_context *rsa, const char *path )
Paul Bakker335db3f2011-04-25 15:28:35 +00001997{
1998 int ret;
1999 size_t n;
2000 unsigned char *buf;
2001
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02002002 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker69e095c2011-12-10 21:55:01 +00002003 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002004
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002005 ret = x509parse_public_key_rsa( rsa, buf, n );
Paul Bakker335db3f2011-04-25 15:28:35 +00002006
2007 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02002008 polarssl_free( buf );
Paul Bakker335db3f2011-04-25 15:28:35 +00002009
2010 return( ret );
2011}
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002012
2013#if defined(POLARSSL_ECP_C)
2014/*
2015 * Load and parse a private EC key
2016 */
2017int x509parse_keyfile_ec( ecp_keypair *eckey,
2018 const char *path, const char *pwd )
2019{
2020 int ret;
2021 size_t n;
2022 unsigned char *buf;
2023
2024 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2025 return( ret );
2026
2027 if( pwd == NULL )
2028 ret = x509parse_key_ec( eckey, buf, n, NULL, 0 );
2029 else
2030 ret = x509parse_key_ec( eckey, buf, n,
2031 (const unsigned char *) pwd, strlen( pwd ) );
2032
2033 memset( buf, 0, n + 1 );
2034 free( buf );
2035
2036 return( ret );
2037}
2038
2039/*
2040 * Load and parse a public EC key
2041 */
2042int x509parse_public_keyfile_ec( ecp_keypair *eckey, const char *path )
2043{
2044 int ret;
2045 size_t n;
2046 unsigned char *buf;
2047
2048 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2049 return( ret );
2050
2051 ret = x509parse_public_key_ec( eckey, buf, n );
2052
2053 memset( buf, 0, n + 1 );
2054 free( buf );
2055
2056 return( ret );
2057}
2058#endif /* defined(POLARSSL_ECP_C) */
Paul Bakker335db3f2011-04-25 15:28:35 +00002059#endif /* POLARSSL_FS_IO */
2060
2061/*
Paul Bakkere2f50402013-06-24 19:00:59 +02002062 * Parse a PKCS#1 encoded private RSA key
Paul Bakker5121ce52009-01-03 21:22:43 +00002063 */
Paul Bakkere2f50402013-06-24 19:00:59 +02002064static int x509parse_key_pkcs1_der( rsa_context *rsa,
2065 const unsigned char *key,
2066 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +00002067{
Paul Bakker23986e52011-04-24 08:57:21 +00002068 int ret;
2069 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00002070 unsigned char *p, *end;
Paul Bakkered56b222011-07-13 11:26:43 +00002071
Paul Bakker96743fc2011-02-12 14:30:57 +00002072 p = (unsigned char *) key;
Paul Bakker96743fc2011-02-12 14:30:57 +00002073 end = p + keylen;
2074
Paul Bakker5121ce52009-01-03 21:22:43 +00002075 /*
Paul Bakkere2f50402013-06-24 19:00:59 +02002076 * This function parses the RSAPrivateKey (PKCS#1)
Paul Bakkered56b222011-07-13 11:26:43 +00002077 *
Paul Bakker5121ce52009-01-03 21:22:43 +00002078 * RSAPrivateKey ::= SEQUENCE {
2079 * version Version,
2080 * modulus INTEGER, -- n
2081 * publicExponent INTEGER, -- e
2082 * privateExponent INTEGER, -- d
2083 * prime1 INTEGER, -- p
2084 * prime2 INTEGER, -- q
2085 * exponent1 INTEGER, -- d mod (p-1)
2086 * exponent2 INTEGER, -- d mod (q-1)
2087 * coefficient INTEGER, -- (inverse of q) mod p
2088 * otherPrimeInfos OtherPrimeInfos OPTIONAL
2089 * }
2090 */
2091 if( ( ret = asn1_get_tag( &p, end, &len,
2092 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2093 {
Paul Bakker9d781402011-05-09 16:17:09 +00002094 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002095 }
2096
2097 end = p + len;
2098
2099 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2100 {
Paul Bakker9d781402011-05-09 16:17:09 +00002101 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002102 }
2103
2104 if( rsa->ver != 0 )
2105 {
Paul Bakker9d781402011-05-09 16:17:09 +00002106 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002107 }
2108
2109 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
2110 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
2111 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
2112 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
2113 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
2114 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
2115 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
2116 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
2117 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002118 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002119 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002120 }
2121
2122 rsa->len = mpi_size( &rsa->N );
2123
2124 if( p != end )
2125 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002126 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002127 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00002128 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002129 }
2130
2131 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2132 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002133 rsa_free( rsa );
2134 return( ret );
2135 }
2136
Paul Bakkere2f50402013-06-24 19:00:59 +02002137 return( 0 );
2138}
2139
2140/*
2141 * Parse an unencrypted PKCS#8 encoded private RSA key
2142 */
2143static int x509parse_key_pkcs8_unencrypted_der(
2144 rsa_context *rsa,
2145 const unsigned char *key,
2146 size_t keylen )
2147{
2148 int ret;
2149 size_t len;
2150 unsigned char *p, *end;
2151 x509_buf pk_alg_oid;
2152 pk_type_t pk_alg = POLARSSL_PK_NONE;
2153
2154 p = (unsigned char *) key;
2155 end = p + keylen;
2156
2157 /*
2158 * This function parses the PrivatKeyInfo object (PKCS#8)
2159 *
2160 * PrivateKeyInfo ::= SEQUENCE {
2161 * version Version,
2162 * algorithm AlgorithmIdentifier,
2163 * PrivateKey BIT STRING
2164 * }
2165 *
2166 * AlgorithmIdentifier ::= SEQUENCE {
2167 * algorithm OBJECT IDENTIFIER,
2168 * parameters ANY DEFINED BY algorithm OPTIONAL
2169 * }
2170 *
2171 * The PrivateKey BIT STRING is a PKCS#1 RSAPrivateKey
2172 */
2173 if( ( ret = asn1_get_tag( &p, end, &len,
2174 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2175 {
2176 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2177 }
2178
2179 end = p + len;
2180
2181 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2182 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2183
2184 if( rsa->ver != 0 )
2185 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2186
Paul Bakkerf8d018a2013-06-29 12:16:17 +02002187 if( ( ret = asn1_get_alg_null( &p, end, &pk_alg_oid ) ) != 0 )
Paul Bakkere2f50402013-06-24 19:00:59 +02002188 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2189
2190 /*
2191 * only RSA keys handled at this time
2192 */
2193 if( oid_get_pk_alg( &pk_alg_oid, &pk_alg ) != 0 )
2194 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
2195
2196 /*
2197 * Get the OCTET STRING and parse the PKCS#1 format inside
2198 */
2199 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2200 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2201
2202 if( ( end - p ) < 1 )
2203 {
2204 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
2205 POLARSSL_ERR_ASN1_OUT_OF_DATA );
2206 }
2207
2208 end = p + len;
2209
2210 if( ( ret = x509parse_key_pkcs1_der( rsa, p, end - p ) ) != 0 )
2211 return( ret );
2212
2213 return( 0 );
2214}
2215
2216/*
Paul Bakkerbda7cb72013-06-24 19:34:25 +02002217 * Parse an encrypted PKCS#8 encoded private RSA key
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002218 */
2219static int x509parse_key_pkcs8_encrypted_der(
2220 rsa_context *rsa,
2221 const unsigned char *key,
2222 size_t keylen,
2223 const unsigned char *pwd,
2224 size_t pwdlen )
2225{
2226 int ret;
2227 size_t len;
Paul Bakkerf8d018a2013-06-29 12:16:17 +02002228 unsigned char *p, *end;
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002229 x509_buf pbe_alg_oid, pbe_params;
2230 unsigned char buf[2048];
Paul Bakker7749a222013-06-28 17:28:20 +02002231#if defined(POLARSSL_PKCS12_C)
2232 cipher_type_t cipher_alg;
2233 md_type_t md_alg;
2234#endif
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002235
2236 memset(buf, 0, 2048);
2237
2238 p = (unsigned char *) key;
2239 end = p + keylen;
2240
Paul Bakker28144de2013-06-24 19:28:55 +02002241 if( pwdlen == 0 )
2242 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
2243
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002244 /*
2245 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
2246 *
2247 * EncryptedPrivateKeyInfo ::= SEQUENCE {
2248 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
2249 * encryptedData EncryptedData
2250 * }
2251 *
2252 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
2253 *
2254 * EncryptedData ::= OCTET STRING
2255 *
2256 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
2257 */
2258 if( ( ret = asn1_get_tag( &p, end, &len,
2259 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2260 {
2261 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2262 }
2263
2264 end = p + len;
2265
Paul Bakkerf8d018a2013-06-29 12:16:17 +02002266 if( ( ret = asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002267 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002268
2269 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2270 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2271
2272 // buf has been sized to 2048 bytes
2273 if( len > 2048 )
2274 return( POLARSSL_ERR_X509_INVALID_INPUT );
2275
2276 /*
2277 * Decrypt EncryptedData with appropriate PDE
2278 */
Paul Bakker38b50d72013-06-24 19:33:27 +02002279#if defined(POLARSSL_PKCS12_C)
Paul Bakker7749a222013-06-28 17:28:20 +02002280 if( oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002281 {
Paul Bakker38b50d72013-06-24 19:33:27 +02002282 if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
Paul Bakker7749a222013-06-28 17:28:20 +02002283 cipher_alg, md_alg,
Paul Bakker38b50d72013-06-24 19:33:27 +02002284 pwd, pwdlen, p, len, buf ) ) != 0 )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002285 {
Paul Bakker38b50d72013-06-24 19:33:27 +02002286 if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH )
2287 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2288
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002289 return( ret );
2290 }
2291 }
2292 else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) )
2293 {
2294 if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params,
2295 PKCS12_PBE_DECRYPT,
2296 pwd, pwdlen,
2297 p, len, buf ) ) != 0 )
2298 {
2299 return( ret );
2300 }
Paul Bakker38b50d72013-06-24 19:33:27 +02002301
2302 // Best guess for password mismatch when using RC4. If first tag is
2303 // not ASN1_CONSTRUCTED | ASN1_SEQUENCE
2304 //
2305 if( *buf != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
2306 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002307 }
Paul Bakker38b50d72013-06-24 19:33:27 +02002308 else
2309#endif /* POLARSSL_PKCS12_C */
Paul Bakker28144de2013-06-24 19:28:55 +02002310#if defined(POLARSSL_PKCS5_C)
Paul Bakker38b50d72013-06-24 19:33:27 +02002311 if( OID_CMP( OID_PKCS5_PBES2, &pbe_alg_oid ) )
Paul Bakker28144de2013-06-24 19:28:55 +02002312 {
2313 if( ( ret = pkcs5_pbes2( &pbe_params, PKCS5_DECRYPT, pwd, pwdlen,
2314 p, len, buf ) ) != 0 )
2315 {
2316 if( ret == POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH )
2317 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2318
2319 return( ret );
2320 }
2321 }
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002322 else
Paul Bakker38b50d72013-06-24 19:33:27 +02002323#endif /* POLARSSL_PKCS5_C */
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002324 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
2325
2326 return x509parse_key_pkcs8_unencrypted_der( rsa, buf, len );
2327}
2328
2329/*
Paul Bakkere2f50402013-06-24 19:00:59 +02002330 * Parse a private RSA key
2331 */
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002332int x509parse_key_rsa( rsa_context *rsa,
2333 const unsigned char *key, size_t keylen,
2334 const unsigned char *pwd, size_t pwdlen )
Paul Bakkere2f50402013-06-24 19:00:59 +02002335{
2336 int ret;
2337
Paul Bakker96743fc2011-02-12 14:30:57 +00002338#if defined(POLARSSL_PEM_C)
Paul Bakkere2f50402013-06-24 19:00:59 +02002339 size_t len;
2340 pem_context pem;
2341
2342 pem_init( &pem );
2343 ret = pem_read_buffer( &pem,
2344 "-----BEGIN RSA PRIVATE KEY-----",
2345 "-----END RSA PRIVATE KEY-----",
2346 key, pwd, pwdlen, &len );
2347 if( ret == 0 )
2348 {
2349 if( ( ret = x509parse_key_pkcs1_der( rsa, pem.buf, pem.buflen ) ) != 0 )
2350 {
2351 rsa_free( rsa );
2352 }
2353
2354 pem_free( &pem );
2355 return( ret );
2356 }
Paul Bakkera4232a72013-06-24 19:32:25 +02002357 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
2358 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2359 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
2360 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
Paul Bakkere2f50402013-06-24 19:00:59 +02002361 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkere2f50402013-06-24 19:00:59 +02002362 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002363
2364 ret = pem_read_buffer( &pem,
2365 "-----BEGIN PRIVATE KEY-----",
2366 "-----END PRIVATE KEY-----",
2367 key, NULL, 0, &len );
2368 if( ret == 0 )
2369 {
2370 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa,
2371 pem.buf, pem.buflen ) ) != 0 )
2372 {
2373 rsa_free( rsa );
2374 }
2375
2376 pem_free( &pem );
2377 return( ret );
2378 }
2379 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkere2f50402013-06-24 19:00:59 +02002380 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002381
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002382 ret = pem_read_buffer( &pem,
2383 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
2384 "-----END ENCRYPTED PRIVATE KEY-----",
2385 key, NULL, 0, &len );
2386 if( ret == 0 )
2387 {
2388 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa,
2389 pem.buf, pem.buflen,
2390 pwd, pwdlen ) ) != 0 )
2391 {
2392 rsa_free( rsa );
2393 }
2394
2395 pem_free( &pem );
2396 return( ret );
2397 }
2398 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002399 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002400#else
2401 ((void) pwd);
2402 ((void) pwdlen);
2403#endif /* POLARSSL_PEM_C */
2404
2405 // At this point we only know it's not a PEM formatted key. Could be any
2406 // of the known DER encoded private key formats
2407 //
2408 // We try the different DER format parsers to see if one passes without
2409 // error
2410 //
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002411 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa, key, keylen,
2412 pwd, pwdlen ) ) == 0 )
Paul Bakkere2f50402013-06-24 19:00:59 +02002413 {
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002414 return( 0 );
Paul Bakkere2f50402013-06-24 19:00:59 +02002415 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002416
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002417 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002418
2419 if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH )
2420 {
2421 return( ret );
2422 }
2423
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002424 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa, key, keylen ) ) == 0 )
2425 return( 0 );
2426
2427 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002428
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002429 if( ( ret = x509parse_key_pkcs1_der( rsa, key, keylen ) ) == 0 )
2430 return( 0 );
2431
2432 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002433
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002434 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00002435}
2436
2437/*
Paul Bakker53019ae2011-03-25 13:58:48 +00002438 * Parse a public RSA key
2439 */
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02002440int x509parse_public_key_rsa( rsa_context *rsa,
2441 const unsigned char *key, size_t keylen )
Paul Bakker53019ae2011-03-25 13:58:48 +00002442{
Paul Bakker23986e52011-04-24 08:57:21 +00002443 int ret;
2444 size_t len;
Paul Bakker53019ae2011-03-25 13:58:48 +00002445 unsigned char *p, *end;
2446 x509_buf alg_oid;
2447#if defined(POLARSSL_PEM_C)
2448 pem_context pem;
2449
2450 pem_init( &pem );
2451 ret = pem_read_buffer( &pem,
2452 "-----BEGIN PUBLIC KEY-----",
2453 "-----END PUBLIC KEY-----",
2454 key, NULL, 0, &len );
2455
2456 if( ret == 0 )
2457 {
2458 /*
2459 * Was PEM encoded
2460 */
2461 keylen = pem.buflen;
2462 }
Paul Bakker00b28602013-06-24 13:02:41 +02002463 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker53019ae2011-03-25 13:58:48 +00002464 {
2465 pem_free( &pem );
2466 return( ret );
2467 }
2468
2469 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2470#else
2471 p = (unsigned char *) key;
2472#endif
2473 end = p + keylen;
2474
2475 /*
2476 * PublicKeyInfo ::= SEQUENCE {
2477 * algorithm AlgorithmIdentifier,
2478 * PublicKey BIT STRING
2479 * }
2480 *
2481 * AlgorithmIdentifier ::= SEQUENCE {
2482 * algorithm OBJECT IDENTIFIER,
2483 * parameters ANY DEFINED BY algorithm OPTIONAL
2484 * }
2485 *
2486 * RSAPublicKey ::= SEQUENCE {
2487 * modulus INTEGER, -- n
2488 * publicExponent INTEGER -- e
2489 * }
2490 */
2491
2492 if( ( ret = asn1_get_tag( &p, end, &len,
2493 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2494 {
2495#if defined(POLARSSL_PEM_C)
2496 pem_free( &pem );
2497#endif
2498 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002499 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002500 }
2501
2502 if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
2503 {
2504#if defined(POLARSSL_PEM_C)
2505 pem_free( &pem );
2506#endif
2507 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002508 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002509 }
2510
2511 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
2512 {
2513#if defined(POLARSSL_PEM_C)
2514 pem_free( &pem );
2515#endif
2516 rsa_free( rsa );
2517 return( ret );
2518 }
2519
2520 rsa->len = mpi_size( &rsa->N );
2521
2522#if defined(POLARSSL_PEM_C)
2523 pem_free( &pem );
2524#endif
2525
2526 return( 0 );
2527}
2528
Manuel Pégourié-Gonnard26833c22013-06-27 11:27:58 +02002529#if defined(POLARSSL_ECP_C)
2530/*
2531 * Parse a private EC key
2532 */
2533int x509parse_key_ec( ecp_keypair *eckey,
2534 const unsigned char *key, size_t keylen,
2535 const unsigned char *pwd, size_t pwdlen )
2536{
2537 int ret;
2538
2539#if defined(POLARSSL_PEM_C)
2540 size_t len;
2541 pem_context pem;
2542
2543 pem_init( &pem );
2544 /* TODO: get list of correct PEM headers */
2545 ret = pem_read_buffer( &pem,
2546 "-----BEGIN EC PRIVATE KEY-----",
2547 "-----END EC PRIVATE KEY-----",
2548 key, pwd, pwdlen, &len );
2549 if( ret == 0 )
2550 {
2551 /* TODO: write der decoding function
2552 if( ( ret = x509parse_key_pkcs8_encrypted_der( eckey,
2553 pem.buf, pem.buflen,
2554 pwd, pwdlen ) ) != 0 )
2555 {
2556 ecp_keypair_free( eckey );
2557 }
2558 */
2559
2560 pem_free( &pem );
2561 return( ret );
2562 }
2563 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
2564 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2565 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
2566 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
2567 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2568 return( ret );
2569
2570 /* TODO: now repeat with other valid PEM headers */
2571
2572#else
2573 ((void) pwd);
2574 ((void) pwdlen);
2575#endif /* POLARSSL_PEM_C */
2576
2577 ((void) keylen);
2578 /* TODO: write der decoding functions (encrypted, unencnrypted)
2579 if( ( ret = x509parse_key_pkcs8_encrypted_der( eckey, key, keylen,
2580 pwd, pwdlen ) ) == 0 )
2581 {
2582 return( 0 );
2583 }
2584
2585 ecp_keypair_free( eckey );
2586
2587 if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH )
2588 {
2589 return( ret );
2590 }
2591
2592 if( ( ret = x509parse_key_pkcs8_unencrypted_der( eckey, key, keylen ) )
2593 == 0 )
2594 {
2595 return( 0 );
2596 }
2597 */
2598
2599 ecp_keypair_free( eckey );
2600
2601 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
2602}
2603
2604/*
2605 * Parse a public EC key
2606 */
2607int x509parse_public_key_ec( ecp_keypair *eckey,
2608 const unsigned char *key, size_t keylen )
2609{
2610 int ret;
2611 size_t len;
2612 unsigned char *p, *end;
2613 x509_buf alg_oid;
2614#if defined(POLARSSL_PEM_C)
2615 pem_context pem;
2616
2617 pem_init( &pem );
2618 ret = pem_read_buffer( &pem, /* TODO: check header */
2619 "-----BEGIN PUBLIC KEY-----",
2620 "-----END PUBLIC KEY-----",
2621 key, NULL, 0, &len );
2622
2623 if( ret == 0 )
2624 {
2625 /*
2626 * Was PEM encoded
2627 */
2628 keylen = pem.buflen;
2629 }
2630 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2631 {
2632 pem_free( &pem );
2633 return( ret );
2634 }
2635
2636 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2637#else
2638 p = (unsigned char *) key;
2639#endif
2640 end = p + keylen;
2641
2642 /* TODO: parse key */
2643 (void) alg_oid;
2644 (void) end;
2645 (void) eckey;
2646
2647 if( ( ret = ecp_check_pubkey( &eckey->grp, &eckey->Q ) ) != 0 )
2648 {
2649#if defined(POLARSSL_PEM_C)
2650 pem_free( &pem );
2651#endif
2652 ecp_keypair_free( eckey );
2653 return( ret );
2654 }
2655
2656#if defined(POLARSSL_PEM_C)
2657 pem_free( &pem );
2658#endif
2659
2660 return( 0 );
2661}
2662#endif /* defined(POLARSSL_ECP_C) */
2663
Paul Bakkereaa89f82011-04-04 21:36:15 +00002664#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00002665/*
Paul Bakker1b57b062011-01-06 15:48:19 +00002666 * Parse DHM parameters
2667 */
Paul Bakker23986e52011-04-24 08:57:21 +00002668int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
Paul Bakker1b57b062011-01-06 15:48:19 +00002669{
Paul Bakker23986e52011-04-24 08:57:21 +00002670 int ret;
2671 size_t len;
Paul Bakker1b57b062011-01-06 15:48:19 +00002672 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00002673#if defined(POLARSSL_PEM_C)
2674 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00002675
Paul Bakker96743fc2011-02-12 14:30:57 +00002676 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00002677
Paul Bakker96743fc2011-02-12 14:30:57 +00002678 ret = pem_read_buffer( &pem,
2679 "-----BEGIN DH PARAMETERS-----",
2680 "-----END DH PARAMETERS-----",
2681 dhmin, NULL, 0, &dhminlen );
2682
2683 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00002684 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002685 /*
2686 * Was PEM encoded
2687 */
2688 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00002689 }
Paul Bakker00b28602013-06-24 13:02:41 +02002690 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00002691 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002692 pem_free( &pem );
2693 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002694 }
2695
Paul Bakker96743fc2011-02-12 14:30:57 +00002696 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
2697#else
2698 p = (unsigned char *) dhmin;
2699#endif
2700 end = p + dhminlen;
2701
Paul Bakker1b57b062011-01-06 15:48:19 +00002702 memset( dhm, 0, sizeof( dhm_context ) );
2703
Paul Bakker1b57b062011-01-06 15:48:19 +00002704 /*
2705 * DHParams ::= SEQUENCE {
2706 * prime INTEGER, -- P
2707 * generator INTEGER, -- g
2708 * }
2709 */
2710 if( ( ret = asn1_get_tag( &p, end, &len,
2711 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2712 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002713#if defined(POLARSSL_PEM_C)
2714 pem_free( &pem );
2715#endif
Paul Bakker9d781402011-05-09 16:17:09 +00002716 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002717 }
2718
2719 end = p + len;
2720
2721 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
2722 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
2723 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002724#if defined(POLARSSL_PEM_C)
2725 pem_free( &pem );
2726#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002727 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002728 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002729 }
2730
2731 if( p != end )
2732 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002733#if defined(POLARSSL_PEM_C)
2734 pem_free( &pem );
2735#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002736 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002737 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker1b57b062011-01-06 15:48:19 +00002738 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
2739 }
2740
Paul Bakker96743fc2011-02-12 14:30:57 +00002741#if defined(POLARSSL_PEM_C)
2742 pem_free( &pem );
2743#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002744
2745 return( 0 );
2746}
2747
Paul Bakker335db3f2011-04-25 15:28:35 +00002748#if defined(POLARSSL_FS_IO)
Paul Bakker1b57b062011-01-06 15:48:19 +00002749/*
Manuel Pégourié-Gonnard4250a1f2013-06-27 13:00:00 +02002750 * Load and parse DHM parameters
Paul Bakker1b57b062011-01-06 15:48:19 +00002751 */
2752int x509parse_dhmfile( dhm_context *dhm, const char *path )
2753{
2754 int ret;
2755 size_t n;
2756 unsigned char *buf;
2757
Paul Bakker69e095c2011-12-10 21:55:01 +00002758 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
2759 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002760
Paul Bakker27fdf462011-06-09 13:55:13 +00002761 ret = x509parse_dhm( dhm, buf, n );
Paul Bakker1b57b062011-01-06 15:48:19 +00002762
2763 memset( buf, 0, n + 1 );
Paul Bakker6e339b52013-07-03 13:37:05 +02002764 polarssl_free( buf );
Paul Bakker1b57b062011-01-06 15:48:19 +00002765
2766 return( ret );
2767}
Paul Bakker335db3f2011-04-25 15:28:35 +00002768#endif /* POLARSSL_FS_IO */
Paul Bakkereaa89f82011-04-04 21:36:15 +00002769#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00002770
Paul Bakker5121ce52009-01-03 21:22:43 +00002771#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002772#include <stdarg.h>
2773
2774#if !defined vsnprintf
2775#define vsnprintf _vsnprintf
2776#endif // vsnprintf
2777
2778/*
2779 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2780 * Result value is not size of buffer needed, but -1 if no fit is possible.
2781 *
2782 * This fuction tries to 'fix' this by at least suggesting enlarging the
2783 * size by 20.
2784 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02002785static int compat_snprintf(char *str, size_t size, const char *format, ...)
Paul Bakkerd98030e2009-05-02 15:13:40 +00002786{
2787 va_list ap;
2788 int res = -1;
2789
2790 va_start( ap, format );
2791
2792 res = vsnprintf( str, size, format, ap );
2793
2794 va_end( ap );
2795
2796 // No quick fix possible
2797 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00002798 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002799
2800 return res;
2801}
2802
2803#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002804#endif
2805
Paul Bakkerd98030e2009-05-02 15:13:40 +00002806#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2807
2808#define SAFE_SNPRINTF() \
2809{ \
2810 if( ret == -1 ) \
2811 return( -1 ); \
2812 \
Paul Bakker23986e52011-04-24 08:57:21 +00002813 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002814 p[n - 1] = '\0'; \
2815 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2816 } \
2817 \
Paul Bakker23986e52011-04-24 08:57:21 +00002818 n -= (unsigned int) ret; \
2819 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002820}
2821
Paul Bakker5121ce52009-01-03 21:22:43 +00002822/*
2823 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002824 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002825 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002826int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002827{
Paul Bakker23986e52011-04-24 08:57:21 +00002828 int ret;
2829 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002830 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002831 const x509_name *name;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002832 const char *short_name = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00002833 char s[128], *p;
2834
2835 memset( s, 0, sizeof( s ) );
2836
2837 name = dn;
2838 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002839 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002840
2841 while( name != NULL )
2842 {
Paul Bakkercefb3962012-06-27 11:51:09 +00002843 if( !name->oid.p )
2844 {
2845 name = name->next;
2846 continue;
2847 }
2848
Paul Bakker74111d32011-01-15 16:57:55 +00002849 if( name != dn )
2850 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002851 ret = snprintf( p, n, ", " );
2852 SAFE_SNPRINTF();
2853 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002854
Paul Bakkerc70b9822013-04-07 22:00:46 +02002855 ret = oid_get_attr_short_name( &name->oid, &short_name );
Paul Bakker5121ce52009-01-03 21:22:43 +00002856
Paul Bakkerc70b9822013-04-07 22:00:46 +02002857 if( ret == 0 )
2858 ret = snprintf( p, n, "%s=", short_name );
Paul Bakker5121ce52009-01-03 21:22:43 +00002859 else
Paul Bakkerd98030e2009-05-02 15:13:40 +00002860 ret = snprintf( p, n, "\?\?=" );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002861 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002862
2863 for( i = 0; i < name->val.len; i++ )
2864 {
Paul Bakker27fdf462011-06-09 13:55:13 +00002865 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002866 break;
2867
2868 c = name->val.p[i];
2869 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2870 s[i] = '?';
2871 else s[i] = c;
2872 }
2873 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002874 ret = snprintf( p, n, "%s", s );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002875 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002876 name = name->next;
2877 }
2878
Paul Bakker23986e52011-04-24 08:57:21 +00002879 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002880}
2881
2882/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002883 * Store the serial in printable form into buf; no more
2884 * than size characters will be written
2885 */
2886int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2887{
Paul Bakker23986e52011-04-24 08:57:21 +00002888 int ret;
2889 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00002890 char *p;
2891
2892 p = buf;
2893 n = size;
2894
2895 nr = ( serial->len <= 32 )
Paul Bakker03c7c252011-11-25 12:37:37 +00002896 ? serial->len : 28;
Paul Bakkerdd476992011-01-16 21:34:59 +00002897
2898 for( i = 0; i < nr; i++ )
2899 {
Paul Bakker93048802011-12-05 14:38:06 +00002900 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002901 continue;
2902
Paul Bakkerdd476992011-01-16 21:34:59 +00002903 ret = snprintf( p, n, "%02X%s",
2904 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2905 SAFE_SNPRINTF();
2906 }
2907
Paul Bakker03c7c252011-11-25 12:37:37 +00002908 if( nr != serial->len )
2909 {
2910 ret = snprintf( p, n, "...." );
2911 SAFE_SNPRINTF();
2912 }
2913
Paul Bakker23986e52011-04-24 08:57:21 +00002914 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00002915}
2916
2917/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002918 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002919 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002920int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2921 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002922{
Paul Bakker23986e52011-04-24 08:57:21 +00002923 int ret;
2924 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002925 char *p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002926 const char *desc = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00002927
2928 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002929 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002930
Paul Bakkerd98030e2009-05-02 15:13:40 +00002931 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002932 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002933 SAFE_SNPRINTF();
2934 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002935 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002936 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002937
Paul Bakkerdd476992011-01-16 21:34:59 +00002938 ret = x509parse_serial_gets( p, n, &crt->serial);
2939 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002940
Paul Bakkerd98030e2009-05-02 15:13:40 +00002941 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2942 SAFE_SNPRINTF();
2943 ret = x509parse_dn_gets( p, n, &crt->issuer );
2944 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002945
Paul Bakkerd98030e2009-05-02 15:13:40 +00002946 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2947 SAFE_SNPRINTF();
2948 ret = x509parse_dn_gets( p, n, &crt->subject );
2949 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002950
Paul Bakkerd98030e2009-05-02 15:13:40 +00002951 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002952 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2953 crt->valid_from.year, crt->valid_from.mon,
2954 crt->valid_from.day, crt->valid_from.hour,
2955 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002956 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002957
Paul Bakkerd98030e2009-05-02 15:13:40 +00002958 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002959 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2960 crt->valid_to.year, crt->valid_to.mon,
2961 crt->valid_to.day, crt->valid_to.hour,
2962 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002963 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002964
Paul Bakkerc70b9822013-04-07 22:00:46 +02002965 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002966 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002967
Paul Bakkerc70b9822013-04-07 22:00:46 +02002968 ret = oid_get_sig_alg_desc( &crt->sig_oid1, &desc );
2969 if( ret != 0 )
2970 ret = snprintf( p, n, "???" );
2971 else
2972 ret = snprintf( p, n, desc );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002973 SAFE_SNPRINTF();
2974
2975 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
Paul Bakker5c2364c2012-10-01 14:41:15 +00002976 (int) crt->rsa.N.n * (int) sizeof( t_uint ) * 8 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002977 SAFE_SNPRINTF();
2978
Paul Bakker23986e52011-04-24 08:57:21 +00002979 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002980}
2981
Paul Bakker74111d32011-01-15 16:57:55 +00002982/*
2983 * Return an informational string describing the given OID
2984 */
2985const char *x509_oid_get_description( x509_buf *oid )
2986{
Paul Bakkerc70b9822013-04-07 22:00:46 +02002987 const char *desc = NULL;
2988 int ret;
Paul Bakker74111d32011-01-15 16:57:55 +00002989
Paul Bakkerc70b9822013-04-07 22:00:46 +02002990 ret = oid_get_extended_key_usage( oid, &desc );
Paul Bakker74111d32011-01-15 16:57:55 +00002991
Paul Bakkerc70b9822013-04-07 22:00:46 +02002992 if( ret != 0 )
2993 return( NULL );
Paul Bakker74111d32011-01-15 16:57:55 +00002994
Paul Bakkerc70b9822013-04-07 22:00:46 +02002995 return( desc );
Paul Bakker74111d32011-01-15 16:57:55 +00002996}
2997
2998/* Return the x.y.z.... style numeric string for the given OID */
2999int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
3000{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003001 return oid_get_numeric_string( buf, size, oid );
Paul Bakker74111d32011-01-15 16:57:55 +00003002}
3003
Paul Bakkerd98030e2009-05-02 15:13:40 +00003004/*
3005 * Return an informational string about the CRL.
3006 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003007int x509parse_crl_info( char *buf, size_t size, const char *prefix,
3008 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003009{
Paul Bakker23986e52011-04-24 08:57:21 +00003010 int ret;
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003011 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003012 char *p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003013 const char *desc;
Paul Bakkerff60ee62010-03-16 21:09:09 +00003014 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003015
3016 p = buf;
3017 n = size;
3018
3019 ret = snprintf( p, n, "%sCRL version : %d",
3020 prefix, crl->version );
3021 SAFE_SNPRINTF();
3022
3023 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
3024 SAFE_SNPRINTF();
3025 ret = x509parse_dn_gets( p, n, &crl->issuer );
3026 SAFE_SNPRINTF();
3027
3028 ret = snprintf( p, n, "\n%sthis update : " \
3029 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3030 crl->this_update.year, crl->this_update.mon,
3031 crl->this_update.day, crl->this_update.hour,
3032 crl->this_update.min, crl->this_update.sec );
3033 SAFE_SNPRINTF();
3034
3035 ret = snprintf( p, n, "\n%snext update : " \
3036 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3037 crl->next_update.year, crl->next_update.mon,
3038 crl->next_update.day, crl->next_update.hour,
3039 crl->next_update.min, crl->next_update.sec );
3040 SAFE_SNPRINTF();
3041
3042 entry = &crl->entry;
3043
3044 ret = snprintf( p, n, "\n%sRevoked certificates:",
3045 prefix );
3046 SAFE_SNPRINTF();
3047
Paul Bakker9be19372009-07-27 20:21:53 +00003048 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003049 {
3050 ret = snprintf( p, n, "\n%sserial number: ",
3051 prefix );
3052 SAFE_SNPRINTF();
3053
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003054 ret = x509parse_serial_gets( p, n, &entry->serial);
3055 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003056
Paul Bakkerd98030e2009-05-02 15:13:40 +00003057 ret = snprintf( p, n, " revocation date: " \
3058 "%04d-%02d-%02d %02d:%02d:%02d",
3059 entry->revocation_date.year, entry->revocation_date.mon,
3060 entry->revocation_date.day, entry->revocation_date.hour,
3061 entry->revocation_date.min, entry->revocation_date.sec );
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003062 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003063
3064 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003065 }
3066
Paul Bakkerc70b9822013-04-07 22:00:46 +02003067 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003068 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003069
Paul Bakkerc70b9822013-04-07 22:00:46 +02003070 ret = oid_get_sig_alg_desc( &crl->sig_oid1, &desc );
3071 if( ret != 0 )
3072 ret = snprintf( p, n, "???" );
3073 else
3074 ret = snprintf( p, n, desc );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003075 SAFE_SNPRINTF();
3076
Paul Bakker1e27bb22009-07-19 20:25:25 +00003077 ret = snprintf( p, n, "\n" );
3078 SAFE_SNPRINTF();
3079
Paul Bakker23986e52011-04-24 08:57:21 +00003080 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003081}
3082
3083/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00003084 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00003085 */
Paul Bakkerfa9b1002013-07-03 15:31:03 +02003086#if defined(POLARSSL_HAVE_TIME)
Paul Bakkerff60ee62010-03-16 21:09:09 +00003087int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00003088{
Paul Bakkercce9d772011-11-18 14:26:47 +00003089 int year, mon, day;
3090 int hour, min, sec;
3091
3092#if defined(_WIN32)
3093 SYSTEMTIME st;
3094
3095 GetLocalTime(&st);
3096
3097 year = st.wYear;
3098 mon = st.wMonth;
3099 day = st.wDay;
3100 hour = st.wHour;
3101 min = st.wMinute;
3102 sec = st.wSecond;
3103#else
Paul Bakker5121ce52009-01-03 21:22:43 +00003104 struct tm *lt;
3105 time_t tt;
3106
3107 tt = time( NULL );
3108 lt = localtime( &tt );
3109
Paul Bakkercce9d772011-11-18 14:26:47 +00003110 year = lt->tm_year + 1900;
3111 mon = lt->tm_mon + 1;
3112 day = lt->tm_mday;
3113 hour = lt->tm_hour;
3114 min = lt->tm_min;
3115 sec = lt->tm_sec;
3116#endif
3117
3118 if( year > to->year )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003119 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003120
Paul Bakkercce9d772011-11-18 14:26:47 +00003121 if( year == to->year &&
3122 mon > to->mon )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003123 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003124
Paul Bakkercce9d772011-11-18 14:26:47 +00003125 if( year == to->year &&
3126 mon == to->mon &&
3127 day > to->day )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003128 return( 1 );
3129
Paul Bakkercce9d772011-11-18 14:26:47 +00003130 if( year == to->year &&
3131 mon == to->mon &&
3132 day == to->day &&
3133 hour > to->hour )
Paul Bakkerb6194992011-01-16 21:40:22 +00003134 return( 1 );
3135
Paul Bakkercce9d772011-11-18 14:26:47 +00003136 if( year == to->year &&
3137 mon == to->mon &&
3138 day == to->day &&
3139 hour == to->hour &&
3140 min > to->min )
Paul Bakkerb6194992011-01-16 21:40:22 +00003141 return( 1 );
3142
Paul Bakkercce9d772011-11-18 14:26:47 +00003143 if( year == to->year &&
3144 mon == to->mon &&
3145 day == to->day &&
3146 hour == to->hour &&
3147 min == to->min &&
3148 sec > to->sec )
Paul Bakkerb6194992011-01-16 21:40:22 +00003149 return( 1 );
3150
Paul Bakker40ea7de2009-05-03 10:18:48 +00003151 return( 0 );
3152}
Paul Bakkerfa9b1002013-07-03 15:31:03 +02003153#else /* POLARSSL_HAVE_TIME */
3154int x509parse_time_expired( const x509_time *to )
3155{
3156 ((void) to);
3157 return( 0 );
3158}
3159#endif /* POLARSSL_HAVE_TIME */
Paul Bakker40ea7de2009-05-03 10:18:48 +00003160
3161/*
3162 * Return 1 if the certificate is revoked, or 0 otherwise.
3163 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003164int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003165{
Paul Bakkerff60ee62010-03-16 21:09:09 +00003166 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00003167
3168 while( cur != NULL && cur->serial.len != 0 )
3169 {
Paul Bakkera056efc2011-01-16 21:38:35 +00003170 if( crt->serial.len == cur->serial.len &&
3171 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003172 {
3173 if( x509parse_time_expired( &cur->revocation_date ) )
3174 return( 1 );
3175 }
3176
3177 cur = cur->next;
3178 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003179
3180 return( 0 );
3181}
3182
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003183/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00003184 * Check that the given certificate is valid accoring to the CRL.
3185 */
3186static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
3187 x509_crl *crl_list)
3188{
3189 int flags = 0;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003190 unsigned char hash[POLARSSL_MD_MAX_SIZE];
3191 const md_info_t *md_info;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003192
Paul Bakker915275b2012-09-28 07:10:55 +00003193 if( ca == NULL )
3194 return( flags );
3195
Paul Bakker76fd75a2011-01-16 21:12:10 +00003196 /*
3197 * TODO: What happens if no CRL is present?
3198 * Suggestion: Revocation state should be unknown if no CRL is present.
3199 * For backwards compatibility this is not yet implemented.
3200 */
3201
Paul Bakker915275b2012-09-28 07:10:55 +00003202 while( crl_list != NULL )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003203 {
Paul Bakker915275b2012-09-28 07:10:55 +00003204 if( crl_list->version == 0 ||
3205 crl_list->issuer_raw.len != ca->subject_raw.len ||
Paul Bakker76fd75a2011-01-16 21:12:10 +00003206 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
3207 crl_list->issuer_raw.len ) != 0 )
3208 {
3209 crl_list = crl_list->next;
3210 continue;
3211 }
3212
3213 /*
3214 * Check if CRL is correctly signed by the trusted CA
3215 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02003216 md_info = md_info_from_type( crl_list->sig_md );
3217 if( md_info == NULL )
3218 {
3219 /*
3220 * Cannot check 'unknown' hash
3221 */
3222 flags |= BADCRL_NOT_TRUSTED;
3223 break;
3224 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00003225
Paul Bakkerc70b9822013-04-07 22:00:46 +02003226 md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
Paul Bakker76fd75a2011-01-16 21:12:10 +00003227
Paul Bakkerc70b9822013-04-07 22:00:46 +02003228 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, crl_list->sig_md,
Paul Bakker76fd75a2011-01-16 21:12:10 +00003229 0, hash, crl_list->sig.p ) == 0 )
3230 {
3231 /*
3232 * CRL is not trusted
3233 */
3234 flags |= BADCRL_NOT_TRUSTED;
3235 break;
3236 }
3237
3238 /*
3239 * Check for validity of CRL (Do not drop out)
3240 */
3241 if( x509parse_time_expired( &crl_list->next_update ) )
3242 flags |= BADCRL_EXPIRED;
3243
3244 /*
3245 * Check if certificate is revoked
3246 */
3247 if( x509parse_revoked(crt, crl_list) )
3248 {
3249 flags |= BADCERT_REVOKED;
3250 break;
3251 }
3252
3253 crl_list = crl_list->next;
3254 }
3255 return flags;
3256}
3257
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02003258static int x509_wildcard_verify( const char *cn, x509_buf *name )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003259{
3260 size_t i;
3261 size_t cn_idx = 0;
3262
Paul Bakker57b12982012-02-11 17:38:38 +00003263 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003264 return( 0 );
3265
3266 for( i = 0; i < strlen( cn ); ++i )
3267 {
3268 if( cn[i] == '.' )
3269 {
3270 cn_idx = i;
3271 break;
3272 }
3273 }
3274
3275 if( cn_idx == 0 )
3276 return( 0 );
3277
Paul Bakker535e97d2012-08-23 10:49:55 +00003278 if( strlen( cn ) - cn_idx == name->len - 1 &&
3279 memcmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003280 {
3281 return( 1 );
3282 }
3283
3284 return( 0 );
3285}
3286
Paul Bakker915275b2012-09-28 07:10:55 +00003287static int x509parse_verify_top(
3288 x509_cert *child, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003289 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003290 int (*f_vrfy)(void *, x509_cert *, int, int *),
3291 void *p_vrfy )
3292{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003293 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003294 int ca_flags = 0, check_path_cnt = path_cnt + 1;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003295 unsigned char hash[POLARSSL_MD_MAX_SIZE];
3296 const md_info_t *md_info;
Paul Bakker915275b2012-09-28 07:10:55 +00003297
3298 if( x509parse_time_expired( &child->valid_to ) )
3299 *flags |= BADCERT_EXPIRED;
3300
3301 /*
3302 * Child is the top of the chain. Check against the trust_ca list.
3303 */
3304 *flags |= BADCERT_NOT_TRUSTED;
3305
3306 while( trust_ca != NULL )
3307 {
3308 if( trust_ca->version == 0 ||
3309 child->issuer_raw.len != trust_ca->subject_raw.len ||
3310 memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
3311 child->issuer_raw.len ) != 0 )
3312 {
3313 trust_ca = trust_ca->next;
3314 continue;
3315 }
3316
Paul Bakker9a736322012-11-14 12:39:52 +00003317 /*
3318 * Reduce path_len to check against if top of the chain is
3319 * the same as the trusted CA
3320 */
3321 if( child->subject_raw.len == trust_ca->subject_raw.len &&
3322 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3323 child->issuer_raw.len ) == 0 )
3324 {
3325 check_path_cnt--;
3326 }
3327
Paul Bakker915275b2012-09-28 07:10:55 +00003328 if( trust_ca->max_pathlen > 0 &&
Paul Bakker9a736322012-11-14 12:39:52 +00003329 trust_ca->max_pathlen < check_path_cnt )
Paul Bakker915275b2012-09-28 07:10:55 +00003330 {
3331 trust_ca = trust_ca->next;
3332 continue;
3333 }
3334
Paul Bakkerc70b9822013-04-07 22:00:46 +02003335 md_info = md_info_from_type( child->sig_md );
3336 if( md_info == NULL )
3337 {
3338 /*
3339 * Cannot check 'unknown' hash
3340 */
3341 continue;
3342 }
Paul Bakker915275b2012-09-28 07:10:55 +00003343
Paul Bakkerc70b9822013-04-07 22:00:46 +02003344 md( md_info, child->tbs.p, child->tbs.len, hash );
Paul Bakker915275b2012-09-28 07:10:55 +00003345
Paul Bakkerc70b9822013-04-07 22:00:46 +02003346 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, child->sig_md,
Paul Bakker915275b2012-09-28 07:10:55 +00003347 0, hash, child->sig.p ) != 0 )
3348 {
3349 trust_ca = trust_ca->next;
3350 continue;
3351 }
3352
3353 /*
3354 * Top of chain is signed by a trusted CA
3355 */
3356 *flags &= ~BADCERT_NOT_TRUSTED;
3357 break;
3358 }
3359
Paul Bakker9a736322012-11-14 12:39:52 +00003360 /*
Paul Bakker3497d8c2012-11-24 11:53:17 +01003361 * If top of chain is not the same as the trusted CA send a verify request
3362 * to the callback for any issues with validity and CRL presence for the
3363 * trusted CA certificate.
Paul Bakker9a736322012-11-14 12:39:52 +00003364 */
3365 if( trust_ca != NULL &&
3366 ( child->subject_raw.len != trust_ca->subject_raw.len ||
3367 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3368 child->issuer_raw.len ) != 0 ) )
Paul Bakker915275b2012-09-28 07:10:55 +00003369 {
3370 /* Check trusted CA's CRL for then chain's top crt */
3371 *flags |= x509parse_verifycrl( child, trust_ca, ca_crl );
3372
3373 if( x509parse_time_expired( &trust_ca->valid_to ) )
3374 ca_flags |= BADCERT_EXPIRED;
3375
Paul Bakker915275b2012-09-28 07:10:55 +00003376 if( NULL != f_vrfy )
3377 {
Paul Bakker9a736322012-11-14 12:39:52 +00003378 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003379 return( ret );
3380 }
3381 }
3382
3383 /* Call callback on top cert */
3384 if( NULL != f_vrfy )
3385 {
Paul Bakker9a736322012-11-14 12:39:52 +00003386 if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003387 return( ret );
3388 }
3389
Paul Bakker915275b2012-09-28 07:10:55 +00003390 *flags |= ca_flags;
3391
3392 return( 0 );
3393}
3394
3395static int x509parse_verify_child(
3396 x509_cert *child, x509_cert *parent, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003397 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003398 int (*f_vrfy)(void *, x509_cert *, int, int *),
3399 void *p_vrfy )
3400{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003401 int ret;
Paul Bakker915275b2012-09-28 07:10:55 +00003402 int parent_flags = 0;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003403 unsigned char hash[POLARSSL_MD_MAX_SIZE];
Paul Bakker915275b2012-09-28 07:10:55 +00003404 x509_cert *grandparent;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003405 const md_info_t *md_info;
Paul Bakker915275b2012-09-28 07:10:55 +00003406
3407 if( x509parse_time_expired( &child->valid_to ) )
3408 *flags |= BADCERT_EXPIRED;
3409
Paul Bakkerc70b9822013-04-07 22:00:46 +02003410 md_info = md_info_from_type( child->sig_md );
3411 if( md_info == NULL )
3412 {
3413 /*
3414 * Cannot check 'unknown' hash
3415 */
Paul Bakker915275b2012-09-28 07:10:55 +00003416 *flags |= BADCERT_NOT_TRUSTED;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003417 }
3418 else
3419 {
3420 md( md_info, child->tbs.p, child->tbs.len, hash );
3421
3422 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, child->sig_md, 0, hash,
3423 child->sig.p ) != 0 )
3424 *flags |= BADCERT_NOT_TRUSTED;
3425 }
3426
Paul Bakker915275b2012-09-28 07:10:55 +00003427 /* Check trusted CA's CRL for the given crt */
3428 *flags |= x509parse_verifycrl(child, parent, ca_crl);
3429
3430 grandparent = parent->next;
3431
3432 while( grandparent != NULL )
3433 {
3434 if( grandparent->version == 0 ||
3435 grandparent->ca_istrue == 0 ||
3436 parent->issuer_raw.len != grandparent->subject_raw.len ||
3437 memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
3438 parent->issuer_raw.len ) != 0 )
3439 {
3440 grandparent = grandparent->next;
3441 continue;
3442 }
3443 break;
3444 }
3445
Paul Bakker915275b2012-09-28 07:10:55 +00003446 if( grandparent != NULL )
3447 {
3448 /*
3449 * Part of the chain
3450 */
Paul Bakker9a736322012-11-14 12:39:52 +00003451 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 +00003452 if( ret != 0 )
3453 return( ret );
3454 }
3455 else
3456 {
Paul Bakker9a736322012-11-14 12:39:52 +00003457 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 +00003458 if( ret != 0 )
3459 return( ret );
3460 }
3461
3462 /* child is verified to be a child of the parent, call verify callback */
3463 if( NULL != f_vrfy )
Paul Bakker9a736322012-11-14 12:39:52 +00003464 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003465 return( ret );
Paul Bakker915275b2012-09-28 07:10:55 +00003466
3467 *flags |= parent_flags;
3468
3469 return( 0 );
3470}
3471
Paul Bakker76fd75a2011-01-16 21:12:10 +00003472/*
Paul Bakker5121ce52009-01-03 21:22:43 +00003473 * Verify the certificate validity
3474 */
3475int x509parse_verify( x509_cert *crt,
3476 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00003477 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003478 const char *cn, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003479 int (*f_vrfy)(void *, x509_cert *, int, int *),
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003480 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00003481{
Paul Bakker23986e52011-04-24 08:57:21 +00003482 size_t cn_len;
Paul Bakker915275b2012-09-28 07:10:55 +00003483 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003484 int pathlen = 0;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003485 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00003486 x509_name *name;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003487 x509_sequence *cur = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003488
Paul Bakker40ea7de2009-05-03 10:18:48 +00003489 *flags = 0;
3490
Paul Bakker5121ce52009-01-03 21:22:43 +00003491 if( cn != NULL )
3492 {
3493 name = &crt->subject;
3494 cn_len = strlen( cn );
3495
Paul Bakker4d2c1242012-05-10 14:12:46 +00003496 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
Paul Bakker5121ce52009-01-03 21:22:43 +00003497 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00003498 cur = &crt->subject_alt_names;
3499
3500 while( cur != NULL )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003501 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003502 if( cur->buf.len == cn_len &&
3503 memcmp( cn, cur->buf.p, cn_len ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003504 break;
3505
Paul Bakker535e97d2012-08-23 10:49:55 +00003506 if( cur->buf.len > 2 &&
3507 memcmp( cur->buf.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003508 x509_wildcard_verify( cn, &cur->buf ) )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003509 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003510
Paul Bakker4d2c1242012-05-10 14:12:46 +00003511 cur = cur->next;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003512 }
3513
3514 if( cur == NULL )
3515 *flags |= BADCERT_CN_MISMATCH;
3516 }
Paul Bakker4d2c1242012-05-10 14:12:46 +00003517 else
3518 {
3519 while( name != NULL )
3520 {
Paul Bakkerc70b9822013-04-07 22:00:46 +02003521 if( OID_CMP( OID_AT_CN, &name->oid ) )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003522 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003523 if( name->val.len == cn_len &&
3524 memcmp( name->val.p, cn, cn_len ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003525 break;
3526
Paul Bakker535e97d2012-08-23 10:49:55 +00003527 if( name->val.len > 2 &&
3528 memcmp( name->val.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003529 x509_wildcard_verify( cn, &name->val ) )
3530 break;
3531 }
3532
3533 name = name->next;
3534 }
3535
3536 if( name == NULL )
3537 *flags |= BADCERT_CN_MISMATCH;
3538 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003539 }
3540
Paul Bakker5121ce52009-01-03 21:22:43 +00003541 /*
Paul Bakker915275b2012-09-28 07:10:55 +00003542 * Iterate upwards in the given cert chain, to find our crt parent.
3543 * Ignore any upper cert with CA != TRUE.
Paul Bakker5121ce52009-01-03 21:22:43 +00003544 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003545 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003546
Paul Bakker76fd75a2011-01-16 21:12:10 +00003547 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003548 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003549 if( parent->ca_istrue == 0 ||
3550 crt->issuer_raw.len != parent->subject_raw.len ||
3551 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00003552 crt->issuer_raw.len ) != 0 )
3553 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003554 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003555 continue;
3556 }
Paul Bakker915275b2012-09-28 07:10:55 +00003557 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003558 }
3559
Paul Bakker915275b2012-09-28 07:10:55 +00003560 if( parent != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003561 {
Paul Bakker915275b2012-09-28 07:10:55 +00003562 /*
3563 * Part of the chain
3564 */
Paul Bakker9a736322012-11-14 12:39:52 +00003565 ret = x509parse_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003566 if( ret != 0 )
3567 return( ret );
3568 }
3569 else
Paul Bakker74111d32011-01-15 16:57:55 +00003570 {
Paul Bakker9a736322012-11-14 12:39:52 +00003571 ret = x509parse_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003572 if( ret != 0 )
3573 return( ret );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003574 }
Paul Bakker915275b2012-09-28 07:10:55 +00003575
3576 if( *flags != 0 )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003577 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003578
Paul Bakker5121ce52009-01-03 21:22:43 +00003579 return( 0 );
3580}
3581
3582/*
3583 * Unallocate all certificate data
3584 */
3585void x509_free( x509_cert *crt )
3586{
3587 x509_cert *cert_cur = crt;
3588 x509_cert *cert_prv;
3589 x509_name *name_cur;
3590 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00003591 x509_sequence *seq_cur;
3592 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00003593
3594 if( crt == NULL )
3595 return;
3596
3597 do
3598 {
3599 rsa_free( &cert_cur->rsa );
3600
3601 name_cur = cert_cur->issuer.next;
3602 while( name_cur != NULL )
3603 {
3604 name_prv = name_cur;
3605 name_cur = name_cur->next;
3606 memset( name_prv, 0, sizeof( x509_name ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02003607 polarssl_free( name_prv );
Paul Bakker5121ce52009-01-03 21:22:43 +00003608 }
3609
3610 name_cur = cert_cur->subject.next;
3611 while( name_cur != NULL )
3612 {
3613 name_prv = name_cur;
3614 name_cur = name_cur->next;
3615 memset( name_prv, 0, sizeof( x509_name ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02003616 polarssl_free( name_prv );
Paul Bakker5121ce52009-01-03 21:22:43 +00003617 }
3618
Paul Bakker74111d32011-01-15 16:57:55 +00003619 seq_cur = cert_cur->ext_key_usage.next;
3620 while( seq_cur != NULL )
3621 {
3622 seq_prv = seq_cur;
3623 seq_cur = seq_cur->next;
3624 memset( seq_prv, 0, sizeof( x509_sequence ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02003625 polarssl_free( seq_prv );
Paul Bakker74111d32011-01-15 16:57:55 +00003626 }
3627
Paul Bakker8afa70d2012-02-11 18:42:45 +00003628 seq_cur = cert_cur->subject_alt_names.next;
3629 while( seq_cur != NULL )
3630 {
3631 seq_prv = seq_cur;
3632 seq_cur = seq_cur->next;
3633 memset( seq_prv, 0, sizeof( x509_sequence ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02003634 polarssl_free( seq_prv );
Paul Bakker8afa70d2012-02-11 18:42:45 +00003635 }
3636
Paul Bakker5121ce52009-01-03 21:22:43 +00003637 if( cert_cur->raw.p != NULL )
3638 {
3639 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
Paul Bakker6e339b52013-07-03 13:37:05 +02003640 polarssl_free( cert_cur->raw.p );
Paul Bakker5121ce52009-01-03 21:22:43 +00003641 }
3642
3643 cert_cur = cert_cur->next;
3644 }
3645 while( cert_cur != NULL );
3646
3647 cert_cur = crt;
3648 do
3649 {
3650 cert_prv = cert_cur;
3651 cert_cur = cert_cur->next;
3652
3653 memset( cert_prv, 0, sizeof( x509_cert ) );
3654 if( cert_prv != crt )
Paul Bakker6e339b52013-07-03 13:37:05 +02003655 polarssl_free( cert_prv );
Paul Bakker5121ce52009-01-03 21:22:43 +00003656 }
3657 while( cert_cur != NULL );
3658}
3659
Paul Bakkerd98030e2009-05-02 15:13:40 +00003660/*
3661 * Unallocate all CRL data
3662 */
3663void x509_crl_free( x509_crl *crl )
3664{
3665 x509_crl *crl_cur = crl;
3666 x509_crl *crl_prv;
3667 x509_name *name_cur;
3668 x509_name *name_prv;
3669 x509_crl_entry *entry_cur;
3670 x509_crl_entry *entry_prv;
3671
3672 if( crl == NULL )
3673 return;
3674
3675 do
3676 {
3677 name_cur = crl_cur->issuer.next;
3678 while( name_cur != NULL )
3679 {
3680 name_prv = name_cur;
3681 name_cur = name_cur->next;
3682 memset( name_prv, 0, sizeof( x509_name ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02003683 polarssl_free( name_prv );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003684 }
3685
3686 entry_cur = crl_cur->entry.next;
3687 while( entry_cur != NULL )
3688 {
3689 entry_prv = entry_cur;
3690 entry_cur = entry_cur->next;
3691 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
Paul Bakker6e339b52013-07-03 13:37:05 +02003692 polarssl_free( entry_prv );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003693 }
3694
3695 if( crl_cur->raw.p != NULL )
3696 {
3697 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
Paul Bakker6e339b52013-07-03 13:37:05 +02003698 polarssl_free( crl_cur->raw.p );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003699 }
3700
3701 crl_cur = crl_cur->next;
3702 }
3703 while( crl_cur != NULL );
3704
3705 crl_cur = crl;
3706 do
3707 {
3708 crl_prv = crl_cur;
3709 crl_cur = crl_cur->next;
3710
3711 memset( crl_prv, 0, sizeof( x509_crl ) );
3712 if( crl_prv != crl )
Paul Bakker6e339b52013-07-03 13:37:05 +02003713 polarssl_free( crl_prv );
Paul Bakkerd98030e2009-05-02 15:13:40 +00003714 }
3715 while( crl_cur != NULL );
3716}
3717
Paul Bakker40e46942009-01-03 21:51:57 +00003718#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00003719
Paul Bakker40e46942009-01-03 21:51:57 +00003720#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00003721
3722/*
3723 * Checkup routine
3724 */
3725int x509_self_test( int verbose )
3726{
Paul Bakker5690efc2011-05-26 13:16:06 +00003727#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00003728 int ret;
3729 int flags;
3730 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00003731 x509_cert cacert;
3732 x509_cert clicert;
3733 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00003734#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003735 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00003736#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003737
3738 if( verbose != 0 )
3739 printf( " X.509 certificate load: " );
3740
3741 memset( &clicert, 0, sizeof( x509_cert ) );
3742
Paul Bakker3c2122f2013-06-24 19:03:14 +02003743 ret = x509parse_crt( &clicert, (const unsigned char *) test_cli_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003744 strlen( test_cli_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003745 if( ret != 0 )
3746 {
3747 if( verbose != 0 )
3748 printf( "failed\n" );
3749
3750 return( ret );
3751 }
3752
3753 memset( &cacert, 0, sizeof( x509_cert ) );
3754
Paul Bakker3c2122f2013-06-24 19:03:14 +02003755 ret = x509parse_crt( &cacert, (const unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003756 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003757 if( ret != 0 )
3758 {
3759 if( verbose != 0 )
3760 printf( "failed\n" );
3761
3762 return( ret );
3763 }
3764
3765 if( verbose != 0 )
3766 printf( "passed\n X.509 private key load: " );
3767
3768 i = strlen( test_ca_key );
3769 j = strlen( test_ca_pwd );
3770
Paul Bakker66b78b22011-03-25 14:22:50 +00003771 rsa_init( &rsa, RSA_PKCS_V15, 0 );
3772
Manuel Pégourié-Gonnardba4878a2013-06-27 10:51:01 +02003773 if( ( ret = x509parse_key_rsa( &rsa,
Paul Bakker3c2122f2013-06-24 19:03:14 +02003774 (const unsigned char *) test_ca_key, i,
3775 (const unsigned char *) test_ca_pwd, j ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003776 {
3777 if( verbose != 0 )
3778 printf( "failed\n" );
3779
3780 return( ret );
3781 }
3782
3783 if( verbose != 0 )
3784 printf( "passed\n X.509 signature verify: ");
3785
Paul Bakker23986e52011-04-24 08:57:21 +00003786 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003787 if( ret != 0 )
3788 {
Paul Bakker23986e52011-04-24 08:57:21 +00003789 printf("%02x", flags);
Paul Bakker5121ce52009-01-03 21:22:43 +00003790 if( verbose != 0 )
3791 printf( "failed\n" );
3792
3793 return( ret );
3794 }
3795
Paul Bakker5690efc2011-05-26 13:16:06 +00003796#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003797 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003798 printf( "passed\n X.509 DHM parameter load: " );
3799
3800 i = strlen( test_dhm_params );
3801 j = strlen( test_ca_pwd );
3802
Paul Bakker3c2122f2013-06-24 19:03:14 +02003803 if( ( ret = x509parse_dhm( &dhm, (const unsigned char *) test_dhm_params, i ) ) != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003804 {
3805 if( verbose != 0 )
3806 printf( "failed\n" );
3807
3808 return( ret );
3809 }
3810
3811 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003812 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00003813#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003814
3815 x509_free( &cacert );
3816 x509_free( &clicert );
3817 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00003818#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003819 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00003820#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003821
3822 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003823#else
3824 ((void) verbose);
3825 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3826#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003827}
3828
3829#endif
3830
3831#endif