blob: c49c48adb57d37c0f2ec42a9f948cef7624c601d [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 Bakker40e46942009-01-03 21:51:57 +000045#include "polarssl/des.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010046#if defined(POLARSSL_MD2_C)
Paul Bakker40e46942009-01-03 21:51:57 +000047#include "polarssl/md2.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010048#endif
49#if defined(POLARSSL_MD4_C)
Paul Bakker40e46942009-01-03 21:51:57 +000050#include "polarssl/md4.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010051#endif
52#if defined(POLARSSL_MD5_C)
Paul Bakker40e46942009-01-03 21:51:57 +000053#include "polarssl/md5.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010054#endif
55#if defined(POLARSSL_SHA1_C)
Paul Bakker40e46942009-01-03 21:51:57 +000056#include "polarssl/sha1.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010057#endif
58#if defined(POLARSSL_SHA2_C)
Paul Bakker026c03b2009-03-28 17:53:03 +000059#include "polarssl/sha2.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010060#endif
61#if defined(POLARSSL_SHA4_C)
Paul Bakker026c03b2009-03-28 17:53:03 +000062#include "polarssl/sha4.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010063#endif
Paul Bakker1b57b062011-01-06 15:48:19 +000064#include "polarssl/dhm.h"
Paul Bakker28144de2013-06-24 19:28:55 +020065#if defined(POLARSSL_PKCS5_C)
66#include "polarssl/pkcs5.h"
67#endif
Paul Bakker38b50d72013-06-24 19:33:27 +020068#if defined(POLARSSL_PKCS12_C)
69#include "polarssl/pkcs12.h"
70#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000071
72#include <string.h>
73#include <stdlib.h>
Paul Bakker4f229e52011-12-04 22:11:35 +000074#if defined(_WIN32)
Paul Bakkercce9d772011-11-18 14:26:47 +000075#include <windows.h>
76#else
Paul Bakker5121ce52009-01-03 21:22:43 +000077#include <time.h>
Paul Bakkercce9d772011-11-18 14:26:47 +000078#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000079
Paul Bakker335db3f2011-04-25 15:28:35 +000080#if defined(POLARSSL_FS_IO)
81#include <stdio.h>
Paul Bakker4a2bd0d2012-11-02 11:06:08 +000082#if !defined(_WIN32)
Paul Bakker8d914582012-06-04 12:46:42 +000083#include <sys/types.h>
Paul Bakker2c8cdd22013-06-24 19:22:42 +020084#include <sys/stat.h>
Paul Bakker8d914582012-06-04 12:46:42 +000085#include <dirent.h>
86#endif
Paul Bakker335db3f2011-04-25 15:28:35 +000087#endif
88
Paul Bakker5121ce52009-01-03 21:22:43 +000089/*
Paul Bakker5121ce52009-01-03 21:22:43 +000090 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
91 */
92static int x509_get_version( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +000093 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +000094 int *ver )
95{
Paul Bakker23986e52011-04-24 08:57:21 +000096 int ret;
97 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +000098
99 if( ( ret = asn1_get_tag( p, end, &len,
100 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
101 {
Paul Bakker40e46942009-01-03 21:51:57 +0000102 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +0000103 {
104 *ver = 0;
105 return( 0 );
106 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000107
108 return( ret );
109 }
110
111 end = *p + len;
112
113 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000114 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000115
116 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000117 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION +
Paul Bakker40e46942009-01-03 21:51:57 +0000118 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000119
120 return( 0 );
121}
122
123/*
Paul Bakkerfae618f2011-10-12 11:53:52 +0000124 * Version ::= INTEGER { v1(0), v2(1) }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000125 */
126static int x509_crl_get_version( unsigned char **p,
127 const unsigned char *end,
128 int *ver )
129{
130 int ret;
131
132 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
133 {
134 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +0000135 {
136 *ver = 0;
137 return( 0 );
138 }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000139
140 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
141 }
142
143 return( 0 );
144}
145
146/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000147 * CertificateSerialNumber ::= INTEGER
148 */
149static int x509_get_serial( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000150 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000151 x509_buf *serial )
152{
153 int ret;
154
155 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000156 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000157 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000158
159 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
160 **p != ASN1_INTEGER )
Paul Bakker9d781402011-05-09 16:17:09 +0000161 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000162 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000163
164 serial->tag = *(*p)++;
165
166 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000167 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000168
169 serial->p = *p;
170 *p += serial->len;
171
172 return( 0 );
173}
174
175/*
176 * AlgorithmIdentifier ::= SEQUENCE {
177 * algorithm OBJECT IDENTIFIER,
178 * parameters ANY DEFINED BY algorithm OPTIONAL }
179 */
180static int x509_get_alg( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000181 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000182 x509_buf *alg )
183{
Paul Bakker23986e52011-04-24 08:57:21 +0000184 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000185
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200186 if( ( ret = asn1_get_alg_null( p, end, alg ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000187 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000188
Paul Bakker5121ce52009-01-03 21:22:43 +0000189 return( 0 );
190}
191
192/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000193 * AttributeTypeAndValue ::= SEQUENCE {
194 * type AttributeType,
195 * value AttributeValue }
196 *
197 * AttributeType ::= OBJECT IDENTIFIER
198 *
199 * AttributeValue ::= ANY DEFINED BY AttributeType
200 */
Paul Bakker400ff6f2011-02-20 10:40:16 +0000201static int x509_get_attr_type_value( unsigned char **p,
202 const unsigned char *end,
203 x509_name *cur )
Paul Bakker5121ce52009-01-03 21:22:43 +0000204{
Paul Bakker23986e52011-04-24 08:57:21 +0000205 int ret;
206 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000207 x509_buf *oid;
208 x509_buf *val;
209
210 if( ( ret = asn1_get_tag( p, end, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000211 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000212 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000213
Paul Bakker5121ce52009-01-03 21:22:43 +0000214 oid = &cur->oid;
215 oid->tag = **p;
216
217 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000218 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000219
220 oid->p = *p;
221 *p += oid->len;
222
223 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000224 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000225 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000226
227 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
228 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
229 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker9d781402011-05-09 16:17:09 +0000230 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000231 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000232
233 val = &cur->val;
234 val->tag = *(*p)++;
235
236 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000237 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000238
239 val->p = *p;
240 *p += val->len;
241
242 cur->next = NULL;
243
Paul Bakker400ff6f2011-02-20 10:40:16 +0000244 return( 0 );
245}
246
247/*
248 * RelativeDistinguishedName ::=
249 * SET OF AttributeTypeAndValue
250 *
251 * AttributeTypeAndValue ::= SEQUENCE {
252 * type AttributeType,
253 * value AttributeValue }
254 *
255 * AttributeType ::= OBJECT IDENTIFIER
256 *
257 * AttributeValue ::= ANY DEFINED BY AttributeType
258 */
259static int x509_get_name( unsigned char **p,
260 const unsigned char *end,
261 x509_name *cur )
262{
Paul Bakker23986e52011-04-24 08:57:21 +0000263 int ret;
264 size_t len;
Paul Bakker400ff6f2011-02-20 10:40:16 +0000265 const unsigned char *end2;
266 x509_name *use;
267
268 if( ( ret = asn1_get_tag( p, end, &len,
269 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000270 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000271
272 end2 = end;
273 end = *p + len;
274 use = cur;
275
276 do
277 {
278 if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
279 return( ret );
280
281 if( *p != end )
282 {
283 use->next = (x509_name *) malloc(
284 sizeof( x509_name ) );
285
286 if( use->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000287 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000288
289 memset( use->next, 0, sizeof( x509_name ) );
290
291 use = use->next;
292 }
293 }
294 while( *p != end );
Paul Bakker5121ce52009-01-03 21:22:43 +0000295
296 /*
297 * recurse until end of SEQUENCE is reached
298 */
299 if( *p == end2 )
300 return( 0 );
301
302 cur->next = (x509_name *) malloc(
303 sizeof( x509_name ) );
304
305 if( cur->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000306 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000307
Paul Bakker430ffbe2012-05-01 08:14:20 +0000308 memset( cur->next, 0, sizeof( x509_name ) );
309
Paul Bakker5121ce52009-01-03 21:22:43 +0000310 return( x509_get_name( p, end2, cur->next ) );
311}
312
313/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000314 * Time ::= CHOICE {
315 * utcTime UTCTime,
316 * generalTime GeneralizedTime }
317 */
Paul Bakker91200182010-02-18 21:26:15 +0000318static int x509_get_time( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000319 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000320 x509_time *time )
321{
Paul Bakker23986e52011-04-24 08:57:21 +0000322 int ret;
323 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000324 char date[64];
Paul Bakker91200182010-02-18 21:26:15 +0000325 unsigned char tag;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000326
Paul Bakker91200182010-02-18 21:26:15 +0000327 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000328 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
329 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000330
Paul Bakker91200182010-02-18 21:26:15 +0000331 tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000332
Paul Bakker91200182010-02-18 21:26:15 +0000333 if ( tag == ASN1_UTC_TIME )
334 {
335 (*p)++;
336 ret = asn1_get_len( p, end, &len );
337
338 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000339 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000340
Paul Bakker91200182010-02-18 21:26:15 +0000341 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000342 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
343 len : sizeof( date ) - 1 );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000344
Paul Bakker91200182010-02-18 21:26:15 +0000345 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
346 &time->year, &time->mon, &time->day,
347 &time->hour, &time->min, &time->sec ) < 5 )
348 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000349
Paul Bakker400ff6f2011-02-20 10:40:16 +0000350 time->year += 100 * ( time->year < 50 );
Paul Bakker91200182010-02-18 21:26:15 +0000351 time->year += 1900;
352
353 *p += len;
354
355 return( 0 );
356 }
357 else if ( tag == ASN1_GENERALIZED_TIME )
358 {
359 (*p)++;
360 ret = asn1_get_len( p, end, &len );
361
362 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000363 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker91200182010-02-18 21:26:15 +0000364
365 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000366 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
367 len : sizeof( date ) - 1 );
Paul Bakker91200182010-02-18 21:26:15 +0000368
369 if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
370 &time->year, &time->mon, &time->day,
371 &time->hour, &time->min, &time->sec ) < 5 )
372 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
373
374 *p += len;
375
376 return( 0 );
377 }
378 else
Paul Bakker9d781402011-05-09 16:17:09 +0000379 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000380}
381
382
383/*
384 * Validity ::= SEQUENCE {
385 * notBefore Time,
386 * notAfter Time }
387 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000388static int x509_get_dates( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000389 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000390 x509_time *from,
391 x509_time *to )
392{
Paul Bakker23986e52011-04-24 08:57:21 +0000393 int ret;
394 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000395
396 if( ( ret = asn1_get_tag( p, end, &len,
397 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000398 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000399
400 end = *p + len;
401
Paul Bakker91200182010-02-18 21:26:15 +0000402 if( ( ret = x509_get_time( p, end, from ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000403 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000404
Paul Bakker91200182010-02-18 21:26:15 +0000405 if( ( ret = x509_get_time( p, end, to ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000406 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000407
408 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000409 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker40e46942009-01-03 21:51:57 +0000410 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000411
412 return( 0 );
413}
414
415/*
416 * SubjectPublicKeyInfo ::= SEQUENCE {
417 * algorithm AlgorithmIdentifier,
418 * subjectPublicKey BIT STRING }
419 */
420static int x509_get_pubkey( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000421 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000422 x509_buf *pk_alg_oid,
423 mpi *N, mpi *E )
424{
Paul Bakkerc70b9822013-04-07 22:00:46 +0200425 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000426 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000427 unsigned char *end2;
Paul Bakkerc70b9822013-04-07 22:00:46 +0200428 pk_type_t pk_alg = POLARSSL_PK_NONE;
Paul Bakker5121ce52009-01-03 21:22:43 +0000429
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200430 if( ( ret = asn1_get_alg_null( p, end, pk_alg_oid ) ) != 0 )
431 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000432
433 /*
434 * only RSA public keys handled at this time
435 */
Paul Bakkerc70b9822013-04-07 22:00:46 +0200436 if( oid_get_pk_alg( pk_alg_oid, &pk_alg ) != 0 )
Paul Bakkered56b222011-07-13 11:26:43 +0000437 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000438
439 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000440 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000441
442 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000443 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000444 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000445
446 end2 = *p + len;
447
448 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000449 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000450
451 /*
452 * RSAPublicKey ::= SEQUENCE {
453 * modulus INTEGER, -- n
454 * publicExponent INTEGER -- e
455 * }
456 */
457 if( ( ret = asn1_get_tag( p, end2, &len,
458 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000459 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000460
461 if( *p + len != end2 )
Paul Bakker9d781402011-05-09 16:17:09 +0000462 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000463 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000464
465 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
466 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000467 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000468
469 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000470 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000471 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000472
473 return( 0 );
474}
475
476static int x509_get_sig( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000477 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000478 x509_buf *sig )
479{
Paul Bakker23986e52011-04-24 08:57:21 +0000480 int ret;
481 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000482
Paul Bakker8afa70d2012-02-11 18:42:45 +0000483 if( ( end - *p ) < 1 )
484 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE +
485 POLARSSL_ERR_ASN1_OUT_OF_DATA );
486
Paul Bakker5121ce52009-01-03 21:22:43 +0000487 sig->tag = **p;
488
489 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000490 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000491
Paul Bakker74111d32011-01-15 16:57:55 +0000492
Paul Bakker5121ce52009-01-03 21:22:43 +0000493 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000494 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000495
496 sig->len = len;
497 sig->p = *p;
498
499 *p += len;
500
501 return( 0 );
502}
503
504/*
505 * X.509 v2/v3 unique identifier (not parsed)
506 */
507static int x509_get_uid( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000508 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000509 x509_buf *uid, int n )
510{
511 int ret;
512
513 if( *p == end )
514 return( 0 );
515
516 uid->tag = **p;
517
518 if( ( ret = asn1_get_tag( p, end, &uid->len,
519 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
520 {
Paul Bakker40e46942009-01-03 21:51:57 +0000521 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000522 return( 0 );
523
524 return( ret );
525 }
526
527 uid->p = *p;
528 *p += uid->len;
529
530 return( 0 );
531}
532
533/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000534 * X.509 Extensions (No parsing of extensions, pointer should
535 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000536 */
537static int x509_get_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000538 const unsigned char *end,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000539 x509_buf *ext, int tag )
Paul Bakker5121ce52009-01-03 21:22:43 +0000540{
Paul Bakker23986e52011-04-24 08:57:21 +0000541 int ret;
542 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000543
544 if( *p == end )
545 return( 0 );
546
547 ext->tag = **p;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000548
Paul Bakker5121ce52009-01-03 21:22:43 +0000549 if( ( ret = asn1_get_tag( p, end, &ext->len,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000550 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000551 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000552
553 ext->p = *p;
554 end = *p + ext->len;
555
556 /*
557 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
558 *
559 * Extension ::= SEQUENCE {
560 * extnID OBJECT IDENTIFIER,
561 * critical BOOLEAN DEFAULT FALSE,
562 * extnValue OCTET STRING }
563 */
564 if( ( ret = asn1_get_tag( p, end, &len,
565 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000566 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000567
568 if( end != *p + len )
Paul Bakker9d781402011-05-09 16:17:09 +0000569 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +0000570 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000571
Paul Bakkerd98030e2009-05-02 15:13:40 +0000572 return( 0 );
573}
574
575/*
576 * X.509 CRL v2 extensions (no extensions parsed yet.)
577 */
578static int x509_get_crl_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000579 const unsigned char *end,
580 x509_buf *ext )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000581{
Paul Bakker23986e52011-04-24 08:57:21 +0000582 int ret;
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000583 size_t len = 0;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000584
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000585 /* Get explicit tag */
586 if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000587 {
588 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
589 return( 0 );
590
591 return( ret );
592 }
593
594 while( *p < end )
595 {
596 if( ( ret = asn1_get_tag( p, end, &len,
597 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000598 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000599
600 *p += len;
601 }
602
603 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000604 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerd98030e2009-05-02 15:13:40 +0000605 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
606
607 return( 0 );
608}
609
Paul Bakkerb5a11ab2011-10-12 09:58:41 +0000610/*
611 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
612 */
613static int x509_get_crl_entry_ext( unsigned char **p,
614 const unsigned char *end,
615 x509_buf *ext )
616{
617 int ret;
618 size_t len = 0;
619
620 /* OPTIONAL */
621 if (end <= *p)
622 return( 0 );
623
624 ext->tag = **p;
625 ext->p = *p;
626
627 /*
628 * Get CRL-entry extension sequence header
629 * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
630 */
631 if( ( ret = asn1_get_tag( p, end, &ext->len,
632 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
633 {
634 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
635 {
636 ext->p = NULL;
637 return( 0 );
638 }
639 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
640 }
641
642 end = *p + ext->len;
643
644 if( end != *p + ext->len )
645 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
646 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
647
648 while( *p < end )
649 {
650 if( ( ret = asn1_get_tag( p, end, &len,
651 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
652 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
653
654 *p += len;
655 }
656
657 if( *p != end )
658 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
659 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
660
661 return( 0 );
662}
663
Paul Bakker74111d32011-01-15 16:57:55 +0000664static int x509_get_basic_constraints( unsigned char **p,
665 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000666 int *ca_istrue,
667 int *max_pathlen )
668{
Paul Bakker23986e52011-04-24 08:57:21 +0000669 int ret;
670 size_t len;
Paul Bakker74111d32011-01-15 16:57:55 +0000671
672 /*
673 * BasicConstraints ::= SEQUENCE {
674 * cA BOOLEAN DEFAULT FALSE,
675 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
676 */
Paul Bakker3cccddb2011-01-16 21:46:31 +0000677 *ca_istrue = 0; /* DEFAULT FALSE */
Paul Bakker74111d32011-01-15 16:57:55 +0000678 *max_pathlen = 0; /* endless */
679
680 if( ( ret = asn1_get_tag( p, end, &len,
681 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000682 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000683
684 if( *p == end )
685 return 0;
686
Paul Bakker3cccddb2011-01-16 21:46:31 +0000687 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000688 {
689 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker3cccddb2011-01-16 21:46:31 +0000690 ret = asn1_get_int( p, end, ca_istrue );
Paul Bakker74111d32011-01-15 16:57:55 +0000691
692 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000693 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000694
Paul Bakker3cccddb2011-01-16 21:46:31 +0000695 if( *ca_istrue != 0 )
696 *ca_istrue = 1;
Paul Bakker74111d32011-01-15 16:57:55 +0000697 }
698
699 if( *p == end )
700 return 0;
701
702 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000703 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000704
705 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000706 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000707 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
708
709 (*max_pathlen)++;
710
Paul Bakker74111d32011-01-15 16:57:55 +0000711 return 0;
712}
713
714static int x509_get_ns_cert_type( unsigned char **p,
715 const unsigned char *end,
716 unsigned char *ns_cert_type)
717{
718 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000719 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000720
721 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000722 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000723
724 if( bs.len != 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000725 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000726 POLARSSL_ERR_ASN1_INVALID_LENGTH );
727
728 /* Get actual bitstring */
729 *ns_cert_type = *bs.p;
730 return 0;
731}
732
733static int x509_get_key_usage( unsigned char **p,
734 const unsigned char *end,
735 unsigned char *key_usage)
736{
737 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000738 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000739
740 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000741 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000742
Paul Bakker94a67962012-08-23 13:03:52 +0000743 if( bs.len < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000744 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000745 POLARSSL_ERR_ASN1_INVALID_LENGTH );
746
747 /* Get actual bitstring */
748 *key_usage = *bs.p;
749 return 0;
750}
751
Paul Bakkerd98030e2009-05-02 15:13:40 +0000752/*
Paul Bakker74111d32011-01-15 16:57:55 +0000753 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
754 *
755 * KeyPurposeId ::= OBJECT IDENTIFIER
756 */
757static int x509_get_ext_key_usage( unsigned char **p,
758 const unsigned char *end,
759 x509_sequence *ext_key_usage)
760{
761 int ret;
762
763 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000764 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000765
766 /* Sequence length must be >= 1 */
767 if( ext_key_usage->buf.p == NULL )
Paul Bakker9d781402011-05-09 16:17:09 +0000768 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000769 POLARSSL_ERR_ASN1_INVALID_LENGTH );
770
771 return 0;
772}
773
774/*
Paul Bakkera8cd2392012-02-11 16:09:32 +0000775 * SubjectAltName ::= GeneralNames
776 *
777 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
778 *
779 * GeneralName ::= CHOICE {
780 * otherName [0] OtherName,
781 * rfc822Name [1] IA5String,
782 * dNSName [2] IA5String,
783 * x400Address [3] ORAddress,
784 * directoryName [4] Name,
785 * ediPartyName [5] EDIPartyName,
786 * uniformResourceIdentifier [6] IA5String,
787 * iPAddress [7] OCTET STRING,
788 * registeredID [8] OBJECT IDENTIFIER }
789 *
790 * OtherName ::= SEQUENCE {
791 * type-id OBJECT IDENTIFIER,
792 * value [0] EXPLICIT ANY DEFINED BY type-id }
793 *
794 * EDIPartyName ::= SEQUENCE {
795 * nameAssigner [0] DirectoryString OPTIONAL,
796 * partyName [1] DirectoryString }
797 *
798 * NOTE: PolarSSL only parses and uses dNSName at this point.
799 */
800static int x509_get_subject_alt_name( unsigned char **p,
801 const unsigned char *end,
802 x509_sequence *subject_alt_name )
803{
804 int ret;
805 size_t len, tag_len;
806 asn1_buf *buf;
807 unsigned char tag;
808 asn1_sequence *cur = subject_alt_name;
809
810 /* Get main sequence tag */
811 if( ( ret = asn1_get_tag( p, end, &len,
812 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
813 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
814
815 if( *p + len != end )
816 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
817 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
818
819 while( *p < end )
820 {
821 if( ( end - *p ) < 1 )
822 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
823 POLARSSL_ERR_ASN1_OUT_OF_DATA );
824
825 tag = **p;
826 (*p)++;
827 if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 )
828 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
829
830 if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC )
831 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
832 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
833
834 if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) )
835 {
836 *p += tag_len;
837 continue;
838 }
839
840 buf = &(cur->buf);
841 buf->tag = tag;
842 buf->p = *p;
843 buf->len = tag_len;
844 *p += buf->len;
845
846 /* Allocate and assign next pointer */
847 if (*p < end)
848 {
849 cur->next = (asn1_sequence *) malloc(
850 sizeof( asn1_sequence ) );
851
852 if( cur->next == NULL )
853 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
854 POLARSSL_ERR_ASN1_MALLOC_FAILED );
855
Paul Bakker535e97d2012-08-23 10:49:55 +0000856 memset( cur->next, 0, sizeof( asn1_sequence ) );
Paul Bakkera8cd2392012-02-11 16:09:32 +0000857 cur = cur->next;
858 }
859 }
860
861 /* Set final sequence entry's next pointer to NULL */
862 cur->next = NULL;
863
864 if( *p != end )
865 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
866 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
867
868 return( 0 );
869}
870
871/*
Paul Bakker74111d32011-01-15 16:57:55 +0000872 * X.509 v3 extensions
873 *
874 * TODO: Perform all of the basic constraints tests required by the RFC
875 * TODO: Set values for undetected extensions to a sane default?
876 *
Paul Bakkerd98030e2009-05-02 15:13:40 +0000877 */
878static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000879 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000880 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000881{
Paul Bakker23986e52011-04-24 08:57:21 +0000882 int ret;
883 size_t len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000884 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000885
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000886 if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000887 {
888 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
889 return( 0 );
890
891 return( ret );
892 }
893
Paul Bakker5121ce52009-01-03 21:22:43 +0000894 while( *p < end )
895 {
Paul Bakker74111d32011-01-15 16:57:55 +0000896 /*
897 * Extension ::= SEQUENCE {
898 * extnID OBJECT IDENTIFIER,
899 * critical BOOLEAN DEFAULT FALSE,
900 * extnValue OCTET STRING }
901 */
902 x509_buf extn_oid = {0, 0, NULL};
903 int is_critical = 0; /* DEFAULT FALSE */
Paul Bakkerc70b9822013-04-07 22:00:46 +0200904 int ext_type = 0;
Paul Bakker74111d32011-01-15 16:57:55 +0000905
Paul Bakker5121ce52009-01-03 21:22:43 +0000906 if( ( ret = asn1_get_tag( p, end, &len,
907 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000908 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000909
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000910 end_ext_data = *p + len;
911
Paul Bakker74111d32011-01-15 16:57:55 +0000912 /* Get extension ID */
913 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000914
Paul Bakker74111d32011-01-15 16:57:55 +0000915 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000916 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000917
Paul Bakker74111d32011-01-15 16:57:55 +0000918 extn_oid.p = *p;
919 *p += extn_oid.len;
920
921 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000922 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000923 POLARSSL_ERR_ASN1_OUT_OF_DATA );
924
925 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000926 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000927 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
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 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000931 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000932 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000933 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000934
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000935 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000936
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000937 if( end_ext_octet != end_ext_data )
Paul Bakker9d781402011-05-09 16:17:09 +0000938 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000939 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000940
Paul Bakker74111d32011-01-15 16:57:55 +0000941 /*
942 * Detect supported extensions
943 */
Paul Bakkerc70b9822013-04-07 22:00:46 +0200944 ret = oid_get_x509_ext_type( &extn_oid, &ext_type );
945
946 if( ret != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000947 {
948 /* No parser found, skip extension */
949 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +0000950
Paul Bakker5c721f92011-07-27 16:51:09 +0000951#if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
Paul Bakker74111d32011-01-15 16:57:55 +0000952 if( is_critical )
953 {
954 /* Data is marked as critical: fail */
Paul Bakker9d781402011-05-09 16:17:09 +0000955 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000956 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
957 }
Paul Bakker5c721f92011-07-27 16:51:09 +0000958#endif
Paul Bakkerc70b9822013-04-07 22:00:46 +0200959 continue;
960 }
961
962 crt->ext_types |= ext_type;
963
964 switch( ext_type )
965 {
966 case EXT_BASIC_CONSTRAINTS:
967 /* Parse basic constraints */
968 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
969 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
970 return ( ret );
971 break;
972
973 case EXT_KEY_USAGE:
974 /* Parse key usage */
975 if( ( ret = x509_get_key_usage( p, end_ext_octet,
976 &crt->key_usage ) ) != 0 )
977 return ( ret );
978 break;
979
980 case EXT_EXTENDED_KEY_USAGE:
981 /* Parse extended key usage */
982 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
983 &crt->ext_key_usage ) ) != 0 )
984 return ( ret );
985 break;
986
987 case EXT_SUBJECT_ALT_NAME:
988 /* Parse subject alt name */
989 if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
990 &crt->subject_alt_names ) ) != 0 )
991 return ( ret );
992 break;
993
994 case EXT_NS_CERT_TYPE:
995 /* Parse netscape certificate type */
996 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
997 &crt->ns_cert_type ) ) != 0 )
998 return ( ret );
999 break;
1000
1001 default:
1002 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker74111d32011-01-15 16:57:55 +00001003 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001004 }
1005
1006 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +00001007 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +00001008 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001009
Paul Bakker5121ce52009-01-03 21:22:43 +00001010 return( 0 );
1011}
1012
1013/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001014 * X.509 CRL Entries
1015 */
1016static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001017 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001018 x509_crl_entry *entry )
1019{
Paul Bakker23986e52011-04-24 08:57:21 +00001020 int ret;
1021 size_t entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001022 x509_crl_entry *cur_entry = entry;
1023
1024 if( *p == end )
1025 return( 0 );
1026
Paul Bakker9be19372009-07-27 20:21:53 +00001027 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001028 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1029 {
1030 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
1031 return( 0 );
1032
1033 return( ret );
1034 }
1035
Paul Bakker9be19372009-07-27 20:21:53 +00001036 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001037
1038 while( *p < end )
1039 {
Paul Bakker23986e52011-04-24 08:57:21 +00001040 size_t len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001041 const unsigned char *end2;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001042
1043 if( ( ret = asn1_get_tag( p, end, &len2,
1044 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1045 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001046 return( ret );
1047 }
1048
Paul Bakker9be19372009-07-27 20:21:53 +00001049 cur_entry->raw.tag = **p;
1050 cur_entry->raw.p = *p;
1051 cur_entry->raw.len = len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001052 end2 = *p + len2;
Paul Bakker9be19372009-07-27 20:21:53 +00001053
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001054 if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001055 return( ret );
1056
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001057 if( ( ret = x509_get_time( p, end2, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001058 return( ret );
1059
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001060 if( ( ret = x509_get_crl_entry_ext( p, end2, &cur_entry->entry_ext ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001061 return( ret );
1062
Paul Bakker74111d32011-01-15 16:57:55 +00001063 if ( *p < end )
1064 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001065 cur_entry->next = malloc( sizeof( x509_crl_entry ) );
Paul Bakkerb15b8512012-01-13 13:44:06 +00001066
1067 if( cur_entry->next == NULL )
1068 return( POLARSSL_ERR_X509_MALLOC_FAILED );
1069
Paul Bakkerd98030e2009-05-02 15:13:40 +00001070 cur_entry = cur_entry->next;
1071 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
1072 }
1073 }
1074
1075 return( 0 );
1076}
1077
Paul Bakkerc70b9822013-04-07 22:00:46 +02001078static int x509_get_sig_alg( const x509_buf *sig_oid, md_type_t *md_alg,
1079 pk_type_t *pk_alg )
Paul Bakker27d66162010-03-17 06:56:01 +00001080{
Paul Bakkerc70b9822013-04-07 22:00:46 +02001081 int ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg );
Paul Bakker27d66162010-03-17 06:56:01 +00001082
Paul Bakkerc70b9822013-04-07 22:00:46 +02001083 if( ret != 0 )
1084 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG + ret );
Paul Bakker27d66162010-03-17 06:56:01 +00001085
Paul Bakkerc70b9822013-04-07 22:00:46 +02001086 return( 0 );
Paul Bakker27d66162010-03-17 06:56:01 +00001087}
1088
Paul Bakkerd98030e2009-05-02 15:13:40 +00001089/*
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001090 * Parse and fill a single X.509 certificate in DER format
Paul Bakker5121ce52009-01-03 21:22:43 +00001091 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02001092static int x509parse_crt_der_core( x509_cert *crt, const unsigned char *buf,
1093 size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001094{
Paul Bakker23986e52011-04-24 08:57:21 +00001095 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001096 size_t len;
Paul Bakkerb00ca422012-09-25 12:10:00 +00001097 unsigned char *p, *end, *crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001098
Paul Bakker320a4b52009-03-28 18:52:39 +00001099 /*
1100 * Check for valid input
1101 */
1102 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001103 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker320a4b52009-03-28 18:52:39 +00001104
Paul Bakker96743fc2011-02-12 14:30:57 +00001105 p = (unsigned char *) malloc( len = buflen );
1106
1107 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001108 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001109
1110 memcpy( p, buf, buflen );
1111
1112 buflen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001113
1114 crt->raw.p = p;
1115 crt->raw.len = len;
1116 end = p + len;
1117
1118 /*
1119 * Certificate ::= SEQUENCE {
1120 * tbsCertificate TBSCertificate,
1121 * signatureAlgorithm AlgorithmIdentifier,
1122 * signatureValue BIT STRING }
1123 */
1124 if( ( ret = asn1_get_tag( &p, end, &len,
1125 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1126 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001127 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001128 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001129 }
1130
Paul Bakkerb00ca422012-09-25 12:10:00 +00001131 if( len > (size_t) ( end - p ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001132 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001133 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001134 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001135 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001136 }
Paul Bakkerb00ca422012-09-25 12:10:00 +00001137 crt_end = p + len;
Paul Bakker42c65812013-06-24 19:21:59 +02001138
Paul Bakker5121ce52009-01-03 21:22:43 +00001139 /*
1140 * TBSCertificate ::= SEQUENCE {
1141 */
1142 crt->tbs.p = p;
1143
1144 if( ( ret = asn1_get_tag( &p, end, &len,
1145 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1146 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001147 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001148 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001149 }
1150
1151 end = p + len;
1152 crt->tbs.len = end - crt->tbs.p;
1153
1154 /*
1155 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1156 *
1157 * CertificateSerialNumber ::= INTEGER
1158 *
1159 * signature AlgorithmIdentifier
1160 */
1161 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1162 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1163 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
1164 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001165 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001166 return( ret );
1167 }
1168
1169 crt->version++;
1170
1171 if( crt->version > 3 )
1172 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001173 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001174 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001175 }
1176
Paul Bakkerc70b9822013-04-07 22:00:46 +02001177 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_md,
1178 &crt->sig_pk ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001179 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001180 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001181 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001182 }
1183
1184 /*
1185 * issuer Name
1186 */
1187 crt->issuer_raw.p = p;
1188
1189 if( ( ret = asn1_get_tag( &p, end, &len,
1190 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1191 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001192 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001193 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001194 }
1195
1196 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1197 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001198 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001199 return( ret );
1200 }
1201
1202 crt->issuer_raw.len = p - crt->issuer_raw.p;
1203
1204 /*
1205 * Validity ::= SEQUENCE {
1206 * notBefore Time,
1207 * notAfter Time }
1208 *
1209 */
1210 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1211 &crt->valid_to ) ) != 0 )
1212 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001213 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001214 return( ret );
1215 }
1216
1217 /*
1218 * subject Name
1219 */
1220 crt->subject_raw.p = p;
1221
1222 if( ( ret = asn1_get_tag( &p, end, &len,
1223 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1224 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001225 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001226 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001227 }
1228
Paul Bakkercefb3962012-06-27 11:51:09 +00001229 if( len && ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001230 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001231 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001232 return( ret );
1233 }
1234
1235 crt->subject_raw.len = p - crt->subject_raw.p;
1236
1237 /*
1238 * SubjectPublicKeyInfo ::= SEQUENCE
1239 * algorithm AlgorithmIdentifier,
1240 * subjectPublicKey BIT STRING }
1241 */
1242 if( ( ret = asn1_get_tag( &p, end, &len,
1243 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1244 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001245 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001246 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001247 }
1248
1249 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1250 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1251 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001252 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001253 return( ret );
1254 }
1255
1256 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1257 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001258 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001259 return( ret );
1260 }
1261
1262 crt->rsa.len = mpi_size( &crt->rsa.N );
1263
1264 /*
1265 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1266 * -- If present, version shall be v2 or v3
1267 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1268 * -- If present, version shall be v2 or v3
1269 * extensions [3] EXPLICIT Extensions OPTIONAL
1270 * -- If present, version shall be v3
1271 */
1272 if( crt->version == 2 || crt->version == 3 )
1273 {
1274 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1275 if( ret != 0 )
1276 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001277 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001278 return( ret );
1279 }
1280 }
1281
1282 if( crt->version == 2 || crt->version == 3 )
1283 {
1284 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1285 if( ret != 0 )
1286 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001287 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001288 return( ret );
1289 }
1290 }
1291
1292 if( crt->version == 3 )
1293 {
Paul Bakker74111d32011-01-15 16:57:55 +00001294 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001295 if( ret != 0 )
1296 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001297 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001298 return( ret );
1299 }
1300 }
1301
1302 if( p != end )
1303 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001304 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001305 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001306 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001307 }
1308
Paul Bakkerb00ca422012-09-25 12:10:00 +00001309 end = crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001310
1311 /*
1312 * signatureAlgorithm AlgorithmIdentifier,
1313 * signatureValue BIT STRING
1314 */
1315 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1316 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001317 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001318 return( ret );
1319 }
1320
Paul Bakker535e97d2012-08-23 10:49:55 +00001321 if( crt->sig_oid1.len != crt->sig_oid2.len ||
1322 memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001323 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001324 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001325 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001326 }
1327
1328 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1329 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001330 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001331 return( ret );
1332 }
1333
1334 if( p != end )
1335 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001336 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001337 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001338 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001339 }
1340
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001341 return( 0 );
1342}
1343
1344/*
Paul Bakker42c65812013-06-24 19:21:59 +02001345 * Parse one X.509 certificate in DER format from a buffer and add them to a
1346 * chained list
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001347 */
Paul Bakker42c65812013-06-24 19:21:59 +02001348int x509parse_crt_der( x509_cert *chain, const unsigned char *buf, size_t buflen )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001349{
Paul Bakker42c65812013-06-24 19:21:59 +02001350 int ret;
1351 x509_cert *crt = chain, *prev = NULL;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001352
1353 /*
1354 * Check for valid input
1355 */
1356 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001357 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001358
1359 while( crt->version != 0 && crt->next != NULL )
1360 {
1361 prev = crt;
1362 crt = crt->next;
1363 }
1364
1365 /*
1366 * Add new certificate on the end of the chain if needed.
1367 */
1368 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001369 {
1370 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1371
Paul Bakker7d06ad22009-05-02 15:53:56 +00001372 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001373 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker320a4b52009-03-28 18:52:39 +00001374
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001375 prev = crt;
Paul Bakker7d06ad22009-05-02 15:53:56 +00001376 crt = crt->next;
1377 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001378 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001379
Paul Bakker42c65812013-06-24 19:21:59 +02001380 if( ( ret = x509parse_crt_der_core( crt, buf, buflen ) ) != 0 )
1381 {
1382 if( prev )
1383 prev->next = NULL;
1384
1385 if( crt != chain )
1386 free( crt );
1387
1388 return( ret );
1389 }
1390
1391 return( 0 );
1392}
1393
1394/*
1395 * Parse one or more PEM certificates from a buffer and add them to the chained list
1396 */
1397int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
1398{
1399 int ret, success = 0, first_error = 0, total_failed = 0;
1400 int buf_format = X509_FORMAT_DER;
1401
1402 /*
1403 * Check for valid input
1404 */
1405 if( chain == NULL || buf == NULL )
1406 return( POLARSSL_ERR_X509_INVALID_INPUT );
1407
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001408 /*
1409 * Determine buffer content. Buffer contains either one DER certificate or
1410 * one or more PEM certificates.
1411 */
1412#if defined(POLARSSL_PEM_C)
Paul Bakker3c2122f2013-06-24 19:03:14 +02001413 if( strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001414 buf_format = X509_FORMAT_PEM;
1415#endif
1416
1417 if( buf_format == X509_FORMAT_DER )
Paul Bakker42c65812013-06-24 19:21:59 +02001418 return x509parse_crt_der( chain, buf, buflen );
1419
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001420#if defined(POLARSSL_PEM_C)
1421 if( buf_format == X509_FORMAT_PEM )
1422 {
1423 pem_context pem;
1424
1425 while( buflen > 0 )
1426 {
1427 size_t use_len;
1428 pem_init( &pem );
1429
1430 ret = pem_read_buffer( &pem,
1431 "-----BEGIN CERTIFICATE-----",
1432 "-----END CERTIFICATE-----",
1433 buf, NULL, 0, &use_len );
1434
1435 if( ret == 0 )
1436 {
1437 /*
1438 * Was PEM encoded
1439 */
1440 buflen -= use_len;
1441 buf += use_len;
1442 }
Paul Bakker5ed3b342013-06-24 19:05:46 +02001443 else if( ret == POLARSSL_ERR_PEM_BAD_INPUT_DATA )
1444 {
1445 return( ret );
1446 }
Paul Bakker00b28602013-06-24 13:02:41 +02001447 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001448 {
1449 pem_free( &pem );
1450
Paul Bakker5ed3b342013-06-24 19:05:46 +02001451 /*
1452 * PEM header and footer were found
1453 */
1454 buflen -= use_len;
1455 buf += use_len;
1456
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001457 if( first_error == 0 )
1458 first_error = ret;
1459
1460 continue;
1461 }
1462 else
1463 break;
1464
Paul Bakker42c65812013-06-24 19:21:59 +02001465 ret = x509parse_crt_der( chain, pem.buf, pem.buflen );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001466
1467 pem_free( &pem );
1468
1469 if( ret != 0 )
1470 {
1471 /*
Paul Bakker42c65812013-06-24 19:21:59 +02001472 * Quit parsing on a memory error
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001473 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001474 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001475 return( ret );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001476
1477 if( first_error == 0 )
1478 first_error = ret;
1479
Paul Bakker42c65812013-06-24 19:21:59 +02001480 total_failed++;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001481 continue;
1482 }
1483
1484 success = 1;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001485 }
1486 }
1487#endif
1488
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001489 if( success )
Paul Bakker69e095c2011-12-10 21:55:01 +00001490 return( total_failed );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001491 else if( first_error )
1492 return( first_error );
1493 else
1494 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001495}
1496
1497/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001498 * Parse one or more CRLs and add them to the chained list
1499 */
Paul Bakker23986e52011-04-24 08:57:21 +00001500int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001501{
Paul Bakker23986e52011-04-24 08:57:21 +00001502 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001503 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001504 unsigned char *p, *end;
1505 x509_crl *crl;
Paul Bakker96743fc2011-02-12 14:30:57 +00001506#if defined(POLARSSL_PEM_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00001507 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001508 pem_context pem;
1509#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001510
1511 crl = chain;
1512
1513 /*
1514 * Check for valid input
1515 */
1516 if( crl == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001517 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001518
1519 while( crl->version != 0 && crl->next != NULL )
1520 crl = crl->next;
1521
1522 /*
1523 * Add new CRL on the end of the chain if needed.
1524 */
1525 if ( crl->version != 0 && crl->next == NULL)
1526 {
1527 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1528
Paul Bakker7d06ad22009-05-02 15:53:56 +00001529 if( crl->next == NULL )
1530 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001531 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001532 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001533 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001534
Paul Bakker7d06ad22009-05-02 15:53:56 +00001535 crl = crl->next;
1536 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001537 }
1538
Paul Bakker96743fc2011-02-12 14:30:57 +00001539#if defined(POLARSSL_PEM_C)
1540 pem_init( &pem );
1541 ret = pem_read_buffer( &pem,
1542 "-----BEGIN X509 CRL-----",
1543 "-----END X509 CRL-----",
1544 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001545
Paul Bakker96743fc2011-02-12 14:30:57 +00001546 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001547 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001548 /*
1549 * Was PEM encoded
1550 */
1551 buflen -= use_len;
1552 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001553
1554 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001555 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001556 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001557 p = pem.buf;
1558 pem.buf = NULL;
1559 len = pem.buflen;
1560 pem_free( &pem );
1561 }
Paul Bakker00b28602013-06-24 13:02:41 +02001562 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker96743fc2011-02-12 14:30:57 +00001563 {
1564 pem_free( &pem );
1565 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001566 }
1567 else
1568 {
1569 /*
1570 * nope, copy the raw DER data
1571 */
1572 p = (unsigned char *) malloc( len = buflen );
1573
1574 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001575 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001576
1577 memcpy( p, buf, buflen );
1578
1579 buflen = 0;
1580 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001581#else
1582 p = (unsigned char *) malloc( len = buflen );
1583
1584 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001585 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001586
1587 memcpy( p, buf, buflen );
1588
1589 buflen = 0;
1590#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001591
1592 crl->raw.p = p;
1593 crl->raw.len = len;
1594 end = p + len;
1595
1596 /*
1597 * CertificateList ::= SEQUENCE {
1598 * tbsCertList TBSCertList,
1599 * signatureAlgorithm AlgorithmIdentifier,
1600 * signatureValue BIT STRING }
1601 */
1602 if( ( ret = asn1_get_tag( &p, end, &len,
1603 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1604 {
1605 x509_crl_free( crl );
1606 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1607 }
1608
Paul Bakker23986e52011-04-24 08:57:21 +00001609 if( len != (size_t) ( end - p ) )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001610 {
1611 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001612 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001613 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1614 }
1615
1616 /*
1617 * TBSCertList ::= SEQUENCE {
1618 */
1619 crl->tbs.p = p;
1620
1621 if( ( ret = asn1_get_tag( &p, end, &len,
1622 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1623 {
1624 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001625 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001626 }
1627
1628 end = p + len;
1629 crl->tbs.len = end - crl->tbs.p;
1630
1631 /*
1632 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1633 * -- if present, MUST be v2
1634 *
1635 * signature AlgorithmIdentifier
1636 */
Paul Bakker3329d1f2011-10-12 09:55:01 +00001637 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
Paul Bakkerd98030e2009-05-02 15:13:40 +00001638 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1639 {
1640 x509_crl_free( crl );
1641 return( ret );
1642 }
1643
1644 crl->version++;
1645
1646 if( crl->version > 2 )
1647 {
1648 x509_crl_free( crl );
1649 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1650 }
1651
Paul Bakkerc70b9822013-04-07 22:00:46 +02001652 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_md,
1653 &crl->sig_pk ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001654 {
1655 x509_crl_free( crl );
1656 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1657 }
1658
1659 /*
1660 * issuer Name
1661 */
1662 crl->issuer_raw.p = p;
1663
1664 if( ( ret = asn1_get_tag( &p, end, &len,
1665 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1666 {
1667 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001668 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001669 }
1670
1671 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1672 {
1673 x509_crl_free( crl );
1674 return( ret );
1675 }
1676
1677 crl->issuer_raw.len = p - crl->issuer_raw.p;
1678
1679 /*
1680 * thisUpdate Time
1681 * nextUpdate Time OPTIONAL
1682 */
Paul Bakker91200182010-02-18 21:26:15 +00001683 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001684 {
1685 x509_crl_free( crl );
1686 return( ret );
1687 }
1688
Paul Bakker91200182010-02-18 21:26:15 +00001689 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001690 {
Paul Bakker9d781402011-05-09 16:17:09 +00001691 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001692 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker9d781402011-05-09 16:17:09 +00001693 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001694 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001695 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001696 x509_crl_free( crl );
1697 return( ret );
1698 }
1699 }
1700
1701 /*
1702 * revokedCertificates SEQUENCE OF SEQUENCE {
1703 * userCertificate CertificateSerialNumber,
1704 * revocationDate Time,
1705 * crlEntryExtensions Extensions OPTIONAL
1706 * -- if present, MUST be v2
1707 * } OPTIONAL
1708 */
1709 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1710 {
1711 x509_crl_free( crl );
1712 return( ret );
1713 }
1714
1715 /*
1716 * crlExtensions EXPLICIT Extensions OPTIONAL
1717 * -- if present, MUST be v2
1718 */
1719 if( crl->version == 2 )
1720 {
1721 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1722
1723 if( ret != 0 )
1724 {
1725 x509_crl_free( crl );
1726 return( ret );
1727 }
1728 }
1729
1730 if( p != end )
1731 {
1732 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001733 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001734 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1735 }
1736
1737 end = crl->raw.p + crl->raw.len;
1738
1739 /*
1740 * signatureAlgorithm AlgorithmIdentifier,
1741 * signatureValue BIT STRING
1742 */
1743 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1744 {
1745 x509_crl_free( crl );
1746 return( ret );
1747 }
1748
Paul Bakker535e97d2012-08-23 10:49:55 +00001749 if( crl->sig_oid1.len != crl->sig_oid2.len ||
1750 memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001751 {
1752 x509_crl_free( crl );
1753 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1754 }
1755
1756 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1757 {
1758 x509_crl_free( crl );
1759 return( ret );
1760 }
1761
1762 if( p != end )
1763 {
1764 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001765 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001766 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1767 }
1768
1769 if( buflen > 0 )
1770 {
1771 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1772
Paul Bakker7d06ad22009-05-02 15:53:56 +00001773 if( crl->next == NULL )
1774 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001775 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001776 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001777 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001778
Paul Bakker7d06ad22009-05-02 15:53:56 +00001779 crl = crl->next;
1780 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001781
1782 return( x509parse_crl( crl, buf, buflen ) );
1783 }
1784
1785 return( 0 );
1786}
1787
Paul Bakker335db3f2011-04-25 15:28:35 +00001788#if defined(POLARSSL_FS_IO)
Paul Bakkerd98030e2009-05-02 15:13:40 +00001789/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001790 * Load all data from a file into a given buffer.
1791 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02001792static int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001793{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001794 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001795
Paul Bakkerd98030e2009-05-02 15:13:40 +00001796 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001797 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001798
Paul Bakkerd98030e2009-05-02 15:13:40 +00001799 fseek( f, 0, SEEK_END );
1800 *n = (size_t) ftell( f );
1801 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001802
Paul Bakkerd98030e2009-05-02 15:13:40 +00001803 if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
Paul Bakkerf6a19bd2013-05-14 13:26:51 +02001804 {
1805 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +00001806 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerf6a19bd2013-05-14 13:26:51 +02001807 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001808
Paul Bakkerd98030e2009-05-02 15:13:40 +00001809 if( fread( *buf, 1, *n, f ) != *n )
1810 {
1811 fclose( f );
1812 free( *buf );
Paul Bakker69e095c2011-12-10 21:55:01 +00001813 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001814 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001815
Paul Bakkerd98030e2009-05-02 15:13:40 +00001816 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001817
Paul Bakkerd98030e2009-05-02 15:13:40 +00001818 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001819
Paul Bakkerd98030e2009-05-02 15:13:40 +00001820 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001821}
1822
1823/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001824 * Load one or more certificates and add them to the chained list
1825 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001826int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001827{
1828 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001829 size_t n;
1830 unsigned char *buf;
1831
Paul Bakker69e095c2011-12-10 21:55:01 +00001832 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1833 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001834
Paul Bakker69e095c2011-12-10 21:55:01 +00001835 ret = x509parse_crt( chain, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001836
1837 memset( buf, 0, n + 1 );
1838 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001839
1840 return( ret );
1841}
1842
Paul Bakker8d914582012-06-04 12:46:42 +00001843int x509parse_crtpath( x509_cert *chain, const char *path )
1844{
1845 int ret = 0;
1846#if defined(_WIN32)
Paul Bakker3338b792012-10-01 21:13:10 +00001847 int w_ret;
1848 WCHAR szDir[MAX_PATH];
1849 char filename[MAX_PATH];
1850 char *p;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001851 int len = strlen( path );
Paul Bakker3338b792012-10-01 21:13:10 +00001852
Paul Bakker97872ac2012-11-02 12:53:26 +00001853 WIN32_FIND_DATAW file_data;
Paul Bakker8d914582012-06-04 12:46:42 +00001854 HANDLE hFind;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001855
1856 if( len > MAX_PATH - 3 )
1857 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker8d914582012-06-04 12:46:42 +00001858
Paul Bakker3338b792012-10-01 21:13:10 +00001859 memset( szDir, 0, sizeof(szDir) );
1860 memset( filename, 0, MAX_PATH );
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001861 memcpy( filename, path, len );
1862 filename[len++] = '\\';
1863 p = filename + len;
1864 filename[len++] = '*';
Paul Bakker3338b792012-10-01 21:13:10 +00001865
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001866 w_ret = MultiByteToWideChar( CP_ACP, 0, path, len, szDir, MAX_PATH - 3 );
Paul Bakker8d914582012-06-04 12:46:42 +00001867
Paul Bakker97872ac2012-11-02 12:53:26 +00001868 hFind = FindFirstFileW( szDir, &file_data );
Paul Bakker8d914582012-06-04 12:46:42 +00001869 if (hFind == INVALID_HANDLE_VALUE)
1870 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1871
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001872 len = MAX_PATH - len;
Paul Bakker8d914582012-06-04 12:46:42 +00001873 do
1874 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001875 memset( p, 0, len );
Paul Bakker3338b792012-10-01 21:13:10 +00001876
Paul Bakkere4791f32012-06-04 21:29:15 +00001877 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
Paul Bakker8d914582012-06-04 12:46:42 +00001878 continue;
1879
Paul Bakker3338b792012-10-01 21:13:10 +00001880 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
1881 lstrlenW(file_data.cFileName),
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001882 p, len - 1,
1883 NULL, NULL );
Paul Bakker8d914582012-06-04 12:46:42 +00001884
Paul Bakker3338b792012-10-01 21:13:10 +00001885 w_ret = x509parse_crtfile( chain, filename );
1886 if( w_ret < 0 )
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001887 ret++;
1888 else
1889 ret += w_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001890 }
Paul Bakker97872ac2012-11-02 12:53:26 +00001891 while( FindNextFileW( hFind, &file_data ) != 0 );
Paul Bakker8d914582012-06-04 12:46:42 +00001892
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001893 if (GetLastError() != ERROR_NO_MORE_FILES)
1894 ret = POLARSSL_ERR_X509_FILE_IO_ERROR;
Paul Bakker8d914582012-06-04 12:46:42 +00001895
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001896cleanup:
Paul Bakker8d914582012-06-04 12:46:42 +00001897 FindClose( hFind );
1898#else
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001899 int t_ret, i;
1900 struct stat sb;
1901 struct dirent entry, *result = NULL;
Paul Bakker8d914582012-06-04 12:46:42 +00001902 char entry_name[255];
1903 DIR *dir = opendir( path );
1904
1905 if( dir == NULL)
1906 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1907
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001908 while( ( t_ret = readdir_r( dir, &entry, &result ) ) == 0 )
Paul Bakker8d914582012-06-04 12:46:42 +00001909 {
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001910 if( result == NULL )
1911 break;
1912
1913 snprintf( entry_name, sizeof(entry_name), "%s/%s", path, entry.d_name );
1914
1915 i = stat( entry_name, &sb );
1916
1917 if( i == -1 )
1918 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1919
1920 if( !S_ISREG( sb.st_mode ) )
Paul Bakker8d914582012-06-04 12:46:42 +00001921 continue;
1922
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001923 // Ignore parse errors
1924 //
Paul Bakker8d914582012-06-04 12:46:42 +00001925 t_ret = x509parse_crtfile( chain, entry_name );
1926 if( t_ret < 0 )
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001927 ret++;
1928 else
1929 ret += t_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001930 }
1931 closedir( dir );
1932#endif
1933
1934 return( ret );
1935}
1936
Paul Bakkerd98030e2009-05-02 15:13:40 +00001937/*
1938 * Load one or more CRLs and add them to the chained list
1939 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001940int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001941{
1942 int ret;
1943 size_t n;
1944 unsigned char *buf;
1945
Paul Bakker69e095c2011-12-10 21:55:01 +00001946 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1947 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001948
Paul Bakker27fdf462011-06-09 13:55:13 +00001949 ret = x509parse_crl( chain, buf, n );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001950
1951 memset( buf, 0, n + 1 );
1952 free( buf );
1953
1954 return( ret );
1955}
1956
Paul Bakker5121ce52009-01-03 21:22:43 +00001957/*
Paul Bakker335db3f2011-04-25 15:28:35 +00001958 * Load and parse a private RSA key
1959 */
1960int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
1961{
1962 int ret;
1963 size_t n;
1964 unsigned char *buf;
1965
Paul Bakker69e095c2011-12-10 21:55:01 +00001966 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1967 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00001968
1969 if( pwd == NULL )
Paul Bakker27fdf462011-06-09 13:55:13 +00001970 ret = x509parse_key( rsa, buf, n, NULL, 0 );
Paul Bakker335db3f2011-04-25 15:28:35 +00001971 else
Paul Bakker27fdf462011-06-09 13:55:13 +00001972 ret = x509parse_key( rsa, buf, n,
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02001973 (const unsigned char *) pwd, strlen( pwd ) );
Paul Bakker335db3f2011-04-25 15:28:35 +00001974
1975 memset( buf, 0, n + 1 );
1976 free( buf );
1977
1978 return( ret );
1979}
1980
1981/*
1982 * Load and parse a public RSA key
1983 */
1984int x509parse_public_keyfile( rsa_context *rsa, const char *path )
1985{
1986 int ret;
1987 size_t n;
1988 unsigned char *buf;
1989
Paul Bakker69e095c2011-12-10 21:55:01 +00001990 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1991 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00001992
Paul Bakker27fdf462011-06-09 13:55:13 +00001993 ret = x509parse_public_key( rsa, buf, n );
Paul Bakker335db3f2011-04-25 15:28:35 +00001994
1995 memset( buf, 0, n + 1 );
1996 free( buf );
1997
1998 return( ret );
1999}
2000#endif /* POLARSSL_FS_IO */
2001
2002/*
Paul Bakkere2f50402013-06-24 19:00:59 +02002003 * Parse a PKCS#1 encoded private RSA key
Paul Bakker5121ce52009-01-03 21:22:43 +00002004 */
Paul Bakkere2f50402013-06-24 19:00:59 +02002005static int x509parse_key_pkcs1_der( rsa_context *rsa,
2006 const unsigned char *key,
2007 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +00002008{
Paul Bakker23986e52011-04-24 08:57:21 +00002009 int ret;
2010 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00002011 unsigned char *p, *end;
Paul Bakkered56b222011-07-13 11:26:43 +00002012
Paul Bakker96743fc2011-02-12 14:30:57 +00002013 p = (unsigned char *) key;
Paul Bakker96743fc2011-02-12 14:30:57 +00002014 end = p + keylen;
2015
Paul Bakker5121ce52009-01-03 21:22:43 +00002016 /*
Paul Bakkere2f50402013-06-24 19:00:59 +02002017 * This function parses the RSAPrivateKey (PKCS#1)
Paul Bakkered56b222011-07-13 11:26:43 +00002018 *
Paul Bakker5121ce52009-01-03 21:22:43 +00002019 * RSAPrivateKey ::= SEQUENCE {
2020 * version Version,
2021 * modulus INTEGER, -- n
2022 * publicExponent INTEGER, -- e
2023 * privateExponent INTEGER, -- d
2024 * prime1 INTEGER, -- p
2025 * prime2 INTEGER, -- q
2026 * exponent1 INTEGER, -- d mod (p-1)
2027 * exponent2 INTEGER, -- d mod (q-1)
2028 * coefficient INTEGER, -- (inverse of q) mod p
2029 * otherPrimeInfos OtherPrimeInfos OPTIONAL
2030 * }
2031 */
2032 if( ( ret = asn1_get_tag( &p, end, &len,
2033 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2034 {
Paul Bakker9d781402011-05-09 16:17:09 +00002035 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002036 }
2037
2038 end = p + len;
2039
2040 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2041 {
Paul Bakker9d781402011-05-09 16:17:09 +00002042 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002043 }
2044
2045 if( rsa->ver != 0 )
2046 {
Paul Bakker9d781402011-05-09 16:17:09 +00002047 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002048 }
2049
2050 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
2051 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
2052 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
2053 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
2054 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
2055 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
2056 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
2057 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
2058 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002059 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002060 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002061 }
2062
2063 rsa->len = mpi_size( &rsa->N );
2064
2065 if( p != end )
2066 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002067 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002068 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00002069 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002070 }
2071
2072 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2073 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002074 rsa_free( rsa );
2075 return( ret );
2076 }
2077
Paul Bakkere2f50402013-06-24 19:00:59 +02002078 return( 0 );
2079}
2080
2081/*
2082 * Parse an unencrypted PKCS#8 encoded private RSA key
2083 */
2084static int x509parse_key_pkcs8_unencrypted_der(
2085 rsa_context *rsa,
2086 const unsigned char *key,
2087 size_t keylen )
2088{
2089 int ret;
2090 size_t len;
2091 unsigned char *p, *end;
2092 x509_buf pk_alg_oid;
2093 pk_type_t pk_alg = POLARSSL_PK_NONE;
2094
2095 p = (unsigned char *) key;
2096 end = p + keylen;
2097
2098 /*
2099 * This function parses the PrivatKeyInfo object (PKCS#8)
2100 *
2101 * PrivateKeyInfo ::= SEQUENCE {
2102 * version Version,
2103 * algorithm AlgorithmIdentifier,
2104 * PrivateKey BIT STRING
2105 * }
2106 *
2107 * AlgorithmIdentifier ::= SEQUENCE {
2108 * algorithm OBJECT IDENTIFIER,
2109 * parameters ANY DEFINED BY algorithm OPTIONAL
2110 * }
2111 *
2112 * The PrivateKey BIT STRING is a PKCS#1 RSAPrivateKey
2113 */
2114 if( ( ret = asn1_get_tag( &p, end, &len,
2115 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2116 {
2117 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2118 }
2119
2120 end = p + len;
2121
2122 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2123 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2124
2125 if( rsa->ver != 0 )
2126 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2127
Paul Bakkerf8d018a2013-06-29 12:16:17 +02002128 if( ( ret = asn1_get_alg_null( &p, end, &pk_alg_oid ) ) != 0 )
Paul Bakkere2f50402013-06-24 19:00:59 +02002129 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2130
2131 /*
2132 * only RSA keys handled at this time
2133 */
2134 if( oid_get_pk_alg( &pk_alg_oid, &pk_alg ) != 0 )
2135 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
2136
2137 /*
2138 * Get the OCTET STRING and parse the PKCS#1 format inside
2139 */
2140 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2141 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2142
2143 if( ( end - p ) < 1 )
2144 {
2145 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
2146 POLARSSL_ERR_ASN1_OUT_OF_DATA );
2147 }
2148
2149 end = p + len;
2150
2151 if( ( ret = x509parse_key_pkcs1_der( rsa, p, end - p ) ) != 0 )
2152 return( ret );
2153
2154 return( 0 );
2155}
2156
2157/*
Paul Bakkerbda7cb72013-06-24 19:34:25 +02002158 * Parse an encrypted PKCS#8 encoded private RSA key
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002159 */
2160static int x509parse_key_pkcs8_encrypted_der(
2161 rsa_context *rsa,
2162 const unsigned char *key,
2163 size_t keylen,
2164 const unsigned char *pwd,
2165 size_t pwdlen )
2166{
2167 int ret;
2168 size_t len;
Paul Bakkerf8d018a2013-06-29 12:16:17 +02002169 unsigned char *p, *end;
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002170 x509_buf pbe_alg_oid, pbe_params;
2171 unsigned char buf[2048];
Paul Bakker7749a222013-06-28 17:28:20 +02002172#if defined(POLARSSL_PKCS12_C)
2173 cipher_type_t cipher_alg;
2174 md_type_t md_alg;
2175#endif
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002176
2177 memset(buf, 0, 2048);
2178
2179 p = (unsigned char *) key;
2180 end = p + keylen;
2181
Paul Bakker28144de2013-06-24 19:28:55 +02002182 if( pwdlen == 0 )
2183 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
2184
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002185 /*
2186 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
2187 *
2188 * EncryptedPrivateKeyInfo ::= SEQUENCE {
2189 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
2190 * encryptedData EncryptedData
2191 * }
2192 *
2193 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
2194 *
2195 * EncryptedData ::= OCTET STRING
2196 *
2197 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
2198 */
2199 if( ( ret = asn1_get_tag( &p, end, &len,
2200 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2201 {
2202 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2203 }
2204
2205 end = p + len;
2206
Paul Bakkerf8d018a2013-06-29 12:16:17 +02002207 if( ( ret = asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002208 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002209
2210 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2211 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2212
2213 // buf has been sized to 2048 bytes
2214 if( len > 2048 )
2215 return( POLARSSL_ERR_X509_INVALID_INPUT );
2216
2217 /*
2218 * Decrypt EncryptedData with appropriate PDE
2219 */
Paul Bakker38b50d72013-06-24 19:33:27 +02002220#if defined(POLARSSL_PKCS12_C)
Paul Bakker7749a222013-06-28 17:28:20 +02002221 if( oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002222 {
Paul Bakker38b50d72013-06-24 19:33:27 +02002223 if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
Paul Bakker7749a222013-06-28 17:28:20 +02002224 cipher_alg, md_alg,
Paul Bakker38b50d72013-06-24 19:33:27 +02002225 pwd, pwdlen, p, len, buf ) ) != 0 )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002226 {
Paul Bakker38b50d72013-06-24 19:33:27 +02002227 if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH )
2228 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2229
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002230 return( ret );
2231 }
2232 }
2233 else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) )
2234 {
2235 if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params,
2236 PKCS12_PBE_DECRYPT,
2237 pwd, pwdlen,
2238 p, len, buf ) ) != 0 )
2239 {
2240 return( ret );
2241 }
Paul Bakker38b50d72013-06-24 19:33:27 +02002242
2243 // Best guess for password mismatch when using RC4. If first tag is
2244 // not ASN1_CONSTRUCTED | ASN1_SEQUENCE
2245 //
2246 if( *buf != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
2247 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002248 }
Paul Bakker38b50d72013-06-24 19:33:27 +02002249 else
2250#endif /* POLARSSL_PKCS12_C */
Paul Bakker28144de2013-06-24 19:28:55 +02002251#if defined(POLARSSL_PKCS5_C)
Paul Bakker38b50d72013-06-24 19:33:27 +02002252 if( OID_CMP( OID_PKCS5_PBES2, &pbe_alg_oid ) )
Paul Bakker28144de2013-06-24 19:28:55 +02002253 {
2254 if( ( ret = pkcs5_pbes2( &pbe_params, PKCS5_DECRYPT, pwd, pwdlen,
2255 p, len, buf ) ) != 0 )
2256 {
2257 if( ret == POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH )
2258 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2259
2260 return( ret );
2261 }
2262 }
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002263 else
Paul Bakker38b50d72013-06-24 19:33:27 +02002264#endif /* POLARSSL_PKCS5_C */
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002265 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
2266
2267 return x509parse_key_pkcs8_unencrypted_der( rsa, buf, len );
2268}
2269
2270/*
Paul Bakkere2f50402013-06-24 19:00:59 +02002271 * Parse a private RSA key
2272 */
2273int x509parse_key( rsa_context *rsa, const unsigned char *key, size_t keylen,
2274 const unsigned char *pwd, size_t pwdlen )
2275{
2276 int ret;
2277
Paul Bakker96743fc2011-02-12 14:30:57 +00002278#if defined(POLARSSL_PEM_C)
Paul Bakkere2f50402013-06-24 19:00:59 +02002279 size_t len;
2280 pem_context pem;
2281
2282 pem_init( &pem );
2283 ret = pem_read_buffer( &pem,
2284 "-----BEGIN RSA PRIVATE KEY-----",
2285 "-----END RSA PRIVATE KEY-----",
2286 key, pwd, pwdlen, &len );
2287 if( ret == 0 )
2288 {
2289 if( ( ret = x509parse_key_pkcs1_der( rsa, pem.buf, pem.buflen ) ) != 0 )
2290 {
2291 rsa_free( rsa );
2292 }
2293
2294 pem_free( &pem );
2295 return( ret );
2296 }
Paul Bakkera4232a72013-06-24 19:32:25 +02002297 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
2298 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2299 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
2300 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
Paul Bakkere2f50402013-06-24 19:00:59 +02002301 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkere2f50402013-06-24 19:00:59 +02002302 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002303
2304 ret = pem_read_buffer( &pem,
2305 "-----BEGIN PRIVATE KEY-----",
2306 "-----END PRIVATE KEY-----",
2307 key, NULL, 0, &len );
2308 if( ret == 0 )
2309 {
2310 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa,
2311 pem.buf, pem.buflen ) ) != 0 )
2312 {
2313 rsa_free( rsa );
2314 }
2315
2316 pem_free( &pem );
2317 return( ret );
2318 }
2319 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkere2f50402013-06-24 19:00:59 +02002320 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002321
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002322 ret = pem_read_buffer( &pem,
2323 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
2324 "-----END ENCRYPTED PRIVATE KEY-----",
2325 key, NULL, 0, &len );
2326 if( ret == 0 )
2327 {
2328 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa,
2329 pem.buf, pem.buflen,
2330 pwd, pwdlen ) ) != 0 )
2331 {
2332 rsa_free( rsa );
2333 }
2334
2335 pem_free( &pem );
2336 return( ret );
2337 }
2338 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002339 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002340#else
2341 ((void) pwd);
2342 ((void) pwdlen);
2343#endif /* POLARSSL_PEM_C */
2344
2345 // At this point we only know it's not a PEM formatted key. Could be any
2346 // of the known DER encoded private key formats
2347 //
2348 // We try the different DER format parsers to see if one passes without
2349 // error
2350 //
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002351 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa, key, keylen,
2352 pwd, pwdlen ) ) == 0 )
Paul Bakkere2f50402013-06-24 19:00:59 +02002353 {
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002354 return( 0 );
Paul Bakkere2f50402013-06-24 19:00:59 +02002355 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002356
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002357 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002358
2359 if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH )
2360 {
2361 return( ret );
2362 }
2363
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002364 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa, key, keylen ) ) == 0 )
2365 return( 0 );
2366
2367 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002368
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002369 if( ( ret = x509parse_key_pkcs1_der( rsa, key, keylen ) ) == 0 )
2370 return( 0 );
2371
2372 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002373
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002374 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00002375}
2376
2377/*
Paul Bakker53019ae2011-03-25 13:58:48 +00002378 * Parse a public RSA key
2379 */
Paul Bakker23986e52011-04-24 08:57:21 +00002380int x509parse_public_key( rsa_context *rsa, const unsigned char *key, size_t keylen )
Paul Bakker53019ae2011-03-25 13:58:48 +00002381{
Paul Bakker23986e52011-04-24 08:57:21 +00002382 int ret;
2383 size_t len;
Paul Bakker53019ae2011-03-25 13:58:48 +00002384 unsigned char *p, *end;
2385 x509_buf alg_oid;
2386#if defined(POLARSSL_PEM_C)
2387 pem_context pem;
2388
2389 pem_init( &pem );
2390 ret = pem_read_buffer( &pem,
2391 "-----BEGIN PUBLIC KEY-----",
2392 "-----END PUBLIC KEY-----",
2393 key, NULL, 0, &len );
2394
2395 if( ret == 0 )
2396 {
2397 /*
2398 * Was PEM encoded
2399 */
2400 keylen = pem.buflen;
2401 }
Paul Bakker00b28602013-06-24 13:02:41 +02002402 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker53019ae2011-03-25 13:58:48 +00002403 {
2404 pem_free( &pem );
2405 return( ret );
2406 }
2407
2408 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2409#else
2410 p = (unsigned char *) key;
2411#endif
2412 end = p + keylen;
2413
2414 /*
2415 * PublicKeyInfo ::= SEQUENCE {
2416 * algorithm AlgorithmIdentifier,
2417 * PublicKey BIT STRING
2418 * }
2419 *
2420 * AlgorithmIdentifier ::= SEQUENCE {
2421 * algorithm OBJECT IDENTIFIER,
2422 * parameters ANY DEFINED BY algorithm OPTIONAL
2423 * }
2424 *
2425 * RSAPublicKey ::= SEQUENCE {
2426 * modulus INTEGER, -- n
2427 * publicExponent INTEGER -- e
2428 * }
2429 */
2430
2431 if( ( ret = asn1_get_tag( &p, end, &len,
2432 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2433 {
2434#if defined(POLARSSL_PEM_C)
2435 pem_free( &pem );
2436#endif
2437 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002438 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002439 }
2440
2441 if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
2442 {
2443#if defined(POLARSSL_PEM_C)
2444 pem_free( &pem );
2445#endif
2446 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002447 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002448 }
2449
2450 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
2451 {
2452#if defined(POLARSSL_PEM_C)
2453 pem_free( &pem );
2454#endif
2455 rsa_free( rsa );
2456 return( ret );
2457 }
2458
2459 rsa->len = mpi_size( &rsa->N );
2460
2461#if defined(POLARSSL_PEM_C)
2462 pem_free( &pem );
2463#endif
2464
2465 return( 0 );
2466}
2467
Paul Bakkereaa89f82011-04-04 21:36:15 +00002468#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00002469/*
Paul Bakker1b57b062011-01-06 15:48:19 +00002470 * Parse DHM parameters
2471 */
Paul Bakker23986e52011-04-24 08:57:21 +00002472int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
Paul Bakker1b57b062011-01-06 15:48:19 +00002473{
Paul Bakker23986e52011-04-24 08:57:21 +00002474 int ret;
2475 size_t len;
Paul Bakker1b57b062011-01-06 15:48:19 +00002476 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00002477#if defined(POLARSSL_PEM_C)
2478 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00002479
Paul Bakker96743fc2011-02-12 14:30:57 +00002480 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00002481
Paul Bakker96743fc2011-02-12 14:30:57 +00002482 ret = pem_read_buffer( &pem,
2483 "-----BEGIN DH PARAMETERS-----",
2484 "-----END DH PARAMETERS-----",
2485 dhmin, NULL, 0, &dhminlen );
2486
2487 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00002488 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002489 /*
2490 * Was PEM encoded
2491 */
2492 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00002493 }
Paul Bakker00b28602013-06-24 13:02:41 +02002494 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00002495 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002496 pem_free( &pem );
2497 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002498 }
2499
Paul Bakker96743fc2011-02-12 14:30:57 +00002500 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
2501#else
2502 p = (unsigned char *) dhmin;
2503#endif
2504 end = p + dhminlen;
2505
Paul Bakker1b57b062011-01-06 15:48:19 +00002506 memset( dhm, 0, sizeof( dhm_context ) );
2507
Paul Bakker1b57b062011-01-06 15:48:19 +00002508 /*
2509 * DHParams ::= SEQUENCE {
2510 * prime INTEGER, -- P
2511 * generator INTEGER, -- g
2512 * }
2513 */
2514 if( ( ret = asn1_get_tag( &p, end, &len,
2515 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2516 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002517#if defined(POLARSSL_PEM_C)
2518 pem_free( &pem );
2519#endif
Paul Bakker9d781402011-05-09 16:17:09 +00002520 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002521 }
2522
2523 end = p + len;
2524
2525 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
2526 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
2527 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002528#if defined(POLARSSL_PEM_C)
2529 pem_free( &pem );
2530#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002531 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002532 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002533 }
2534
2535 if( p != end )
2536 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002537#if defined(POLARSSL_PEM_C)
2538 pem_free( &pem );
2539#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002540 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002541 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker1b57b062011-01-06 15:48:19 +00002542 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
2543 }
2544
Paul Bakker96743fc2011-02-12 14:30:57 +00002545#if defined(POLARSSL_PEM_C)
2546 pem_free( &pem );
2547#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002548
2549 return( 0 );
2550}
2551
Paul Bakker335db3f2011-04-25 15:28:35 +00002552#if defined(POLARSSL_FS_IO)
Paul Bakker1b57b062011-01-06 15:48:19 +00002553/*
2554 * Load and parse a private RSA key
2555 */
2556int x509parse_dhmfile( dhm_context *dhm, const char *path )
2557{
2558 int ret;
2559 size_t n;
2560 unsigned char *buf;
2561
Paul Bakker69e095c2011-12-10 21:55:01 +00002562 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
2563 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002564
Paul Bakker27fdf462011-06-09 13:55:13 +00002565 ret = x509parse_dhm( dhm, buf, n );
Paul Bakker1b57b062011-01-06 15:48:19 +00002566
2567 memset( buf, 0, n + 1 );
2568 free( buf );
2569
2570 return( ret );
2571}
Paul Bakker335db3f2011-04-25 15:28:35 +00002572#endif /* POLARSSL_FS_IO */
Paul Bakkereaa89f82011-04-04 21:36:15 +00002573#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00002574
Paul Bakker5121ce52009-01-03 21:22:43 +00002575#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002576#include <stdarg.h>
2577
2578#if !defined vsnprintf
2579#define vsnprintf _vsnprintf
2580#endif // vsnprintf
2581
2582/*
2583 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2584 * Result value is not size of buffer needed, but -1 if no fit is possible.
2585 *
2586 * This fuction tries to 'fix' this by at least suggesting enlarging the
2587 * size by 20.
2588 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02002589static int compat_snprintf(char *str, size_t size, const char *format, ...)
Paul Bakkerd98030e2009-05-02 15:13:40 +00002590{
2591 va_list ap;
2592 int res = -1;
2593
2594 va_start( ap, format );
2595
2596 res = vsnprintf( str, size, format, ap );
2597
2598 va_end( ap );
2599
2600 // No quick fix possible
2601 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00002602 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002603
2604 return res;
2605}
2606
2607#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002608#endif
2609
Paul Bakkerd98030e2009-05-02 15:13:40 +00002610#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2611
2612#define SAFE_SNPRINTF() \
2613{ \
2614 if( ret == -1 ) \
2615 return( -1 ); \
2616 \
Paul Bakker23986e52011-04-24 08:57:21 +00002617 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002618 p[n - 1] = '\0'; \
2619 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2620 } \
2621 \
Paul Bakker23986e52011-04-24 08:57:21 +00002622 n -= (unsigned int) ret; \
2623 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002624}
2625
Paul Bakker5121ce52009-01-03 21:22:43 +00002626/*
2627 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002628 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002629 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002630int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002631{
Paul Bakker23986e52011-04-24 08:57:21 +00002632 int ret;
2633 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002634 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002635 const x509_name *name;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002636 const char *short_name = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00002637 char s[128], *p;
2638
2639 memset( s, 0, sizeof( s ) );
2640
2641 name = dn;
2642 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002643 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002644
2645 while( name != NULL )
2646 {
Paul Bakkercefb3962012-06-27 11:51:09 +00002647 if( !name->oid.p )
2648 {
2649 name = name->next;
2650 continue;
2651 }
2652
Paul Bakker74111d32011-01-15 16:57:55 +00002653 if( name != dn )
2654 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002655 ret = snprintf( p, n, ", " );
2656 SAFE_SNPRINTF();
2657 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002658
Paul Bakkerc70b9822013-04-07 22:00:46 +02002659 ret = oid_get_attr_short_name( &name->oid, &short_name );
Paul Bakker5121ce52009-01-03 21:22:43 +00002660
Paul Bakkerc70b9822013-04-07 22:00:46 +02002661 if( ret == 0 )
2662 ret = snprintf( p, n, "%s=", short_name );
Paul Bakker5121ce52009-01-03 21:22:43 +00002663 else
Paul Bakkerd98030e2009-05-02 15:13:40 +00002664 ret = snprintf( p, n, "\?\?=" );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002665 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002666
2667 for( i = 0; i < name->val.len; i++ )
2668 {
Paul Bakker27fdf462011-06-09 13:55:13 +00002669 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002670 break;
2671
2672 c = name->val.p[i];
2673 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2674 s[i] = '?';
2675 else s[i] = c;
2676 }
2677 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002678 ret = snprintf( p, n, "%s", s );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002679 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002680 name = name->next;
2681 }
2682
Paul Bakker23986e52011-04-24 08:57:21 +00002683 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002684}
2685
2686/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002687 * Store the serial in printable form into buf; no more
2688 * than size characters will be written
2689 */
2690int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2691{
Paul Bakker23986e52011-04-24 08:57:21 +00002692 int ret;
2693 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00002694 char *p;
2695
2696 p = buf;
2697 n = size;
2698
2699 nr = ( serial->len <= 32 )
Paul Bakker03c7c252011-11-25 12:37:37 +00002700 ? serial->len : 28;
Paul Bakkerdd476992011-01-16 21:34:59 +00002701
2702 for( i = 0; i < nr; i++ )
2703 {
Paul Bakker93048802011-12-05 14:38:06 +00002704 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002705 continue;
2706
Paul Bakkerdd476992011-01-16 21:34:59 +00002707 ret = snprintf( p, n, "%02X%s",
2708 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2709 SAFE_SNPRINTF();
2710 }
2711
Paul Bakker03c7c252011-11-25 12:37:37 +00002712 if( nr != serial->len )
2713 {
2714 ret = snprintf( p, n, "...." );
2715 SAFE_SNPRINTF();
2716 }
2717
Paul Bakker23986e52011-04-24 08:57:21 +00002718 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00002719}
2720
2721/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002722 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002723 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002724int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2725 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002726{
Paul Bakker23986e52011-04-24 08:57:21 +00002727 int ret;
2728 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002729 char *p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002730 const char *desc = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00002731
2732 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002733 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002734
Paul Bakkerd98030e2009-05-02 15:13:40 +00002735 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002736 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002737 SAFE_SNPRINTF();
2738 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002739 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002740 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002741
Paul Bakkerdd476992011-01-16 21:34:59 +00002742 ret = x509parse_serial_gets( p, n, &crt->serial);
2743 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002744
Paul Bakkerd98030e2009-05-02 15:13:40 +00002745 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2746 SAFE_SNPRINTF();
2747 ret = x509parse_dn_gets( p, n, &crt->issuer );
2748 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002749
Paul Bakkerd98030e2009-05-02 15:13:40 +00002750 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2751 SAFE_SNPRINTF();
2752 ret = x509parse_dn_gets( p, n, &crt->subject );
2753 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002754
Paul Bakkerd98030e2009-05-02 15:13:40 +00002755 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002756 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2757 crt->valid_from.year, crt->valid_from.mon,
2758 crt->valid_from.day, crt->valid_from.hour,
2759 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002760 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002761
Paul Bakkerd98030e2009-05-02 15:13:40 +00002762 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002763 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2764 crt->valid_to.year, crt->valid_to.mon,
2765 crt->valid_to.day, crt->valid_to.hour,
2766 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002767 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002768
Paul Bakkerc70b9822013-04-07 22:00:46 +02002769 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002770 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002771
Paul Bakkerc70b9822013-04-07 22:00:46 +02002772 ret = oid_get_sig_alg_desc( &crt->sig_oid1, &desc );
2773 if( ret != 0 )
2774 ret = snprintf( p, n, "???" );
2775 else
2776 ret = snprintf( p, n, desc );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002777 SAFE_SNPRINTF();
2778
2779 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
Paul Bakker5c2364c2012-10-01 14:41:15 +00002780 (int) crt->rsa.N.n * (int) sizeof( t_uint ) * 8 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002781 SAFE_SNPRINTF();
2782
Paul Bakker23986e52011-04-24 08:57:21 +00002783 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002784}
2785
Paul Bakker74111d32011-01-15 16:57:55 +00002786/*
2787 * Return an informational string describing the given OID
2788 */
2789const char *x509_oid_get_description( x509_buf *oid )
2790{
Paul Bakkerc70b9822013-04-07 22:00:46 +02002791 const char *desc = NULL;
2792 int ret;
Paul Bakker74111d32011-01-15 16:57:55 +00002793
Paul Bakkerc70b9822013-04-07 22:00:46 +02002794 ret = oid_get_extended_key_usage( oid, &desc );
Paul Bakker74111d32011-01-15 16:57:55 +00002795
Paul Bakkerc70b9822013-04-07 22:00:46 +02002796 if( ret != 0 )
2797 return( NULL );
Paul Bakker74111d32011-01-15 16:57:55 +00002798
Paul Bakkerc70b9822013-04-07 22:00:46 +02002799 return( desc );
Paul Bakker74111d32011-01-15 16:57:55 +00002800}
2801
2802/* Return the x.y.z.... style numeric string for the given OID */
2803int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2804{
Paul Bakkerc70b9822013-04-07 22:00:46 +02002805 return oid_get_numeric_string( buf, size, oid );
Paul Bakker74111d32011-01-15 16:57:55 +00002806}
2807
Paul Bakkerd98030e2009-05-02 15:13:40 +00002808/*
2809 * Return an informational string about the CRL.
2810 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002811int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2812 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002813{
Paul Bakker23986e52011-04-24 08:57:21 +00002814 int ret;
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002815 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002816 char *p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002817 const char *desc;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002818 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002819
2820 p = buf;
2821 n = size;
2822
2823 ret = snprintf( p, n, "%sCRL version : %d",
2824 prefix, crl->version );
2825 SAFE_SNPRINTF();
2826
2827 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2828 SAFE_SNPRINTF();
2829 ret = x509parse_dn_gets( p, n, &crl->issuer );
2830 SAFE_SNPRINTF();
2831
2832 ret = snprintf( p, n, "\n%sthis update : " \
2833 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2834 crl->this_update.year, crl->this_update.mon,
2835 crl->this_update.day, crl->this_update.hour,
2836 crl->this_update.min, crl->this_update.sec );
2837 SAFE_SNPRINTF();
2838
2839 ret = snprintf( p, n, "\n%snext update : " \
2840 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2841 crl->next_update.year, crl->next_update.mon,
2842 crl->next_update.day, crl->next_update.hour,
2843 crl->next_update.min, crl->next_update.sec );
2844 SAFE_SNPRINTF();
2845
2846 entry = &crl->entry;
2847
2848 ret = snprintf( p, n, "\n%sRevoked certificates:",
2849 prefix );
2850 SAFE_SNPRINTF();
2851
Paul Bakker9be19372009-07-27 20:21:53 +00002852 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002853 {
2854 ret = snprintf( p, n, "\n%sserial number: ",
2855 prefix );
2856 SAFE_SNPRINTF();
2857
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002858 ret = x509parse_serial_gets( p, n, &entry->serial);
2859 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002860
Paul Bakkerd98030e2009-05-02 15:13:40 +00002861 ret = snprintf( p, n, " revocation date: " \
2862 "%04d-%02d-%02d %02d:%02d:%02d",
2863 entry->revocation_date.year, entry->revocation_date.mon,
2864 entry->revocation_date.day, entry->revocation_date.hour,
2865 entry->revocation_date.min, entry->revocation_date.sec );
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002866 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002867
2868 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002869 }
2870
Paul Bakkerc70b9822013-04-07 22:00:46 +02002871 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002872 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002873
Paul Bakkerc70b9822013-04-07 22:00:46 +02002874 ret = oid_get_sig_alg_desc( &crl->sig_oid1, &desc );
2875 if( ret != 0 )
2876 ret = snprintf( p, n, "???" );
2877 else
2878 ret = snprintf( p, n, desc );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002879 SAFE_SNPRINTF();
2880
Paul Bakker1e27bb22009-07-19 20:25:25 +00002881 ret = snprintf( p, n, "\n" );
2882 SAFE_SNPRINTF();
2883
Paul Bakker23986e52011-04-24 08:57:21 +00002884 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002885}
2886
2887/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00002888 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00002889 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002890int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00002891{
Paul Bakkercce9d772011-11-18 14:26:47 +00002892 int year, mon, day;
2893 int hour, min, sec;
2894
2895#if defined(_WIN32)
2896 SYSTEMTIME st;
2897
2898 GetLocalTime(&st);
2899
2900 year = st.wYear;
2901 mon = st.wMonth;
2902 day = st.wDay;
2903 hour = st.wHour;
2904 min = st.wMinute;
2905 sec = st.wSecond;
2906#else
Paul Bakker5121ce52009-01-03 21:22:43 +00002907 struct tm *lt;
2908 time_t tt;
2909
2910 tt = time( NULL );
2911 lt = localtime( &tt );
2912
Paul Bakkercce9d772011-11-18 14:26:47 +00002913 year = lt->tm_year + 1900;
2914 mon = lt->tm_mon + 1;
2915 day = lt->tm_mday;
2916 hour = lt->tm_hour;
2917 min = lt->tm_min;
2918 sec = lt->tm_sec;
2919#endif
2920
2921 if( year > to->year )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002922 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002923
Paul Bakkercce9d772011-11-18 14:26:47 +00002924 if( year == to->year &&
2925 mon > to->mon )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002926 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002927
Paul Bakkercce9d772011-11-18 14:26:47 +00002928 if( year == to->year &&
2929 mon == to->mon &&
2930 day > to->day )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002931 return( 1 );
2932
Paul Bakkercce9d772011-11-18 14:26:47 +00002933 if( year == to->year &&
2934 mon == to->mon &&
2935 day == to->day &&
2936 hour > to->hour )
Paul Bakkerb6194992011-01-16 21:40:22 +00002937 return( 1 );
2938
Paul Bakkercce9d772011-11-18 14:26:47 +00002939 if( year == to->year &&
2940 mon == to->mon &&
2941 day == to->day &&
2942 hour == to->hour &&
2943 min > to->min )
Paul Bakkerb6194992011-01-16 21:40:22 +00002944 return( 1 );
2945
Paul Bakkercce9d772011-11-18 14:26:47 +00002946 if( year == to->year &&
2947 mon == to->mon &&
2948 day == to->day &&
2949 hour == to->hour &&
2950 min == to->min &&
2951 sec > to->sec )
Paul Bakkerb6194992011-01-16 21:40:22 +00002952 return( 1 );
2953
Paul Bakker40ea7de2009-05-03 10:18:48 +00002954 return( 0 );
2955}
2956
2957/*
2958 * Return 1 if the certificate is revoked, or 0 otherwise.
2959 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002960int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002961{
Paul Bakkerff60ee62010-03-16 21:09:09 +00002962 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00002963
2964 while( cur != NULL && cur->serial.len != 0 )
2965 {
Paul Bakkera056efc2011-01-16 21:38:35 +00002966 if( crt->serial.len == cur->serial.len &&
2967 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002968 {
2969 if( x509parse_time_expired( &cur->revocation_date ) )
2970 return( 1 );
2971 }
2972
2973 cur = cur->next;
2974 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002975
2976 return( 0 );
2977}
2978
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002979/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00002980 * Check that the given certificate is valid accoring to the CRL.
2981 */
2982static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
2983 x509_crl *crl_list)
2984{
2985 int flags = 0;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002986 unsigned char hash[POLARSSL_MD_MAX_SIZE];
2987 const md_info_t *md_info;
Paul Bakker76fd75a2011-01-16 21:12:10 +00002988
Paul Bakker915275b2012-09-28 07:10:55 +00002989 if( ca == NULL )
2990 return( flags );
2991
Paul Bakker76fd75a2011-01-16 21:12:10 +00002992 /*
2993 * TODO: What happens if no CRL is present?
2994 * Suggestion: Revocation state should be unknown if no CRL is present.
2995 * For backwards compatibility this is not yet implemented.
2996 */
2997
Paul Bakker915275b2012-09-28 07:10:55 +00002998 while( crl_list != NULL )
Paul Bakker76fd75a2011-01-16 21:12:10 +00002999 {
Paul Bakker915275b2012-09-28 07:10:55 +00003000 if( crl_list->version == 0 ||
3001 crl_list->issuer_raw.len != ca->subject_raw.len ||
Paul Bakker76fd75a2011-01-16 21:12:10 +00003002 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
3003 crl_list->issuer_raw.len ) != 0 )
3004 {
3005 crl_list = crl_list->next;
3006 continue;
3007 }
3008
3009 /*
3010 * Check if CRL is correctly signed by the trusted CA
3011 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02003012 md_info = md_info_from_type( crl_list->sig_md );
3013 if( md_info == NULL )
3014 {
3015 /*
3016 * Cannot check 'unknown' hash
3017 */
3018 flags |= BADCRL_NOT_TRUSTED;
3019 break;
3020 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00003021
Paul Bakkerc70b9822013-04-07 22:00:46 +02003022 md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
Paul Bakker76fd75a2011-01-16 21:12:10 +00003023
Paul Bakkerc70b9822013-04-07 22:00:46 +02003024 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, crl_list->sig_md,
Paul Bakker76fd75a2011-01-16 21:12:10 +00003025 0, hash, crl_list->sig.p ) == 0 )
3026 {
3027 /*
3028 * CRL is not trusted
3029 */
3030 flags |= BADCRL_NOT_TRUSTED;
3031 break;
3032 }
3033
3034 /*
3035 * Check for validity of CRL (Do not drop out)
3036 */
3037 if( x509parse_time_expired( &crl_list->next_update ) )
3038 flags |= BADCRL_EXPIRED;
3039
3040 /*
3041 * Check if certificate is revoked
3042 */
3043 if( x509parse_revoked(crt, crl_list) )
3044 {
3045 flags |= BADCERT_REVOKED;
3046 break;
3047 }
3048
3049 crl_list = crl_list->next;
3050 }
3051 return flags;
3052}
3053
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02003054static int x509_wildcard_verify( const char *cn, x509_buf *name )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003055{
3056 size_t i;
3057 size_t cn_idx = 0;
3058
Paul Bakker57b12982012-02-11 17:38:38 +00003059 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003060 return( 0 );
3061
3062 for( i = 0; i < strlen( cn ); ++i )
3063 {
3064 if( cn[i] == '.' )
3065 {
3066 cn_idx = i;
3067 break;
3068 }
3069 }
3070
3071 if( cn_idx == 0 )
3072 return( 0 );
3073
Paul Bakker535e97d2012-08-23 10:49:55 +00003074 if( strlen( cn ) - cn_idx == name->len - 1 &&
3075 memcmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003076 {
3077 return( 1 );
3078 }
3079
3080 return( 0 );
3081}
3082
Paul Bakker915275b2012-09-28 07:10:55 +00003083static int x509parse_verify_top(
3084 x509_cert *child, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003085 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003086 int (*f_vrfy)(void *, x509_cert *, int, int *),
3087 void *p_vrfy )
3088{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003089 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003090 int ca_flags = 0, check_path_cnt = path_cnt + 1;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003091 unsigned char hash[POLARSSL_MD_MAX_SIZE];
3092 const md_info_t *md_info;
Paul Bakker915275b2012-09-28 07:10:55 +00003093
3094 if( x509parse_time_expired( &child->valid_to ) )
3095 *flags |= BADCERT_EXPIRED;
3096
3097 /*
3098 * Child is the top of the chain. Check against the trust_ca list.
3099 */
3100 *flags |= BADCERT_NOT_TRUSTED;
3101
3102 while( trust_ca != NULL )
3103 {
3104 if( trust_ca->version == 0 ||
3105 child->issuer_raw.len != trust_ca->subject_raw.len ||
3106 memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
3107 child->issuer_raw.len ) != 0 )
3108 {
3109 trust_ca = trust_ca->next;
3110 continue;
3111 }
3112
Paul Bakker9a736322012-11-14 12:39:52 +00003113 /*
3114 * Reduce path_len to check against if top of the chain is
3115 * the same as the trusted CA
3116 */
3117 if( child->subject_raw.len == trust_ca->subject_raw.len &&
3118 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3119 child->issuer_raw.len ) == 0 )
3120 {
3121 check_path_cnt--;
3122 }
3123
Paul Bakker915275b2012-09-28 07:10:55 +00003124 if( trust_ca->max_pathlen > 0 &&
Paul Bakker9a736322012-11-14 12:39:52 +00003125 trust_ca->max_pathlen < check_path_cnt )
Paul Bakker915275b2012-09-28 07:10:55 +00003126 {
3127 trust_ca = trust_ca->next;
3128 continue;
3129 }
3130
Paul Bakkerc70b9822013-04-07 22:00:46 +02003131 md_info = md_info_from_type( child->sig_md );
3132 if( md_info == NULL )
3133 {
3134 /*
3135 * Cannot check 'unknown' hash
3136 */
3137 continue;
3138 }
Paul Bakker915275b2012-09-28 07:10:55 +00003139
Paul Bakkerc70b9822013-04-07 22:00:46 +02003140 md( md_info, child->tbs.p, child->tbs.len, hash );
Paul Bakker915275b2012-09-28 07:10:55 +00003141
Paul Bakkerc70b9822013-04-07 22:00:46 +02003142 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, child->sig_md,
Paul Bakker915275b2012-09-28 07:10:55 +00003143 0, hash, child->sig.p ) != 0 )
3144 {
3145 trust_ca = trust_ca->next;
3146 continue;
3147 }
3148
3149 /*
3150 * Top of chain is signed by a trusted CA
3151 */
3152 *flags &= ~BADCERT_NOT_TRUSTED;
3153 break;
3154 }
3155
Paul Bakker9a736322012-11-14 12:39:52 +00003156 /*
Paul Bakker3497d8c2012-11-24 11:53:17 +01003157 * If top of chain is not the same as the trusted CA send a verify request
3158 * to the callback for any issues with validity and CRL presence for the
3159 * trusted CA certificate.
Paul Bakker9a736322012-11-14 12:39:52 +00003160 */
3161 if( trust_ca != NULL &&
3162 ( child->subject_raw.len != trust_ca->subject_raw.len ||
3163 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3164 child->issuer_raw.len ) != 0 ) )
Paul Bakker915275b2012-09-28 07:10:55 +00003165 {
3166 /* Check trusted CA's CRL for then chain's top crt */
3167 *flags |= x509parse_verifycrl( child, trust_ca, ca_crl );
3168
3169 if( x509parse_time_expired( &trust_ca->valid_to ) )
3170 ca_flags |= BADCERT_EXPIRED;
3171
Paul Bakker915275b2012-09-28 07:10:55 +00003172 if( NULL != f_vrfy )
3173 {
Paul Bakker9a736322012-11-14 12:39:52 +00003174 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003175 return( ret );
3176 }
3177 }
3178
3179 /* Call callback on top cert */
3180 if( NULL != f_vrfy )
3181 {
Paul Bakker9a736322012-11-14 12:39:52 +00003182 if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003183 return( ret );
3184 }
3185
Paul Bakker915275b2012-09-28 07:10:55 +00003186 *flags |= ca_flags;
3187
3188 return( 0 );
3189}
3190
3191static int x509parse_verify_child(
3192 x509_cert *child, x509_cert *parent, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003193 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003194 int (*f_vrfy)(void *, x509_cert *, int, int *),
3195 void *p_vrfy )
3196{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003197 int ret;
Paul Bakker915275b2012-09-28 07:10:55 +00003198 int parent_flags = 0;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003199 unsigned char hash[POLARSSL_MD_MAX_SIZE];
Paul Bakker915275b2012-09-28 07:10:55 +00003200 x509_cert *grandparent;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003201 const md_info_t *md_info;
Paul Bakker915275b2012-09-28 07:10:55 +00003202
3203 if( x509parse_time_expired( &child->valid_to ) )
3204 *flags |= BADCERT_EXPIRED;
3205
Paul Bakkerc70b9822013-04-07 22:00:46 +02003206 md_info = md_info_from_type( child->sig_md );
3207 if( md_info == NULL )
3208 {
3209 /*
3210 * Cannot check 'unknown' hash
3211 */
Paul Bakker915275b2012-09-28 07:10:55 +00003212 *flags |= BADCERT_NOT_TRUSTED;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003213 }
3214 else
3215 {
3216 md( md_info, child->tbs.p, child->tbs.len, hash );
3217
3218 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, child->sig_md, 0, hash,
3219 child->sig.p ) != 0 )
3220 *flags |= BADCERT_NOT_TRUSTED;
3221 }
3222
Paul Bakker915275b2012-09-28 07:10:55 +00003223 /* Check trusted CA's CRL for the given crt */
3224 *flags |= x509parse_verifycrl(child, parent, ca_crl);
3225
3226 grandparent = parent->next;
3227
3228 while( grandparent != NULL )
3229 {
3230 if( grandparent->version == 0 ||
3231 grandparent->ca_istrue == 0 ||
3232 parent->issuer_raw.len != grandparent->subject_raw.len ||
3233 memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
3234 parent->issuer_raw.len ) != 0 )
3235 {
3236 grandparent = grandparent->next;
3237 continue;
3238 }
3239 break;
3240 }
3241
Paul Bakker915275b2012-09-28 07:10:55 +00003242 if( grandparent != NULL )
3243 {
3244 /*
3245 * Part of the chain
3246 */
Paul Bakker9a736322012-11-14 12:39:52 +00003247 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 +00003248 if( ret != 0 )
3249 return( ret );
3250 }
3251 else
3252 {
Paul Bakker9a736322012-11-14 12:39:52 +00003253 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 +00003254 if( ret != 0 )
3255 return( ret );
3256 }
3257
3258 /* child is verified to be a child of the parent, call verify callback */
3259 if( NULL != f_vrfy )
Paul Bakker9a736322012-11-14 12:39:52 +00003260 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003261 return( ret );
Paul Bakker915275b2012-09-28 07:10:55 +00003262
3263 *flags |= parent_flags;
3264
3265 return( 0 );
3266}
3267
Paul Bakker76fd75a2011-01-16 21:12:10 +00003268/*
Paul Bakker5121ce52009-01-03 21:22:43 +00003269 * Verify the certificate validity
3270 */
3271int x509parse_verify( x509_cert *crt,
3272 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00003273 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003274 const char *cn, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003275 int (*f_vrfy)(void *, x509_cert *, int, int *),
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003276 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00003277{
Paul Bakker23986e52011-04-24 08:57:21 +00003278 size_t cn_len;
Paul Bakker915275b2012-09-28 07:10:55 +00003279 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003280 int pathlen = 0;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003281 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00003282 x509_name *name;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003283 x509_sequence *cur = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003284
Paul Bakker40ea7de2009-05-03 10:18:48 +00003285 *flags = 0;
3286
Paul Bakker5121ce52009-01-03 21:22:43 +00003287 if( cn != NULL )
3288 {
3289 name = &crt->subject;
3290 cn_len = strlen( cn );
3291
Paul Bakker4d2c1242012-05-10 14:12:46 +00003292 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
Paul Bakker5121ce52009-01-03 21:22:43 +00003293 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00003294 cur = &crt->subject_alt_names;
3295
3296 while( cur != NULL )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003297 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003298 if( cur->buf.len == cn_len &&
3299 memcmp( cn, cur->buf.p, cn_len ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003300 break;
3301
Paul Bakker535e97d2012-08-23 10:49:55 +00003302 if( cur->buf.len > 2 &&
3303 memcmp( cur->buf.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003304 x509_wildcard_verify( cn, &cur->buf ) )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003305 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003306
Paul Bakker4d2c1242012-05-10 14:12:46 +00003307 cur = cur->next;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003308 }
3309
3310 if( cur == NULL )
3311 *flags |= BADCERT_CN_MISMATCH;
3312 }
Paul Bakker4d2c1242012-05-10 14:12:46 +00003313 else
3314 {
3315 while( name != NULL )
3316 {
Paul Bakkerc70b9822013-04-07 22:00:46 +02003317 if( OID_CMP( OID_AT_CN, &name->oid ) )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003318 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003319 if( name->val.len == cn_len &&
3320 memcmp( name->val.p, cn, cn_len ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003321 break;
3322
Paul Bakker535e97d2012-08-23 10:49:55 +00003323 if( name->val.len > 2 &&
3324 memcmp( name->val.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003325 x509_wildcard_verify( cn, &name->val ) )
3326 break;
3327 }
3328
3329 name = name->next;
3330 }
3331
3332 if( name == NULL )
3333 *flags |= BADCERT_CN_MISMATCH;
3334 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003335 }
3336
Paul Bakker5121ce52009-01-03 21:22:43 +00003337 /*
Paul Bakker915275b2012-09-28 07:10:55 +00003338 * Iterate upwards in the given cert chain, to find our crt parent.
3339 * Ignore any upper cert with CA != TRUE.
Paul Bakker5121ce52009-01-03 21:22:43 +00003340 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003341 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003342
Paul Bakker76fd75a2011-01-16 21:12:10 +00003343 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003344 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003345 if( parent->ca_istrue == 0 ||
3346 crt->issuer_raw.len != parent->subject_raw.len ||
3347 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00003348 crt->issuer_raw.len ) != 0 )
3349 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003350 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003351 continue;
3352 }
Paul Bakker915275b2012-09-28 07:10:55 +00003353 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003354 }
3355
Paul Bakker915275b2012-09-28 07:10:55 +00003356 if( parent != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003357 {
Paul Bakker915275b2012-09-28 07:10:55 +00003358 /*
3359 * Part of the chain
3360 */
Paul Bakker9a736322012-11-14 12:39:52 +00003361 ret = x509parse_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003362 if( ret != 0 )
3363 return( ret );
3364 }
3365 else
Paul Bakker74111d32011-01-15 16:57:55 +00003366 {
Paul Bakker9a736322012-11-14 12:39:52 +00003367 ret = x509parse_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003368 if( ret != 0 )
3369 return( ret );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003370 }
Paul Bakker915275b2012-09-28 07:10:55 +00003371
3372 if( *flags != 0 )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003373 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003374
Paul Bakker5121ce52009-01-03 21:22:43 +00003375 return( 0 );
3376}
3377
3378/*
3379 * Unallocate all certificate data
3380 */
3381void x509_free( x509_cert *crt )
3382{
3383 x509_cert *cert_cur = crt;
3384 x509_cert *cert_prv;
3385 x509_name *name_cur;
3386 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00003387 x509_sequence *seq_cur;
3388 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00003389
3390 if( crt == NULL )
3391 return;
3392
3393 do
3394 {
3395 rsa_free( &cert_cur->rsa );
3396
3397 name_cur = cert_cur->issuer.next;
3398 while( name_cur != NULL )
3399 {
3400 name_prv = name_cur;
3401 name_cur = name_cur->next;
3402 memset( name_prv, 0, sizeof( x509_name ) );
3403 free( name_prv );
3404 }
3405
3406 name_cur = cert_cur->subject.next;
3407 while( name_cur != NULL )
3408 {
3409 name_prv = name_cur;
3410 name_cur = name_cur->next;
3411 memset( name_prv, 0, sizeof( x509_name ) );
3412 free( name_prv );
3413 }
3414
Paul Bakker74111d32011-01-15 16:57:55 +00003415 seq_cur = cert_cur->ext_key_usage.next;
3416 while( seq_cur != NULL )
3417 {
3418 seq_prv = seq_cur;
3419 seq_cur = seq_cur->next;
3420 memset( seq_prv, 0, sizeof( x509_sequence ) );
3421 free( seq_prv );
3422 }
3423
Paul Bakker8afa70d2012-02-11 18:42:45 +00003424 seq_cur = cert_cur->subject_alt_names.next;
3425 while( seq_cur != NULL )
3426 {
3427 seq_prv = seq_cur;
3428 seq_cur = seq_cur->next;
3429 memset( seq_prv, 0, sizeof( x509_sequence ) );
3430 free( seq_prv );
3431 }
3432
Paul Bakker5121ce52009-01-03 21:22:43 +00003433 if( cert_cur->raw.p != NULL )
3434 {
3435 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
3436 free( cert_cur->raw.p );
3437 }
3438
3439 cert_cur = cert_cur->next;
3440 }
3441 while( cert_cur != NULL );
3442
3443 cert_cur = crt;
3444 do
3445 {
3446 cert_prv = cert_cur;
3447 cert_cur = cert_cur->next;
3448
3449 memset( cert_prv, 0, sizeof( x509_cert ) );
3450 if( cert_prv != crt )
3451 free( cert_prv );
3452 }
3453 while( cert_cur != NULL );
3454}
3455
Paul Bakkerd98030e2009-05-02 15:13:40 +00003456/*
3457 * Unallocate all CRL data
3458 */
3459void x509_crl_free( x509_crl *crl )
3460{
3461 x509_crl *crl_cur = crl;
3462 x509_crl *crl_prv;
3463 x509_name *name_cur;
3464 x509_name *name_prv;
3465 x509_crl_entry *entry_cur;
3466 x509_crl_entry *entry_prv;
3467
3468 if( crl == NULL )
3469 return;
3470
3471 do
3472 {
3473 name_cur = crl_cur->issuer.next;
3474 while( name_cur != NULL )
3475 {
3476 name_prv = name_cur;
3477 name_cur = name_cur->next;
3478 memset( name_prv, 0, sizeof( x509_name ) );
3479 free( name_prv );
3480 }
3481
3482 entry_cur = crl_cur->entry.next;
3483 while( entry_cur != NULL )
3484 {
3485 entry_prv = entry_cur;
3486 entry_cur = entry_cur->next;
3487 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
3488 free( entry_prv );
3489 }
3490
3491 if( crl_cur->raw.p != NULL )
3492 {
3493 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
3494 free( crl_cur->raw.p );
3495 }
3496
3497 crl_cur = crl_cur->next;
3498 }
3499 while( crl_cur != NULL );
3500
3501 crl_cur = crl;
3502 do
3503 {
3504 crl_prv = crl_cur;
3505 crl_cur = crl_cur->next;
3506
3507 memset( crl_prv, 0, sizeof( x509_crl ) );
3508 if( crl_prv != crl )
3509 free( crl_prv );
3510 }
3511 while( crl_cur != NULL );
3512}
3513
Paul Bakker40e46942009-01-03 21:51:57 +00003514#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00003515
Paul Bakker40e46942009-01-03 21:51:57 +00003516#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00003517
3518/*
3519 * Checkup routine
3520 */
3521int x509_self_test( int verbose )
3522{
Paul Bakker5690efc2011-05-26 13:16:06 +00003523#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00003524 int ret;
3525 int flags;
3526 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00003527 x509_cert cacert;
3528 x509_cert clicert;
3529 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00003530#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003531 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00003532#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003533
3534 if( verbose != 0 )
3535 printf( " X.509 certificate load: " );
3536
3537 memset( &clicert, 0, sizeof( x509_cert ) );
3538
Paul Bakker3c2122f2013-06-24 19:03:14 +02003539 ret = x509parse_crt( &clicert, (const unsigned char *) test_cli_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003540 strlen( test_cli_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003541 if( ret != 0 )
3542 {
3543 if( verbose != 0 )
3544 printf( "failed\n" );
3545
3546 return( ret );
3547 }
3548
3549 memset( &cacert, 0, sizeof( x509_cert ) );
3550
Paul Bakker3c2122f2013-06-24 19:03:14 +02003551 ret = x509parse_crt( &cacert, (const unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003552 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003553 if( ret != 0 )
3554 {
3555 if( verbose != 0 )
3556 printf( "failed\n" );
3557
3558 return( ret );
3559 }
3560
3561 if( verbose != 0 )
3562 printf( "passed\n X.509 private key load: " );
3563
3564 i = strlen( test_ca_key );
3565 j = strlen( test_ca_pwd );
3566
Paul Bakker66b78b22011-03-25 14:22:50 +00003567 rsa_init( &rsa, RSA_PKCS_V15, 0 );
3568
Paul Bakker5121ce52009-01-03 21:22:43 +00003569 if( ( ret = x509parse_key( &rsa,
Paul Bakker3c2122f2013-06-24 19:03:14 +02003570 (const unsigned char *) test_ca_key, i,
3571 (const unsigned char *) test_ca_pwd, j ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003572 {
3573 if( verbose != 0 )
3574 printf( "failed\n" );
3575
3576 return( ret );
3577 }
3578
3579 if( verbose != 0 )
3580 printf( "passed\n X.509 signature verify: ");
3581
Paul Bakker23986e52011-04-24 08:57:21 +00003582 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003583 if( ret != 0 )
3584 {
Paul Bakker23986e52011-04-24 08:57:21 +00003585 printf("%02x", flags);
Paul Bakker5121ce52009-01-03 21:22:43 +00003586 if( verbose != 0 )
3587 printf( "failed\n" );
3588
3589 return( ret );
3590 }
3591
Paul Bakker5690efc2011-05-26 13:16:06 +00003592#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003593 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003594 printf( "passed\n X.509 DHM parameter load: " );
3595
3596 i = strlen( test_dhm_params );
3597 j = strlen( test_ca_pwd );
3598
Paul Bakker3c2122f2013-06-24 19:03:14 +02003599 if( ( ret = x509parse_dhm( &dhm, (const unsigned char *) test_dhm_params, i ) ) != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003600 {
3601 if( verbose != 0 )
3602 printf( "failed\n" );
3603
3604 return( ret );
3605 }
3606
3607 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003608 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00003609#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003610
3611 x509_free( &cacert );
3612 x509_free( &clicert );
3613 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00003614#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003615 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00003616#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003617
3618 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003619#else
3620 ((void) verbose);
3621 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3622#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003623}
3624
3625#endif
3626
3627#endif