blob: 806dceab2440ab4046c7fac1d7a42191ed2f72a5 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * X.509 certificate and private key decoding
3 *
Paul Bakkerefc30292011-11-10 14:43:23 +00004 * Copyright (C) 2006-2011, 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 Bakker96743fc2011-02-12 14:30:57 +000043#include "polarssl/pem.h"
Paul Bakker40e46942009-01-03 21:51:57 +000044#include "polarssl/des.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010045#if defined(POLARSSL_MD2_C)
Paul Bakker40e46942009-01-03 21:51:57 +000046#include "polarssl/md2.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010047#endif
48#if defined(POLARSSL_MD4_C)
Paul Bakker40e46942009-01-03 21:51:57 +000049#include "polarssl/md4.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010050#endif
51#if defined(POLARSSL_MD5_C)
Paul Bakker40e46942009-01-03 21:51:57 +000052#include "polarssl/md5.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010053#endif
54#if defined(POLARSSL_SHA1_C)
Paul Bakker40e46942009-01-03 21:51:57 +000055#include "polarssl/sha1.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010056#endif
57#if defined(POLARSSL_SHA2_C)
Paul Bakker026c03b2009-03-28 17:53:03 +000058#include "polarssl/sha2.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010059#endif
60#if defined(POLARSSL_SHA4_C)
Paul Bakker026c03b2009-03-28 17:53:03 +000061#include "polarssl/sha4.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010062#endif
Paul Bakker1b57b062011-01-06 15:48:19 +000063#include "polarssl/dhm.h"
Paul Bakker1fd43212013-06-17 15:14:42 +020064#if defined(POLARSSL_PKCS5_C)
65#include "polarssl/pkcs5.h"
66#endif
Paul Bakker14a222c2013-06-18 16:35:48 +020067#if defined(POLARSSL_PKCS12_C)
68#include "polarssl/pkcs12.h"
69#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000070
71#include <string.h>
72#include <stdlib.h>
Paul Bakker4f229e52011-12-04 22:11:35 +000073#if defined(_WIN32)
Paul Bakkercce9d772011-11-18 14:26:47 +000074#include <windows.h>
75#else
Paul Bakker5121ce52009-01-03 21:22:43 +000076#include <time.h>
Paul Bakkercce9d772011-11-18 14:26:47 +000077#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000078
Paul Bakker335db3f2011-04-25 15:28:35 +000079#if defined(POLARSSL_FS_IO)
80#include <stdio.h>
Paul Bakker4a2bd0d2012-11-02 11:06:08 +000081#if !defined(_WIN32)
Paul Bakker8d914582012-06-04 12:46:42 +000082#include <sys/types.h>
Paul Bakkercbfcaa92013-06-13 09:20:25 +020083#include <sys/stat.h>
Paul Bakker8d914582012-06-04 12:46:42 +000084#include <dirent.h>
85#endif
Paul Bakker335db3f2011-04-25 15:28:35 +000086#endif
87
Paul Bakkercf6e95d2013-06-12 13:18:15 +020088/* Compare a given OID string with an OID x509_buf * */
89#define OID_CMP(oid_str, oid_buf) \
90 ( ( OID_SIZE(oid_str) == (oid_buf)->len ) && \
91 memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0)
92
Paul Bakker5121ce52009-01-03 21:22:43 +000093/*
Paul Bakker5121ce52009-01-03 21:22:43 +000094 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
95 */
96static int x509_get_version( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +000097 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +000098 int *ver )
99{
Paul Bakker23986e52011-04-24 08:57:21 +0000100 int ret;
101 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000102
103 if( ( ret = asn1_get_tag( p, end, &len,
104 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
105 {
Paul Bakker40e46942009-01-03 21:51:57 +0000106 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +0000107 {
108 *ver = 0;
109 return( 0 );
110 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000111
112 return( ret );
113 }
114
115 end = *p + len;
116
117 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000118 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000119
120 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000121 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION +
Paul Bakker40e46942009-01-03 21:51:57 +0000122 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000123
124 return( 0 );
125}
126
127/*
Paul Bakkerfae618f2011-10-12 11:53:52 +0000128 * Version ::= INTEGER { v1(0), v2(1) }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000129 */
130static int x509_crl_get_version( unsigned char **p,
131 const unsigned char *end,
132 int *ver )
133{
134 int ret;
135
136 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
137 {
138 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +0000139 {
140 *ver = 0;
141 return( 0 );
142 }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000143
144 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
145 }
146
147 return( 0 );
148}
149
150/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000151 * CertificateSerialNumber ::= INTEGER
152 */
153static int x509_get_serial( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000154 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000155 x509_buf *serial )
156{
157 int ret;
158
159 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000160 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000161 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000162
163 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
164 **p != ASN1_INTEGER )
Paul Bakker9d781402011-05-09 16:17:09 +0000165 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000166 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000167
168 serial->tag = *(*p)++;
169
170 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000171 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000172
173 serial->p = *p;
174 *p += serial->len;
175
176 return( 0 );
177}
178
179/*
180 * AlgorithmIdentifier ::= SEQUENCE {
181 * algorithm OBJECT IDENTIFIER,
182 * parameters ANY DEFINED BY algorithm OPTIONAL }
183 */
184static int x509_get_alg( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000185 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000186 x509_buf *alg )
187{
Paul Bakker23986e52011-04-24 08:57:21 +0000188 int ret;
189 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000190
191 if( ( ret = asn1_get_tag( p, end, &len,
192 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000193 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000194
195 end = *p + len;
196 alg->tag = **p;
197
198 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000199 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000200
201 alg->p = *p;
202 *p += alg->len;
203
204 if( *p == end )
205 return( 0 );
206
207 /*
208 * assume the algorithm parameters must be NULL
209 */
210 if( ( ret = asn1_get_tag( p, end, &len, ASN1_NULL ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000211 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000212
213 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000214 return( POLARSSL_ERR_X509_CERT_INVALID_ALG +
Paul Bakker40e46942009-01-03 21:51:57 +0000215 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000216
217 return( 0 );
218}
219
220/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000221 * AttributeTypeAndValue ::= SEQUENCE {
222 * type AttributeType,
223 * value AttributeValue }
224 *
225 * AttributeType ::= OBJECT IDENTIFIER
226 *
227 * AttributeValue ::= ANY DEFINED BY AttributeType
228 */
Paul Bakker400ff6f2011-02-20 10:40:16 +0000229static int x509_get_attr_type_value( unsigned char **p,
230 const unsigned char *end,
231 x509_name *cur )
Paul Bakker5121ce52009-01-03 21:22:43 +0000232{
Paul Bakker23986e52011-04-24 08:57:21 +0000233 int ret;
234 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000235 x509_buf *oid;
236 x509_buf *val;
237
238 if( ( ret = asn1_get_tag( p, end, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000239 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000240 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000241
Paul Bakker5121ce52009-01-03 21:22:43 +0000242 oid = &cur->oid;
243 oid->tag = **p;
244
245 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000246 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000247
248 oid->p = *p;
249 *p += oid->len;
250
251 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000252 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000253 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000254
255 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
256 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
257 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker9d781402011-05-09 16:17:09 +0000258 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000259 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000260
261 val = &cur->val;
262 val->tag = *(*p)++;
263
264 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000265 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000266
267 val->p = *p;
268 *p += val->len;
269
270 cur->next = NULL;
271
Paul Bakker400ff6f2011-02-20 10:40:16 +0000272 return( 0 );
273}
274
275/*
276 * RelativeDistinguishedName ::=
277 * SET OF AttributeTypeAndValue
278 *
279 * AttributeTypeAndValue ::= SEQUENCE {
280 * type AttributeType,
281 * value AttributeValue }
282 *
283 * AttributeType ::= OBJECT IDENTIFIER
284 *
285 * AttributeValue ::= ANY DEFINED BY AttributeType
Manuel Pégourié-Gonnard6b440382014-10-23 14:53:46 +0200286 *
287 * We restrict RelativeDistinguishedName to be a set of 1 element. This is
288 * the most common case, and our x509_name structure currently can't handle
289 * more than that.
Paul Bakker400ff6f2011-02-20 10:40:16 +0000290 */
291static int x509_get_name( unsigned char **p,
292 const unsigned char *end,
293 x509_name *cur )
294{
Paul Bakker23986e52011-04-24 08:57:21 +0000295 int ret;
Manuel Pégourié-Gonnard6b440382014-10-23 14:53:46 +0200296 size_t set_len;
297 const unsigned char *end_set;
298
299 /*
300 * parse first SET, restricted to 1 element
301 */
302 if( ( ret = asn1_get_tag( p, end, &set_len,
Paul Bakker400ff6f2011-02-20 10:40:16 +0000303 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000304 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000305
Manuel Pégourié-Gonnard6b440382014-10-23 14:53:46 +0200306 end_set = *p + set_len;
Paul Bakker400ff6f2011-02-20 10:40:16 +0000307
Manuel Pégourié-Gonnard6b440382014-10-23 14:53:46 +0200308 if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 )
309 return( ret );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000310
Manuel Pégourié-Gonnard6b440382014-10-23 14:53:46 +0200311 if( *p != end_set )
312 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000313
314 /*
315 * recurse until end of SEQUENCE is reached
316 */
Manuel Pégourié-Gonnard6b440382014-10-23 14:53:46 +0200317 if( *p == end )
Paul Bakker5121ce52009-01-03 21:22:43 +0000318 return( 0 );
319
320 cur->next = (x509_name *) malloc(
321 sizeof( x509_name ) );
322
323 if( cur->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000324 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000325
Paul Bakker430ffbe2012-05-01 08:14:20 +0000326 memset( cur->next, 0, sizeof( x509_name ) );
327
Manuel Pégourié-Gonnard6b440382014-10-23 14:53:46 +0200328 return( x509_get_name( p, end, cur->next ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000329}
330
331/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000332 * Time ::= CHOICE {
333 * utcTime UTCTime,
334 * generalTime GeneralizedTime }
335 */
Paul Bakker91200182010-02-18 21:26:15 +0000336static int x509_get_time( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000337 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000338 x509_time *time )
339{
Paul Bakker23986e52011-04-24 08:57:21 +0000340 int ret;
341 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000342 char date[64];
Paul Bakker91200182010-02-18 21:26:15 +0000343 unsigned char tag;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000344
Paul Bakker91200182010-02-18 21:26:15 +0000345 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000346 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
347 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000348
Paul Bakker91200182010-02-18 21:26:15 +0000349 tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000350
Paul Bakker91200182010-02-18 21:26:15 +0000351 if ( tag == ASN1_UTC_TIME )
352 {
353 (*p)++;
354 ret = asn1_get_len( p, end, &len );
355
356 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000357 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000358
Paul Bakker91200182010-02-18 21:26:15 +0000359 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000360 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
361 len : sizeof( date ) - 1 );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000362
Paul Bakker243d6182014-07-08 14:40:58 +0200363 if( sscanf( date, "%2d%2d%2d%2d%2d%2dZ",
Paul Bakker91200182010-02-18 21:26:15 +0000364 &time->year, &time->mon, &time->day,
365 &time->hour, &time->min, &time->sec ) < 5 )
366 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000367
Paul Bakker400ff6f2011-02-20 10:40:16 +0000368 time->year += 100 * ( time->year < 50 );
Paul Bakker91200182010-02-18 21:26:15 +0000369 time->year += 1900;
370
371 *p += len;
372
373 return( 0 );
374 }
375 else if ( tag == ASN1_GENERALIZED_TIME )
376 {
377 (*p)++;
378 ret = asn1_get_len( p, end, &len );
379
380 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000381 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker91200182010-02-18 21:26:15 +0000382
383 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000384 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
385 len : sizeof( date ) - 1 );
Paul Bakker91200182010-02-18 21:26:15 +0000386
Paul Bakker243d6182014-07-08 14:40:58 +0200387 if( sscanf( date, "%4d%2d%2d%2d%2d%2dZ",
Paul Bakker91200182010-02-18 21:26:15 +0000388 &time->year, &time->mon, &time->day,
389 &time->hour, &time->min, &time->sec ) < 5 )
390 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
391
392 *p += len;
393
394 return( 0 );
395 }
396 else
Paul Bakker9d781402011-05-09 16:17:09 +0000397 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000398}
399
400
401/*
402 * Validity ::= SEQUENCE {
403 * notBefore Time,
404 * notAfter Time }
405 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000406static int x509_get_dates( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000407 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000408 x509_time *from,
409 x509_time *to )
410{
Paul Bakker23986e52011-04-24 08:57:21 +0000411 int ret;
412 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000413
414 if( ( ret = asn1_get_tag( p, end, &len,
415 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000416 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000417
418 end = *p + len;
419
Paul Bakker91200182010-02-18 21:26:15 +0000420 if( ( ret = x509_get_time( p, end, from ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000421 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000422
Paul Bakker91200182010-02-18 21:26:15 +0000423 if( ( ret = x509_get_time( p, end, to ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000424 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000425
426 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000427 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker40e46942009-01-03 21:51:57 +0000428 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000429
430 return( 0 );
431}
432
433/*
434 * SubjectPublicKeyInfo ::= SEQUENCE {
435 * algorithm AlgorithmIdentifier,
436 * subjectPublicKey BIT STRING }
437 */
438static int x509_get_pubkey( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000439 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000440 x509_buf *pk_alg_oid,
441 mpi *N, mpi *E )
442{
Paul Bakker65a19092013-06-06 21:14:58 +0200443 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000444 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000445 unsigned char *end2;
446
447 if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 )
448 return( ret );
449
450 /*
451 * only RSA public keys handled at this time
452 */
Paul Bakker65a19092013-06-06 21:14:58 +0200453 if( pk_alg_oid->len != 9 ||
454 memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) != 0 )
Paul Bakker400ff6f2011-02-20 10:40:16 +0000455 {
Paul Bakkered56b222011-07-13 11:26:43 +0000456 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
Paul Bakker65a19092013-06-06 21:14:58 +0200457 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000458
459 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000460 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000461
462 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000463 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000464 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000465
466 end2 = *p + len;
467
468 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000469 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000470
471 /*
472 * RSAPublicKey ::= SEQUENCE {
473 * modulus INTEGER, -- n
474 * publicExponent INTEGER -- e
475 * }
476 */
477 if( ( ret = asn1_get_tag( p, end2, &len,
478 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000479 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000480
481 if( *p + len != end2 )
Paul Bakker9d781402011-05-09 16:17:09 +0000482 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000483 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000484
485 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
486 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000487 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000488
489 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000490 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000491 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000492
493 return( 0 );
494}
495
496static int x509_get_sig( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000497 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000498 x509_buf *sig )
499{
Paul Bakker23986e52011-04-24 08:57:21 +0000500 int ret;
501 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000502
Paul Bakker8afa70d2012-02-11 18:42:45 +0000503 if( ( end - *p ) < 1 )
504 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE +
505 POLARSSL_ERR_ASN1_OUT_OF_DATA );
506
Paul Bakker5121ce52009-01-03 21:22:43 +0000507 sig->tag = **p;
508
509 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000510 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000511
Paul Bakker74111d32011-01-15 16:57:55 +0000512
Paul Bakker5121ce52009-01-03 21:22:43 +0000513 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000514 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000515
516 sig->len = len;
517 sig->p = *p;
518
519 *p += len;
520
521 return( 0 );
522}
523
524/*
525 * X.509 v2/v3 unique identifier (not parsed)
526 */
527static int x509_get_uid( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000528 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000529 x509_buf *uid, int n )
530{
531 int ret;
532
533 if( *p == end )
534 return( 0 );
535
536 uid->tag = **p;
537
538 if( ( ret = asn1_get_tag( p, end, &uid->len,
539 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
540 {
Paul Bakker40e46942009-01-03 21:51:57 +0000541 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000542 return( 0 );
543
544 return( ret );
545 }
546
547 uid->p = *p;
548 *p += uid->len;
549
550 return( 0 );
551}
552
553/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000554 * X.509 Extensions (No parsing of extensions, pointer should
555 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000556 */
557static int x509_get_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000558 const unsigned char *end,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000559 x509_buf *ext, int tag )
Paul Bakker5121ce52009-01-03 21:22:43 +0000560{
Paul Bakker23986e52011-04-24 08:57:21 +0000561 int ret;
562 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000563
564 if( *p == end )
565 return( 0 );
566
567 ext->tag = **p;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000568
Paul Bakker5121ce52009-01-03 21:22:43 +0000569 if( ( ret = asn1_get_tag( p, end, &ext->len,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000570 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000571 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000572
573 ext->p = *p;
574 end = *p + ext->len;
575
576 /*
577 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
578 *
579 * Extension ::= SEQUENCE {
580 * extnID OBJECT IDENTIFIER,
581 * critical BOOLEAN DEFAULT FALSE,
582 * extnValue OCTET STRING }
583 */
584 if( ( ret = asn1_get_tag( p, end, &len,
585 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000586 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000587
588 if( end != *p + len )
Paul Bakker9d781402011-05-09 16:17:09 +0000589 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +0000590 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000591
Paul Bakkerd98030e2009-05-02 15:13:40 +0000592 return( 0 );
593}
594
595/*
596 * X.509 CRL v2 extensions (no extensions parsed yet.)
597 */
598static int x509_get_crl_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000599 const unsigned char *end,
600 x509_buf *ext )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000601{
Paul Bakker23986e52011-04-24 08:57:21 +0000602 int ret;
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000603 size_t len = 0;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000604
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000605 /* Get explicit tag */
606 if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000607 {
608 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
609 return( 0 );
610
611 return( ret );
612 }
613
614 while( *p < end )
615 {
616 if( ( ret = asn1_get_tag( p, end, &len,
617 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000618 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000619
620 *p += len;
621 }
622
623 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000624 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerd98030e2009-05-02 15:13:40 +0000625 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
626
627 return( 0 );
628}
629
Paul Bakkerb5a11ab2011-10-12 09:58:41 +0000630/*
631 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
632 */
633static int x509_get_crl_entry_ext( unsigned char **p,
634 const unsigned char *end,
635 x509_buf *ext )
636{
637 int ret;
638 size_t len = 0;
639
640 /* OPTIONAL */
641 if (end <= *p)
642 return( 0 );
643
644 ext->tag = **p;
645 ext->p = *p;
646
647 /*
648 * Get CRL-entry extension sequence header
649 * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
650 */
651 if( ( ret = asn1_get_tag( p, end, &ext->len,
652 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
653 {
654 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
655 {
656 ext->p = NULL;
657 return( 0 );
658 }
659 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
660 }
661
662 end = *p + ext->len;
663
664 if( end != *p + ext->len )
665 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
666 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
667
668 while( *p < end )
669 {
670 if( ( ret = asn1_get_tag( p, end, &len,
671 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
672 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
673
674 *p += len;
675 }
676
677 if( *p != end )
678 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
679 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
680
681 return( 0 );
682}
683
Paul Bakker74111d32011-01-15 16:57:55 +0000684static int x509_get_basic_constraints( unsigned char **p,
685 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000686 int *ca_istrue,
687 int *max_pathlen )
688{
Paul Bakker23986e52011-04-24 08:57:21 +0000689 int ret;
690 size_t len;
Paul Bakker74111d32011-01-15 16:57:55 +0000691
692 /*
693 * BasicConstraints ::= SEQUENCE {
694 * cA BOOLEAN DEFAULT FALSE,
695 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
696 */
Paul Bakker3cccddb2011-01-16 21:46:31 +0000697 *ca_istrue = 0; /* DEFAULT FALSE */
Paul Bakker74111d32011-01-15 16:57:55 +0000698 *max_pathlen = 0; /* endless */
699
700 if( ( ret = asn1_get_tag( p, end, &len,
701 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000702 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000703
704 if( *p == end )
705 return 0;
706
Paul Bakker3cccddb2011-01-16 21:46:31 +0000707 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000708 {
709 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker3cccddb2011-01-16 21:46:31 +0000710 ret = asn1_get_int( p, end, ca_istrue );
Paul Bakker74111d32011-01-15 16:57:55 +0000711
712 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000713 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000714
Paul Bakker3cccddb2011-01-16 21:46:31 +0000715 if( *ca_istrue != 0 )
716 *ca_istrue = 1;
Paul Bakker74111d32011-01-15 16:57:55 +0000717 }
718
719 if( *p == end )
720 return 0;
721
722 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000723 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000724
725 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000726 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000727 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
728
729 (*max_pathlen)++;
730
Paul Bakker74111d32011-01-15 16:57:55 +0000731 return 0;
732}
733
734static int x509_get_ns_cert_type( unsigned char **p,
735 const unsigned char *end,
736 unsigned char *ns_cert_type)
737{
738 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000739 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000740
741 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000742 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000743
744 if( bs.len != 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000745 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000746 POLARSSL_ERR_ASN1_INVALID_LENGTH );
747
748 /* Get actual bitstring */
749 *ns_cert_type = *bs.p;
750 return 0;
751}
752
753static int x509_get_key_usage( unsigned char **p,
754 const unsigned char *end,
755 unsigned char *key_usage)
756{
757 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000758 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000759
760 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000761 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000762
Paul Bakker94a67962012-08-23 13:03:52 +0000763 if( bs.len < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000764 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000765 POLARSSL_ERR_ASN1_INVALID_LENGTH );
766
767 /* Get actual bitstring */
768 *key_usage = *bs.p;
769 return 0;
770}
771
Paul Bakkerd98030e2009-05-02 15:13:40 +0000772/*
Paul Bakker74111d32011-01-15 16:57:55 +0000773 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
774 *
775 * KeyPurposeId ::= OBJECT IDENTIFIER
776 */
777static int x509_get_ext_key_usage( unsigned char **p,
778 const unsigned char *end,
779 x509_sequence *ext_key_usage)
780{
781 int ret;
782
783 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000784 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000785
786 /* Sequence length must be >= 1 */
787 if( ext_key_usage->buf.p == NULL )
Paul Bakker9d781402011-05-09 16:17:09 +0000788 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000789 POLARSSL_ERR_ASN1_INVALID_LENGTH );
790
791 return 0;
792}
793
794/*
Paul Bakkera8cd2392012-02-11 16:09:32 +0000795 * SubjectAltName ::= GeneralNames
796 *
797 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
798 *
799 * GeneralName ::= CHOICE {
800 * otherName [0] OtherName,
801 * rfc822Name [1] IA5String,
802 * dNSName [2] IA5String,
803 * x400Address [3] ORAddress,
804 * directoryName [4] Name,
805 * ediPartyName [5] EDIPartyName,
806 * uniformResourceIdentifier [6] IA5String,
807 * iPAddress [7] OCTET STRING,
808 * registeredID [8] OBJECT IDENTIFIER }
809 *
810 * OtherName ::= SEQUENCE {
811 * type-id OBJECT IDENTIFIER,
812 * value [0] EXPLICIT ANY DEFINED BY type-id }
813 *
814 * EDIPartyName ::= SEQUENCE {
815 * nameAssigner [0] DirectoryString OPTIONAL,
816 * partyName [1] DirectoryString }
817 *
818 * NOTE: PolarSSL only parses and uses dNSName at this point.
819 */
820static int x509_get_subject_alt_name( unsigned char **p,
821 const unsigned char *end,
822 x509_sequence *subject_alt_name )
823{
824 int ret;
825 size_t len, tag_len;
826 asn1_buf *buf;
827 unsigned char tag;
828 asn1_sequence *cur = subject_alt_name;
829
830 /* Get main sequence tag */
831 if( ( ret = asn1_get_tag( p, end, &len,
832 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
833 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
834
835 if( *p + len != end )
836 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
837 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
838
839 while( *p < end )
840 {
841 if( ( end - *p ) < 1 )
842 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
843 POLARSSL_ERR_ASN1_OUT_OF_DATA );
844
845 tag = **p;
846 (*p)++;
847 if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 )
848 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
849
850 if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC )
851 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
852 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
853
854 if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) )
855 {
856 *p += tag_len;
857 continue;
858 }
859
860 buf = &(cur->buf);
861 buf->tag = tag;
862 buf->p = *p;
863 buf->len = tag_len;
864 *p += buf->len;
865
866 /* Allocate and assign next pointer */
867 if (*p < end)
868 {
869 cur->next = (asn1_sequence *) malloc(
870 sizeof( asn1_sequence ) );
871
872 if( cur->next == NULL )
873 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
874 POLARSSL_ERR_ASN1_MALLOC_FAILED );
875
Paul Bakker535e97d2012-08-23 10:49:55 +0000876 memset( cur->next, 0, sizeof( asn1_sequence ) );
Paul Bakkera8cd2392012-02-11 16:09:32 +0000877 cur = cur->next;
878 }
879 }
880
881 /* Set final sequence entry's next pointer to NULL */
882 cur->next = NULL;
883
884 if( *p != end )
885 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
886 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
887
888 return( 0 );
889}
890
891/*
Paul Bakker74111d32011-01-15 16:57:55 +0000892 * X.509 v3 extensions
893 *
894 * TODO: Perform all of the basic constraints tests required by the RFC
895 * TODO: Set values for undetected extensions to a sane default?
896 *
Paul Bakkerd98030e2009-05-02 15:13:40 +0000897 */
898static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000899 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000900 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000901{
Paul Bakker23986e52011-04-24 08:57:21 +0000902 int ret;
903 size_t len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000904 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000905
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000906 if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000907 {
908 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
909 return( 0 );
910
911 return( ret );
912 }
913
Paul Bakker5121ce52009-01-03 21:22:43 +0000914 while( *p < end )
915 {
Paul Bakker74111d32011-01-15 16:57:55 +0000916 /*
917 * Extension ::= SEQUENCE {
918 * extnID OBJECT IDENTIFIER,
919 * critical BOOLEAN DEFAULT FALSE,
920 * extnValue OCTET STRING }
921 */
922 x509_buf extn_oid = {0, 0, NULL};
923 int is_critical = 0; /* DEFAULT FALSE */
924
Paul Bakker5121ce52009-01-03 21:22:43 +0000925 if( ( ret = asn1_get_tag( p, end, &len,
926 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000927 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000928
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000929 end_ext_data = *p + len;
930
Paul Bakker74111d32011-01-15 16:57:55 +0000931 /* Get extension ID */
932 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000933
Paul Bakker74111d32011-01-15 16:57:55 +0000934 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000935 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000936
Paul Bakker74111d32011-01-15 16:57:55 +0000937 extn_oid.p = *p;
938 *p += extn_oid.len;
939
940 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000941 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000942 POLARSSL_ERR_ASN1_OUT_OF_DATA );
943
944 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000945 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000946 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
Paul Bakker9d781402011-05-09 16:17:09 +0000947 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000948
Paul Bakker74111d32011-01-15 16:57:55 +0000949 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000950 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000951 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000952 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000953
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000954 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000955
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000956 if( end_ext_octet != end_ext_data )
Paul Bakker9d781402011-05-09 16:17:09 +0000957 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000958 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000959
Paul Bakker74111d32011-01-15 16:57:55 +0000960 /*
961 * Detect supported extensions
962 */
963 if( ( OID_SIZE( OID_BASIC_CONSTRAINTS ) == extn_oid.len ) &&
964 memcmp( extn_oid.p, OID_BASIC_CONSTRAINTS, extn_oid.len ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000965 {
Paul Bakker74111d32011-01-15 16:57:55 +0000966 /* Parse basic constraints */
967 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
Paul Bakker3cccddb2011-01-16 21:46:31 +0000968 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000969 return ( ret );
970 crt->ext_types |= EXT_BASIC_CONSTRAINTS;
Paul Bakker5121ce52009-01-03 21:22:43 +0000971 }
Paul Bakker74111d32011-01-15 16:57:55 +0000972 else if( ( OID_SIZE( OID_NS_CERT_TYPE ) == extn_oid.len ) &&
973 memcmp( extn_oid.p, OID_NS_CERT_TYPE, extn_oid.len ) == 0 )
974 {
975 /* Parse netscape certificate type */
976 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
977 &crt->ns_cert_type ) ) != 0 )
978 return ( ret );
979 crt->ext_types |= EXT_NS_CERT_TYPE;
980 }
981 else if( ( OID_SIZE( OID_KEY_USAGE ) == extn_oid.len ) &&
982 memcmp( extn_oid.p, OID_KEY_USAGE, extn_oid.len ) == 0 )
983 {
984 /* Parse key usage */
985 if( ( ret = x509_get_key_usage( p, end_ext_octet,
986 &crt->key_usage ) ) != 0 )
987 return ( ret );
988 crt->ext_types |= EXT_KEY_USAGE;
989 }
990 else if( ( OID_SIZE( OID_EXTENDED_KEY_USAGE ) == extn_oid.len ) &&
991 memcmp( extn_oid.p, OID_EXTENDED_KEY_USAGE, extn_oid.len ) == 0 )
992 {
993 /* Parse extended key usage */
994 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
995 &crt->ext_key_usage ) ) != 0 )
996 return ( ret );
997 crt->ext_types |= EXT_EXTENDED_KEY_USAGE;
998 }
Paul Bakkera8cd2392012-02-11 16:09:32 +0000999 else if( ( OID_SIZE( OID_SUBJECT_ALT_NAME ) == extn_oid.len ) &&
1000 memcmp( extn_oid.p, OID_SUBJECT_ALT_NAME, extn_oid.len ) == 0 )
1001 {
1002 /* Parse extended key usage */
1003 if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
1004 &crt->subject_alt_names ) ) != 0 )
1005 return ( ret );
1006 crt->ext_types |= EXT_SUBJECT_ALT_NAME;
1007 }
Paul Bakker74111d32011-01-15 16:57:55 +00001008 else
1009 {
1010 /* No parser found, skip extension */
1011 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +00001012
Paul Bakker5c721f92011-07-27 16:51:09 +00001013#if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
Paul Bakker74111d32011-01-15 16:57:55 +00001014 if( is_critical )
1015 {
1016 /* Data is marked as critical: fail */
Paul Bakker9d781402011-05-09 16:17:09 +00001017 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +00001018 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
1019 }
Paul Bakker5c721f92011-07-27 16:51:09 +00001020#endif
Paul Bakker74111d32011-01-15 16:57:55 +00001021 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001022 }
1023
1024 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +00001025 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +00001026 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001027
Paul Bakker5121ce52009-01-03 21:22:43 +00001028 return( 0 );
1029}
1030
1031/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001032 * X.509 CRL Entries
1033 */
1034static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001035 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001036 x509_crl_entry *entry )
1037{
Paul Bakker23986e52011-04-24 08:57:21 +00001038 int ret;
1039 size_t entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001040 x509_crl_entry *cur_entry = entry;
1041
1042 if( *p == end )
1043 return( 0 );
1044
Paul Bakker9be19372009-07-27 20:21:53 +00001045 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001046 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1047 {
1048 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
1049 return( 0 );
1050
1051 return( ret );
1052 }
1053
Paul Bakker9be19372009-07-27 20:21:53 +00001054 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001055
1056 while( *p < end )
1057 {
Paul Bakker23986e52011-04-24 08:57:21 +00001058 size_t len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001059 const unsigned char *end2;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001060
1061 if( ( ret = asn1_get_tag( p, end, &len2,
1062 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1063 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001064 return( ret );
1065 }
1066
Paul Bakker9be19372009-07-27 20:21:53 +00001067 cur_entry->raw.tag = **p;
1068 cur_entry->raw.p = *p;
1069 cur_entry->raw.len = len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001070 end2 = *p + len2;
Paul Bakker9be19372009-07-27 20:21:53 +00001071
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001072 if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001073 return( ret );
1074
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001075 if( ( ret = x509_get_time( p, end2, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001076 return( ret );
1077
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001078 if( ( ret = x509_get_crl_entry_ext( p, end2, &cur_entry->entry_ext ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001079 return( ret );
1080
Paul Bakker74111d32011-01-15 16:57:55 +00001081 if ( *p < end )
1082 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001083 cur_entry->next = malloc( sizeof( x509_crl_entry ) );
Paul Bakkerb15b8512012-01-13 13:44:06 +00001084
1085 if( cur_entry->next == NULL )
1086 return( POLARSSL_ERR_X509_MALLOC_FAILED );
1087
Paul Bakkerd98030e2009-05-02 15:13:40 +00001088 cur_entry = cur_entry->next;
1089 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
1090 }
1091 }
1092
1093 return( 0 );
1094}
1095
Paul Bakker27d66162010-03-17 06:56:01 +00001096static int x509_get_sig_alg( const x509_buf *sig_oid, int *sig_alg )
1097{
1098 if( sig_oid->len == 9 &&
1099 memcmp( sig_oid->p, OID_PKCS1, 8 ) == 0 )
1100 {
1101 if( sig_oid->p[8] >= 2 && sig_oid->p[8] <= 5 )
1102 {
1103 *sig_alg = sig_oid->p[8];
1104 return( 0 );
1105 }
1106
1107 if ( sig_oid->p[8] >= 11 && sig_oid->p[8] <= 14 )
1108 {
1109 *sig_alg = sig_oid->p[8];
1110 return( 0 );
1111 }
1112
1113 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1114 }
Paul Bakker400ff6f2011-02-20 10:40:16 +00001115 if( sig_oid->len == 5 &&
1116 memcmp( sig_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
1117 {
1118 *sig_alg = SIG_RSA_SHA1;
1119 return( 0 );
1120 }
Paul Bakker27d66162010-03-17 06:56:01 +00001121
1122 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1123}
1124
Paul Bakkerd98030e2009-05-02 15:13:40 +00001125/*
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001126 * Parse and fill a single X.509 certificate in DER format
Paul Bakker5121ce52009-01-03 21:22:43 +00001127 */
Paul Bakker1d073c52014-07-08 20:15:51 +02001128static int x509parse_crt_der_core( x509_cert *crt, const unsigned char *buf,
1129 size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001130{
Paul Bakker23986e52011-04-24 08:57:21 +00001131 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001132 size_t len;
Paul Bakkerb00ca422012-09-25 12:10:00 +00001133 unsigned char *p, *end, *crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001134
Paul Bakker320a4b52009-03-28 18:52:39 +00001135 /*
1136 * Check for valid input
1137 */
1138 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001139 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker320a4b52009-03-28 18:52:39 +00001140
Paul Bakker96743fc2011-02-12 14:30:57 +00001141 p = (unsigned char *) malloc( len = buflen );
1142
1143 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001144 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001145
1146 memcpy( p, buf, buflen );
1147
Paul Bakker5121ce52009-01-03 21:22:43 +00001148 crt->raw.p = p;
1149 crt->raw.len = len;
1150 end = p + len;
1151
1152 /*
1153 * Certificate ::= SEQUENCE {
1154 * tbsCertificate TBSCertificate,
1155 * signatureAlgorithm AlgorithmIdentifier,
1156 * signatureValue BIT STRING }
1157 */
1158 if( ( ret = asn1_get_tag( &p, end, &len,
1159 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1160 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001161 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001162 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001163 }
1164
Paul Bakkerb00ca422012-09-25 12:10:00 +00001165 if( len > (size_t) ( end - p ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001166 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001167 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001168 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001169 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001170 }
Paul Bakkerb00ca422012-09-25 12:10:00 +00001171 crt_end = p + len;
Paul Bakkerd6d41092013-06-13 09:00:25 +02001172
Paul Bakker5121ce52009-01-03 21:22:43 +00001173 /*
1174 * TBSCertificate ::= SEQUENCE {
1175 */
1176 crt->tbs.p = p;
1177
1178 if( ( ret = asn1_get_tag( &p, end, &len,
1179 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1180 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001181 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001182 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001183 }
1184
1185 end = p + len;
1186 crt->tbs.len = end - crt->tbs.p;
1187
1188 /*
1189 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1190 *
1191 * CertificateSerialNumber ::= INTEGER
1192 *
1193 * signature AlgorithmIdentifier
1194 */
1195 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1196 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1197 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
1198 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001199 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001200 return( ret );
1201 }
1202
1203 crt->version++;
1204
1205 if( crt->version > 3 )
1206 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001207 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001208 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001209 }
1210
Paul Bakker27d66162010-03-17 06:56:01 +00001211 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_alg ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001212 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001213 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001214 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001215 }
1216
1217 /*
1218 * issuer Name
1219 */
1220 crt->issuer_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
1229 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1230 {
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->issuer_raw.len = p - crt->issuer_raw.p;
1236
1237 /*
1238 * Validity ::= SEQUENCE {
1239 * notBefore Time,
1240 * notAfter Time }
1241 *
1242 */
1243 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1244 &crt->valid_to ) ) != 0 )
1245 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001246 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001247 return( ret );
1248 }
1249
1250 /*
1251 * subject Name
1252 */
1253 crt->subject_raw.p = p;
1254
1255 if( ( ret = asn1_get_tag( &p, end, &len,
1256 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1257 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001258 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001259 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001260 }
1261
Paul Bakkercefb3962012-06-27 11:51:09 +00001262 if( len && ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001263 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001264 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001265 return( ret );
1266 }
1267
1268 crt->subject_raw.len = p - crt->subject_raw.p;
1269
1270 /*
1271 * SubjectPublicKeyInfo ::= SEQUENCE
1272 * algorithm AlgorithmIdentifier,
1273 * subjectPublicKey BIT STRING }
1274 */
1275 if( ( ret = asn1_get_tag( &p, end, &len,
1276 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1277 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001278 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001279 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001280 }
1281
1282 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1283 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1284 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001285 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001286 return( ret );
1287 }
1288
1289 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1290 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001291 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001292 return( ret );
1293 }
1294
1295 crt->rsa.len = mpi_size( &crt->rsa.N );
1296
1297 /*
1298 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1299 * -- If present, version shall be v2 or v3
1300 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1301 * -- If present, version shall be v2 or v3
1302 * extensions [3] EXPLICIT Extensions OPTIONAL
1303 * -- If present, version shall be v3
1304 */
1305 if( crt->version == 2 || crt->version == 3 )
1306 {
1307 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1308 if( ret != 0 )
1309 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001310 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001311 return( ret );
1312 }
1313 }
1314
1315 if( crt->version == 2 || crt->version == 3 )
1316 {
1317 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1318 if( ret != 0 )
1319 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001320 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001321 return( ret );
1322 }
1323 }
1324
1325 if( crt->version == 3 )
1326 {
Paul Bakker74111d32011-01-15 16:57:55 +00001327 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001328 if( ret != 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
1335 if( p != end )
1336 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001337 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001338 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001339 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001340 }
1341
Paul Bakkerb00ca422012-09-25 12:10:00 +00001342 end = crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001343
1344 /*
1345 * signatureAlgorithm AlgorithmIdentifier,
1346 * signatureValue BIT STRING
1347 */
1348 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1349 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001350 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001351 return( ret );
1352 }
1353
Paul Bakker535e97d2012-08-23 10:49:55 +00001354 if( crt->sig_oid1.len != crt->sig_oid2.len ||
1355 memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001356 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001357 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001358 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001359 }
1360
1361 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1362 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001363 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001364 return( ret );
1365 }
1366
1367 if( p != end )
1368 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001369 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001370 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001371 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001372 }
1373
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001374 return( 0 );
1375}
1376
1377/*
Paul Bakkerd6d41092013-06-13 09:00:25 +02001378 * Parse one X.509 certificate in DER format from a buffer and add them to a
1379 * chained list
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001380 */
Paul Bakkerd6d41092013-06-13 09:00:25 +02001381int x509parse_crt_der( x509_cert *chain, const unsigned char *buf, size_t buflen )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001382{
Paul Bakkerd6d41092013-06-13 09:00:25 +02001383 int ret;
1384 x509_cert *crt = chain, *prev = NULL;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001385
1386 /*
1387 * Check for valid input
1388 */
1389 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001390 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001391
1392 while( crt->version != 0 && crt->next != NULL )
1393 {
1394 prev = crt;
1395 crt = crt->next;
1396 }
1397
1398 /*
1399 * Add new certificate on the end of the chain if needed.
1400 */
1401 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001402 {
1403 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1404
Paul Bakker7d06ad22009-05-02 15:53:56 +00001405 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001406 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker320a4b52009-03-28 18:52:39 +00001407
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001408 prev = crt;
Paul Bakker7d06ad22009-05-02 15:53:56 +00001409 crt = crt->next;
1410 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001411 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001412
Paul Bakkerd6d41092013-06-13 09:00:25 +02001413 if( ( ret = x509parse_crt_der_core( crt, buf, buflen ) ) != 0 )
1414 {
1415 if( prev )
1416 prev->next = NULL;
1417
1418 if( crt != chain )
1419 free( crt );
1420
1421 return( ret );
1422 }
1423
1424 return( 0 );
1425}
1426
1427/*
1428 * Parse one or more PEM certificates from a buffer and add them to the chained list
1429 */
1430int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
1431{
1432 int ret, success = 0, first_error = 0, total_failed = 0;
1433 int buf_format = X509_FORMAT_DER;
1434
1435 /*
1436 * Check for valid input
1437 */
1438 if( chain == NULL || buf == NULL )
1439 return( POLARSSL_ERR_X509_INVALID_INPUT );
1440
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001441 /*
1442 * Determine buffer content. Buffer contains either one DER certificate or
1443 * one or more PEM certificates.
1444 */
1445#if defined(POLARSSL_PEM_C)
Paul Bakkereae09db2013-06-06 12:35:54 +02001446 if( strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001447 buf_format = X509_FORMAT_PEM;
1448#endif
1449
1450 if( buf_format == X509_FORMAT_DER )
Paul Bakkerd6d41092013-06-13 09:00:25 +02001451 return x509parse_crt_der( chain, buf, buflen );
1452
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001453#if defined(POLARSSL_PEM_C)
1454 if( buf_format == X509_FORMAT_PEM )
1455 {
1456 pem_context pem;
1457
1458 while( buflen > 0 )
1459 {
1460 size_t use_len;
1461 pem_init( &pem );
1462
1463 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02001464 (char *) "-----BEGIN CERTIFICATE-----",
1465 (char *) "-----END CERTIFICATE-----",
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001466 buf, NULL, 0, &use_len );
1467
1468 if( ret == 0 )
1469 {
1470 /*
1471 * Was PEM encoded
1472 */
1473 buflen -= use_len;
1474 buf += use_len;
1475 }
Paul Bakker64171862013-06-06 15:01:18 +02001476 else if( ret == POLARSSL_ERR_PEM_BAD_INPUT_DATA )
1477 {
1478 return( ret );
1479 }
Paul Bakker9255e832013-06-06 14:58:28 +02001480 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001481 {
1482 pem_free( &pem );
1483
Paul Bakker64171862013-06-06 15:01:18 +02001484 /*
1485 * PEM header and footer were found
1486 */
1487 buflen -= use_len;
1488 buf += use_len;
1489
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001490 if( first_error == 0 )
1491 first_error = ret;
1492
Manuel Pégourié-Gonnard7d75ea42014-10-23 15:13:39 +02001493 total_failed++;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001494 continue;
1495 }
1496 else
1497 break;
1498
Paul Bakkerd6d41092013-06-13 09:00:25 +02001499 ret = x509parse_crt_der( chain, pem.buf, pem.buflen );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001500
1501 pem_free( &pem );
1502
1503 if( ret != 0 )
1504 {
1505 /*
Paul Bakkerd6d41092013-06-13 09:00:25 +02001506 * Quit parsing on a memory error
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001507 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001508 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001509 return( ret );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001510
1511 if( first_error == 0 )
1512 first_error = ret;
1513
Paul Bakkerd6d41092013-06-13 09:00:25 +02001514 total_failed++;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001515 continue;
1516 }
1517
1518 success = 1;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001519 }
1520 }
1521#endif
1522
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001523 if( success )
Paul Bakker69e095c2011-12-10 21:55:01 +00001524 return( total_failed );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001525 else if( first_error )
1526 return( first_error );
1527 else
1528 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001529}
1530
1531/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001532 * Parse one or more CRLs and add them to the chained list
1533 */
Paul Bakker23986e52011-04-24 08:57:21 +00001534int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001535{
Paul Bakker23986e52011-04-24 08:57:21 +00001536 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001537 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001538 unsigned char *p, *end;
1539 x509_crl *crl;
Paul Bakker96743fc2011-02-12 14:30:57 +00001540#if defined(POLARSSL_PEM_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00001541 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001542 pem_context pem;
1543#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001544
1545 crl = chain;
1546
1547 /*
1548 * Check for valid input
1549 */
1550 if( crl == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001551 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001552
1553 while( crl->version != 0 && crl->next != NULL )
1554 crl = crl->next;
1555
1556 /*
1557 * Add new CRL on the end of the chain if needed.
1558 */
1559 if ( crl->version != 0 && crl->next == NULL)
1560 {
1561 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1562
Paul Bakker7d06ad22009-05-02 15:53:56 +00001563 if( crl->next == NULL )
1564 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001565 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001566 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001567 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001568
Paul Bakker7d06ad22009-05-02 15:53:56 +00001569 crl = crl->next;
1570 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001571 }
1572
Paul Bakker96743fc2011-02-12 14:30:57 +00001573#if defined(POLARSSL_PEM_C)
1574 pem_init( &pem );
1575 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02001576 (char *) "-----BEGIN X509 CRL-----",
1577 (char *) "-----END X509 CRL-----",
Paul Bakker96743fc2011-02-12 14:30:57 +00001578 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001579
Paul Bakker96743fc2011-02-12 14:30:57 +00001580 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001581 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001582 /*
1583 * Was PEM encoded
1584 */
1585 buflen -= use_len;
1586 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001587
1588 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001589 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001590 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001591 p = pem.buf;
1592 pem.buf = NULL;
1593 len = pem.buflen;
1594 pem_free( &pem );
1595 }
Paul Bakker9255e832013-06-06 14:58:28 +02001596 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker96743fc2011-02-12 14:30:57 +00001597 {
1598 pem_free( &pem );
1599 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001600 }
1601 else
1602 {
1603 /*
1604 * nope, copy the raw DER data
1605 */
1606 p = (unsigned char *) malloc( len = buflen );
1607
1608 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001609 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001610
1611 memcpy( p, buf, buflen );
1612
1613 buflen = 0;
1614 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001615#else
1616 p = (unsigned char *) malloc( len = buflen );
1617
1618 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001619 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001620
1621 memcpy( p, buf, buflen );
1622
1623 buflen = 0;
1624#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001625
1626 crl->raw.p = p;
1627 crl->raw.len = len;
1628 end = p + len;
1629
1630 /*
1631 * CertificateList ::= SEQUENCE {
1632 * tbsCertList TBSCertList,
1633 * signatureAlgorithm AlgorithmIdentifier,
1634 * signatureValue BIT STRING }
1635 */
1636 if( ( ret = asn1_get_tag( &p, end, &len,
1637 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1638 {
1639 x509_crl_free( crl );
1640 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1641 }
1642
Paul Bakker23986e52011-04-24 08:57:21 +00001643 if( len != (size_t) ( end - p ) )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001644 {
1645 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001646 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001647 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1648 }
1649
1650 /*
1651 * TBSCertList ::= SEQUENCE {
1652 */
1653 crl->tbs.p = p;
1654
1655 if( ( ret = asn1_get_tag( &p, end, &len,
1656 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1657 {
1658 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001659 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001660 }
1661
1662 end = p + len;
1663 crl->tbs.len = end - crl->tbs.p;
1664
1665 /*
1666 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1667 * -- if present, MUST be v2
1668 *
1669 * signature AlgorithmIdentifier
1670 */
Paul Bakker3329d1f2011-10-12 09:55:01 +00001671 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
Paul Bakkerd98030e2009-05-02 15:13:40 +00001672 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1673 {
1674 x509_crl_free( crl );
1675 return( ret );
1676 }
1677
1678 crl->version++;
1679
1680 if( crl->version > 2 )
1681 {
1682 x509_crl_free( crl );
1683 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1684 }
1685
Paul Bakker27d66162010-03-17 06:56:01 +00001686 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_alg ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001687 {
1688 x509_crl_free( crl );
1689 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1690 }
1691
1692 /*
1693 * issuer Name
1694 */
1695 crl->issuer_raw.p = p;
1696
1697 if( ( ret = asn1_get_tag( &p, end, &len,
1698 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1699 {
1700 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001701 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001702 }
1703
1704 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1705 {
1706 x509_crl_free( crl );
1707 return( ret );
1708 }
1709
1710 crl->issuer_raw.len = p - crl->issuer_raw.p;
1711
1712 /*
1713 * thisUpdate Time
1714 * nextUpdate Time OPTIONAL
1715 */
Paul Bakker91200182010-02-18 21:26:15 +00001716 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001717 {
1718 x509_crl_free( crl );
1719 return( ret );
1720 }
1721
Paul Bakker91200182010-02-18 21:26:15 +00001722 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001723 {
Paul Bakker9d781402011-05-09 16:17:09 +00001724 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001725 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker9d781402011-05-09 16:17:09 +00001726 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001727 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001728 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001729 x509_crl_free( crl );
1730 return( ret );
1731 }
1732 }
1733
1734 /*
1735 * revokedCertificates SEQUENCE OF SEQUENCE {
1736 * userCertificate CertificateSerialNumber,
1737 * revocationDate Time,
1738 * crlEntryExtensions Extensions OPTIONAL
1739 * -- if present, MUST be v2
1740 * } OPTIONAL
1741 */
1742 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1743 {
1744 x509_crl_free( crl );
1745 return( ret );
1746 }
1747
1748 /*
1749 * crlExtensions EXPLICIT Extensions OPTIONAL
1750 * -- if present, MUST be v2
1751 */
1752 if( crl->version == 2 )
1753 {
1754 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1755
1756 if( ret != 0 )
1757 {
1758 x509_crl_free( crl );
1759 return( ret );
1760 }
1761 }
1762
1763 if( p != end )
1764 {
1765 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001766 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001767 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1768 }
1769
1770 end = crl->raw.p + crl->raw.len;
1771
1772 /*
1773 * signatureAlgorithm AlgorithmIdentifier,
1774 * signatureValue BIT STRING
1775 */
1776 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1777 {
1778 x509_crl_free( crl );
1779 return( ret );
1780 }
1781
Paul Bakker535e97d2012-08-23 10:49:55 +00001782 if( crl->sig_oid1.len != crl->sig_oid2.len ||
1783 memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001784 {
1785 x509_crl_free( crl );
1786 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1787 }
1788
1789 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1790 {
1791 x509_crl_free( crl );
1792 return( ret );
1793 }
1794
1795 if( p != end )
1796 {
1797 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001798 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001799 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1800 }
1801
1802 if( buflen > 0 )
1803 {
1804 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1805
Paul Bakker7d06ad22009-05-02 15:53:56 +00001806 if( crl->next == NULL )
1807 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001808 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001809 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001810 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001811
Paul Bakker7d06ad22009-05-02 15:53:56 +00001812 crl = crl->next;
1813 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001814
1815 return( x509parse_crl( crl, buf, buflen ) );
1816 }
1817
1818 return( 0 );
1819}
1820
Paul Bakker335db3f2011-04-25 15:28:35 +00001821#if defined(POLARSSL_FS_IO)
Paul Bakkerd98030e2009-05-02 15:13:40 +00001822/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001823 * Load all data from a file into a given buffer.
1824 */
Paul Bakker1d073c52014-07-08 20:15:51 +02001825static int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001826{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001827 FILE *f;
Paul Bakkerfe7c24c2013-09-11 11:37:33 +02001828 long size;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001829
Paul Bakkerd98030e2009-05-02 15:13:40 +00001830 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001831 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001832
Paul Bakkerd98030e2009-05-02 15:13:40 +00001833 fseek( f, 0, SEEK_END );
Paul Bakkerfe7c24c2013-09-11 11:37:33 +02001834 if( ( size = ftell( f ) ) == -1 )
1835 {
1836 fclose( f );
1837 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1838 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001839 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001840
Paul Bakkerfe7c24c2013-09-11 11:37:33 +02001841 *n = (size_t) size;
1842
1843 if( *n + 1 == 0 ||
1844 ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
1845 {
1846 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +00001847 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerfe7c24c2013-09-11 11:37:33 +02001848 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001849
Paul Bakkerd98030e2009-05-02 15:13:40 +00001850 if( fread( *buf, 1, *n, f ) != *n )
1851 {
1852 fclose( f );
1853 free( *buf );
Paul Bakker69e095c2011-12-10 21:55:01 +00001854 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001855 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001856
Paul Bakkerd98030e2009-05-02 15:13:40 +00001857 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001858
Paul Bakkerd98030e2009-05-02 15:13:40 +00001859 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001860
Paul Bakkerd98030e2009-05-02 15:13:40 +00001861 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001862}
1863
1864/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001865 * Load one or more certificates and add them to the chained list
1866 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001867int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001868{
1869 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001870 size_t n;
1871 unsigned char *buf;
1872
Paul Bakker69e095c2011-12-10 21:55:01 +00001873 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1874 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001875
Paul Bakker69e095c2011-12-10 21:55:01 +00001876 ret = x509parse_crt( chain, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001877
1878 memset( buf, 0, n + 1 );
1879 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001880
1881 return( ret );
1882}
1883
Paul Bakker8d914582012-06-04 12:46:42 +00001884int x509parse_crtpath( x509_cert *chain, const char *path )
1885{
1886 int ret = 0;
1887#if defined(_WIN32)
Paul Bakker3338b792012-10-01 21:13:10 +00001888 int w_ret;
1889 WCHAR szDir[MAX_PATH];
1890 char filename[MAX_PATH];
1891 char *p;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001892 int len = strlen( path );
Paul Bakker3338b792012-10-01 21:13:10 +00001893
Paul Bakker97872ac2012-11-02 12:53:26 +00001894 WIN32_FIND_DATAW file_data;
Paul Bakker8d914582012-06-04 12:46:42 +00001895 HANDLE hFind;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001896
1897 if( len > MAX_PATH - 3 )
1898 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker8d914582012-06-04 12:46:42 +00001899
Paul Bakker3338b792012-10-01 21:13:10 +00001900 memset( szDir, 0, sizeof(szDir) );
1901 memset( filename, 0, MAX_PATH );
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001902 memcpy( filename, path, len );
1903 filename[len++] = '\\';
1904 p = filename + len;
1905 filename[len++] = '*';
Paul Bakker3338b792012-10-01 21:13:10 +00001906
Paul Bakker40cc9142014-07-07 15:16:47 +02001907 w_ret = MultiByteToWideChar( CP_ACP, 0, filename, len, szDir, MAX_PATH - 3 );
Paul Bakker8d914582012-06-04 12:46:42 +00001908
Paul Bakker97872ac2012-11-02 12:53:26 +00001909 hFind = FindFirstFileW( szDir, &file_data );
Paul Bakker8d914582012-06-04 12:46:42 +00001910 if (hFind == INVALID_HANDLE_VALUE)
1911 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1912
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001913 len = MAX_PATH - len;
Paul Bakker8d914582012-06-04 12:46:42 +00001914 do
1915 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001916 memset( p, 0, len );
Paul Bakker3338b792012-10-01 21:13:10 +00001917
Paul Bakkere4791f32012-06-04 21:29:15 +00001918 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
Paul Bakker8d914582012-06-04 12:46:42 +00001919 continue;
1920
Paul Bakker3338b792012-10-01 21:13:10 +00001921 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
1922 lstrlenW(file_data.cFileName),
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001923 p, len - 1,
1924 NULL, NULL );
Paul Bakker8d914582012-06-04 12:46:42 +00001925
Paul Bakker3338b792012-10-01 21:13:10 +00001926 w_ret = x509parse_crtfile( chain, filename );
1927 if( w_ret < 0 )
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001928 ret++;
1929 else
1930 ret += w_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001931 }
Paul Bakker97872ac2012-11-02 12:53:26 +00001932 while( FindNextFileW( hFind, &file_data ) != 0 );
Paul Bakker8d914582012-06-04 12:46:42 +00001933
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001934 if (GetLastError() != ERROR_NO_MORE_FILES)
1935 ret = POLARSSL_ERR_X509_FILE_IO_ERROR;
Paul Bakker8d914582012-06-04 12:46:42 +00001936
1937 FindClose( hFind );
1938#else
Paul Bakker9ccb2112014-07-07 13:43:31 +02001939#if defined(POLARSSL_HAVE_READDIR_R)
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001940 int t_ret, i;
1941 struct stat sb;
1942 struct dirent entry, *result = NULL;
Paul Bakker8d914582012-06-04 12:46:42 +00001943 char entry_name[255];
1944 DIR *dir = opendir( path );
1945
1946 if( dir == NULL)
1947 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1948
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001949 while( ( t_ret = readdir_r( dir, &entry, &result ) ) == 0 )
Paul Bakker8d914582012-06-04 12:46:42 +00001950 {
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001951 if( result == NULL )
1952 break;
1953
1954 snprintf( entry_name, sizeof(entry_name), "%s/%s", path, entry.d_name );
1955
1956 i = stat( entry_name, &sb );
1957
1958 if( i == -1 )
Paul Bakker88a22642013-09-11 12:14:16 +02001959 {
1960 closedir( dir );
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001961 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker88a22642013-09-11 12:14:16 +02001962 }
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001963
1964 if( !S_ISREG( sb.st_mode ) )
Paul Bakker8d914582012-06-04 12:46:42 +00001965 continue;
1966
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001967 // Ignore parse errors
1968 //
Paul Bakker8d914582012-06-04 12:46:42 +00001969 t_ret = x509parse_crtfile( chain, entry_name );
1970 if( t_ret < 0 )
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001971 ret++;
1972 else
1973 ret += t_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001974 }
1975 closedir( dir );
Paul Bakker9ccb2112014-07-07 13:43:31 +02001976#else /* POLARSSL_HAVE_READDIR_R */
1977 ((void) chain);
1978 ((void) path);
1979 ret = POLARSSL_ERR_X509_FEATURE_UNAVAILABLE;
1980#endif /* POLARSSL_HAVE_READDIR_R */
1981#endif /* _WIN32 */
Paul Bakker8d914582012-06-04 12:46:42 +00001982
1983 return( ret );
1984}
1985
Paul Bakkerd98030e2009-05-02 15:13:40 +00001986/*
1987 * Load one or more CRLs and add them to the chained list
1988 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001989int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001990{
1991 int ret;
1992 size_t n;
1993 unsigned char *buf;
1994
Paul Bakker69e095c2011-12-10 21:55:01 +00001995 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1996 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001997
Paul Bakker27fdf462011-06-09 13:55:13 +00001998 ret = x509parse_crl( chain, buf, n );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001999
2000 memset( buf, 0, n + 1 );
2001 free( buf );
2002
2003 return( ret );
2004}
2005
Paul Bakker5121ce52009-01-03 21:22:43 +00002006/*
Paul Bakker335db3f2011-04-25 15:28:35 +00002007 * Load and parse a private RSA key
2008 */
2009int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
2010{
2011 int ret;
2012 size_t n;
2013 unsigned char *buf;
2014
Paul Bakker69e095c2011-12-10 21:55:01 +00002015 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2016 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002017
2018 if( pwd == NULL )
Paul Bakker27fdf462011-06-09 13:55:13 +00002019 ret = x509parse_key( rsa, buf, n, NULL, 0 );
Paul Bakker335db3f2011-04-25 15:28:35 +00002020 else
Paul Bakker27fdf462011-06-09 13:55:13 +00002021 ret = x509parse_key( rsa, buf, n,
Paul Bakker335db3f2011-04-25 15:28:35 +00002022 (unsigned char *) pwd, strlen( pwd ) );
2023
2024 memset( buf, 0, n + 1 );
2025 free( buf );
2026
2027 return( ret );
2028}
2029
2030/*
2031 * Load and parse a public RSA key
2032 */
2033int x509parse_public_keyfile( rsa_context *rsa, const char *path )
2034{
2035 int ret;
2036 size_t n;
2037 unsigned char *buf;
2038
Paul Bakker69e095c2011-12-10 21:55:01 +00002039 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2040 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002041
Paul Bakker27fdf462011-06-09 13:55:13 +00002042 ret = x509parse_public_key( rsa, buf, n );
Paul Bakker335db3f2011-04-25 15:28:35 +00002043
2044 memset( buf, 0, n + 1 );
2045 free( buf );
2046
2047 return( ret );
2048}
2049#endif /* POLARSSL_FS_IO */
2050
2051/*
Paul Bakker65a19092013-06-06 21:14:58 +02002052 * Parse a PKCS#1 encoded private RSA key
Paul Bakker5121ce52009-01-03 21:22:43 +00002053 */
Paul Bakker65a19092013-06-06 21:14:58 +02002054static int x509parse_key_pkcs1_der( rsa_context *rsa,
2055 const unsigned char *key,
2056 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +00002057{
Paul Bakker23986e52011-04-24 08:57:21 +00002058 int ret;
2059 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00002060 unsigned char *p, *end;
Paul Bakkered56b222011-07-13 11:26:43 +00002061
Paul Bakker96743fc2011-02-12 14:30:57 +00002062 p = (unsigned char *) key;
Paul Bakker96743fc2011-02-12 14:30:57 +00002063 end = p + keylen;
2064
Paul Bakker5121ce52009-01-03 21:22:43 +00002065 /*
Paul Bakker65a19092013-06-06 21:14:58 +02002066 * This function parses the RSAPrivateKey (PKCS#1)
Paul Bakkered56b222011-07-13 11:26:43 +00002067 *
Paul Bakker5121ce52009-01-03 21:22:43 +00002068 * RSAPrivateKey ::= SEQUENCE {
2069 * version Version,
2070 * modulus INTEGER, -- n
2071 * publicExponent INTEGER, -- e
2072 * privateExponent INTEGER, -- d
2073 * prime1 INTEGER, -- p
2074 * prime2 INTEGER, -- q
2075 * exponent1 INTEGER, -- d mod (p-1)
2076 * exponent2 INTEGER, -- d mod (q-1)
2077 * coefficient INTEGER, -- (inverse of q) mod p
2078 * otherPrimeInfos OtherPrimeInfos OPTIONAL
2079 * }
2080 */
2081 if( ( ret = asn1_get_tag( &p, end, &len,
2082 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2083 {
Paul Bakker9d781402011-05-09 16:17:09 +00002084 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002085 }
2086
2087 end = p + len;
2088
2089 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2090 {
Paul Bakker9d781402011-05-09 16:17:09 +00002091 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002092 }
2093
2094 if( rsa->ver != 0 )
2095 {
Paul Bakker9d781402011-05-09 16:17:09 +00002096 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002097 }
2098
2099 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
2100 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
2101 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
2102 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
2103 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
2104 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
2105 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
2106 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
2107 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002108 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002109 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002110 }
2111
2112 rsa->len = mpi_size( &rsa->N );
2113
2114 if( p != end )
2115 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002116 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002117 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00002118 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002119 }
2120
2121 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2122 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002123 rsa_free( rsa );
2124 return( ret );
2125 }
2126
Paul Bakker65a19092013-06-06 21:14:58 +02002127 return( 0 );
2128}
2129
2130/*
2131 * Parse an unencrypted PKCS#8 encoded private RSA key
2132 */
2133static int x509parse_key_pkcs8_unencrypted_der(
2134 rsa_context *rsa,
2135 const unsigned char *key,
2136 size_t keylen )
2137{
2138 int ret;
2139 size_t len;
2140 unsigned char *p, *end;
2141 x509_buf pk_alg_oid;
2142
2143 p = (unsigned char *) key;
2144 end = p + keylen;
2145
2146 /*
2147 * This function parses the PrivatKeyInfo object (PKCS#8)
2148 *
2149 * PrivateKeyInfo ::= SEQUENCE {
2150 * version Version,
2151 * algorithm AlgorithmIdentifier,
2152 * PrivateKey BIT STRING
2153 * }
2154 *
2155 * AlgorithmIdentifier ::= SEQUENCE {
2156 * algorithm OBJECT IDENTIFIER,
2157 * parameters ANY DEFINED BY algorithm OPTIONAL
2158 * }
2159 *
2160 * The PrivateKey BIT STRING is a PKCS#1 RSAPrivateKey
2161 */
2162 if( ( ret = asn1_get_tag( &p, end, &len,
2163 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2164 {
2165 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2166 }
2167
2168 end = p + len;
2169
2170 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2171 {
2172 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2173 }
2174
2175 if( rsa->ver != 0 )
2176 {
2177 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2178 }
2179
2180 if( ( ret = x509_get_alg( &p, end, &pk_alg_oid ) ) != 0 )
2181 {
2182 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2183 }
2184
2185 /*
2186 * only RSA keys handled at this time
2187 */
2188 if( pk_alg_oid.len != 9 ||
2189 memcmp( pk_alg_oid.p, OID_PKCS1_RSA, 9 ) != 0 )
2190 {
2191 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
2192 }
2193
2194 /*
2195 * Get the OCTET STRING and parse the PKCS#1 format inside
2196 */
2197 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2198 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2199
2200 if( ( end - p ) < 1 )
2201 {
2202 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
2203 POLARSSL_ERR_ASN1_OUT_OF_DATA );
2204 }
2205
2206 end = p + len;
2207
2208 if( ( ret = x509parse_key_pkcs1_der( rsa, p, end - p ) ) != 0 )
2209 return( ret );
2210
2211 return( 0 );
2212}
2213
2214/*
Paul Bakkerda7fdbd2013-06-19 11:15:43 +02002215 * Parse an encrypted PKCS#8 encoded private RSA key
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002216 */
2217static int x509parse_key_pkcs8_encrypted_der(
2218 rsa_context *rsa,
2219 const unsigned char *key,
2220 size_t keylen,
2221 const unsigned char *pwd,
2222 size_t pwdlen )
2223{
2224 int ret;
2225 size_t len;
2226 unsigned char *p, *end, *end2;
2227 x509_buf pbe_alg_oid, pbe_params;
2228 unsigned char buf[2048];
2229
2230 memset(buf, 0, 2048);
2231
2232 p = (unsigned char *) key;
2233 end = p + keylen;
2234
Paul Bakker1fd43212013-06-17 15:14:42 +02002235 if( pwdlen == 0 )
2236 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
2237
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002238 /*
2239 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
2240 *
2241 * EncryptedPrivateKeyInfo ::= SEQUENCE {
2242 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
2243 * encryptedData EncryptedData
2244 * }
2245 *
2246 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
2247 *
2248 * EncryptedData ::= OCTET STRING
2249 *
2250 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
2251 */
2252 if( ( ret = asn1_get_tag( &p, end, &len,
2253 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2254 {
2255 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2256 }
2257
2258 end = p + len;
2259
2260 if( ( ret = asn1_get_tag( &p, end, &len,
2261 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2262 {
2263 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2264 }
2265
2266 end2 = p + len;
2267
2268 if( ( ret = asn1_get_tag( &p, end, &pbe_alg_oid.len, ASN1_OID ) ) != 0 )
2269 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2270
2271 pbe_alg_oid.p = p;
2272 p += pbe_alg_oid.len;
2273
2274 /*
2275 * Store the algorithm parameters
2276 */
2277 pbe_params.p = p;
2278 pbe_params.len = end2 - p;
2279 p += pbe_params.len;
2280
2281 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2282 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2283
2284 // buf has been sized to 2048 bytes
2285 if( len > 2048 )
2286 return( POLARSSL_ERR_X509_INVALID_INPUT );
2287
2288 /*
2289 * Decrypt EncryptedData with appropriate PDE
2290 */
Paul Bakker14a222c2013-06-18 16:35:48 +02002291#if defined(POLARSSL_PKCS12_C)
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002292 if( OID_CMP( OID_PKCS12_PBE_SHA1_DES3_EDE_CBC, &pbe_alg_oid ) )
2293 {
Paul Bakker14a222c2013-06-18 16:35:48 +02002294 if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
2295 POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1,
2296 pwd, pwdlen, p, len, buf ) ) != 0 )
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002297 {
Paul Bakker14a222c2013-06-18 16:35:48 +02002298 if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH )
2299 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2300
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002301 return( ret );
2302 }
2303 }
2304 else if( OID_CMP( OID_PKCS12_PBE_SHA1_DES2_EDE_CBC, &pbe_alg_oid ) )
2305 {
Paul Bakker14a222c2013-06-18 16:35:48 +02002306 if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
2307 POLARSSL_CIPHER_DES_EDE_CBC, POLARSSL_MD_SHA1,
2308 pwd, pwdlen, p, len, buf ) ) != 0 )
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002309 {
Paul Bakker14a222c2013-06-18 16:35:48 +02002310 if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH )
2311 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2312
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002313 return( ret );
2314 }
2315 }
2316 else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) )
2317 {
2318 if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params,
2319 PKCS12_PBE_DECRYPT,
2320 pwd, pwdlen,
2321 p, len, buf ) ) != 0 )
2322 {
2323 return( ret );
2324 }
Paul Bakker14a222c2013-06-18 16:35:48 +02002325
2326 // Best guess for password mismatch when using RC4. If first tag is
2327 // not ASN1_CONSTRUCTED | ASN1_SEQUENCE
2328 //
2329 if( *buf != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
2330 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002331 }
Paul Bakker14a222c2013-06-18 16:35:48 +02002332 else
2333#endif /* POLARSSL_PKCS12_C */
Paul Bakker1fd43212013-06-17 15:14:42 +02002334#if defined(POLARSSL_PKCS5_C)
Paul Bakker14a222c2013-06-18 16:35:48 +02002335 if( OID_CMP( OID_PKCS5_PBES2, &pbe_alg_oid ) )
Paul Bakker1fd43212013-06-17 15:14:42 +02002336 {
2337 if( ( ret = pkcs5_pbes2( &pbe_params, PKCS5_DECRYPT, pwd, pwdlen,
2338 p, len, buf ) ) != 0 )
2339 {
2340 if( ret == POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH )
2341 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2342
2343 return( ret );
2344 }
2345 }
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002346 else
Paul Bakker14a222c2013-06-18 16:35:48 +02002347#endif /* POLARSSL_PKCS5_C */
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002348 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
2349
2350 return x509parse_key_pkcs8_unencrypted_der( rsa, buf, len );
2351}
2352
2353/*
Paul Bakker65a19092013-06-06 21:14:58 +02002354 * Parse a private RSA key
2355 */
2356int x509parse_key( rsa_context *rsa, const unsigned char *key, size_t keylen,
2357 const unsigned char *pwd, size_t pwdlen )
2358{
2359 int ret;
2360
Paul Bakker96743fc2011-02-12 14:30:57 +00002361#if defined(POLARSSL_PEM_C)
Paul Bakker65a19092013-06-06 21:14:58 +02002362 size_t len;
2363 pem_context pem;
2364
2365 pem_init( &pem );
2366 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02002367 (char *) "-----BEGIN RSA PRIVATE KEY-----",
2368 (char *) "-----END RSA PRIVATE KEY-----",
Paul Bakker65a19092013-06-06 21:14:58 +02002369 key, pwd, pwdlen, &len );
2370 if( ret == 0 )
2371 {
2372 if( ( ret = x509parse_key_pkcs1_der( rsa, pem.buf, pem.buflen ) ) != 0 )
2373 {
2374 rsa_free( rsa );
2375 }
2376
2377 pem_free( &pem );
2378 return( ret );
2379 }
Paul Bakkerb495d3a2013-06-17 15:58:04 +02002380 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
2381 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2382 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
2383 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
Paul Bakker65a19092013-06-06 21:14:58 +02002384 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker65a19092013-06-06 21:14:58 +02002385 return( ret );
Paul Bakker65a19092013-06-06 21:14:58 +02002386
2387 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02002388 (char *) "-----BEGIN PRIVATE KEY-----",
2389 (char *) "-----END PRIVATE KEY-----",
Paul Bakker65a19092013-06-06 21:14:58 +02002390 key, NULL, 0, &len );
2391 if( ret == 0 )
2392 {
2393 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa,
2394 pem.buf, pem.buflen ) ) != 0 )
2395 {
2396 rsa_free( rsa );
2397 }
2398
2399 pem_free( &pem );
2400 return( ret );
2401 }
2402 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker65a19092013-06-06 21:14:58 +02002403 return( ret );
Paul Bakker65a19092013-06-06 21:14:58 +02002404
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002405 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02002406 (char *) "-----BEGIN ENCRYPTED PRIVATE KEY-----",
2407 (char *) "-----END ENCRYPTED PRIVATE KEY-----",
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002408 key, NULL, 0, &len );
2409 if( ret == 0 )
2410 {
2411 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa,
2412 pem.buf, pem.buflen,
2413 pwd, pwdlen ) ) != 0 )
2414 {
2415 rsa_free( rsa );
2416 }
2417
2418 pem_free( &pem );
2419 return( ret );
2420 }
2421 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002422 return( ret );
Paul Bakker65a19092013-06-06 21:14:58 +02002423#else
2424 ((void) pwd);
2425 ((void) pwdlen);
2426#endif /* POLARSSL_PEM_C */
2427
2428 // At this point we only know it's not a PEM formatted key. Could be any
2429 // of the known DER encoded private key formats
2430 //
2431 // We try the different DER format parsers to see if one passes without
2432 // error
2433 //
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002434 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa, key, keylen,
2435 pwd, pwdlen ) ) == 0 )
Paul Bakker65a19092013-06-06 21:14:58 +02002436 {
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002437 return( 0 );
Paul Bakker65a19092013-06-06 21:14:58 +02002438 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002439
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002440 rsa_free( rsa );
Paul Bakker1fd43212013-06-17 15:14:42 +02002441
2442 if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH )
2443 {
2444 return( ret );
2445 }
2446
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002447 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa, key, keylen ) ) == 0 )
2448 return( 0 );
2449
2450 rsa_free( rsa );
Paul Bakker1fd43212013-06-17 15:14:42 +02002451
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002452 if( ( ret = x509parse_key_pkcs1_der( rsa, key, keylen ) ) == 0 )
2453 return( 0 );
2454
2455 rsa_free( rsa );
Paul Bakker1fd43212013-06-17 15:14:42 +02002456
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002457 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00002458}
2459
2460/*
Paul Bakker53019ae2011-03-25 13:58:48 +00002461 * Parse a public RSA key
2462 */
Paul Bakker23986e52011-04-24 08:57:21 +00002463int x509parse_public_key( rsa_context *rsa, const unsigned char *key, size_t keylen )
Paul Bakker53019ae2011-03-25 13:58:48 +00002464{
Paul Bakker23986e52011-04-24 08:57:21 +00002465 int ret;
2466 size_t len;
Paul Bakker53019ae2011-03-25 13:58:48 +00002467 unsigned char *p, *end;
2468 x509_buf alg_oid;
2469#if defined(POLARSSL_PEM_C)
2470 pem_context pem;
2471
2472 pem_init( &pem );
2473 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02002474 (char *) "-----BEGIN PUBLIC KEY-----",
2475 (char *) "-----END PUBLIC KEY-----",
Paul Bakker53019ae2011-03-25 13:58:48 +00002476 key, NULL, 0, &len );
2477
2478 if( ret == 0 )
2479 {
2480 /*
2481 * Was PEM encoded
2482 */
2483 keylen = pem.buflen;
2484 }
Paul Bakker9255e832013-06-06 14:58:28 +02002485 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker53019ae2011-03-25 13:58:48 +00002486 {
2487 pem_free( &pem );
2488 return( ret );
2489 }
2490
2491 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2492#else
2493 p = (unsigned char *) key;
2494#endif
2495 end = p + keylen;
2496
2497 /*
2498 * PublicKeyInfo ::= SEQUENCE {
2499 * algorithm AlgorithmIdentifier,
2500 * PublicKey BIT STRING
2501 * }
2502 *
2503 * AlgorithmIdentifier ::= SEQUENCE {
2504 * algorithm OBJECT IDENTIFIER,
2505 * parameters ANY DEFINED BY algorithm OPTIONAL
2506 * }
2507 *
2508 * RSAPublicKey ::= SEQUENCE {
2509 * modulus INTEGER, -- n
2510 * publicExponent INTEGER -- e
2511 * }
2512 */
2513
2514 if( ( ret = asn1_get_tag( &p, end, &len,
2515 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2516 {
2517#if defined(POLARSSL_PEM_C)
2518 pem_free( &pem );
2519#endif
2520 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002521 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002522 }
2523
2524 if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
2525 {
2526#if defined(POLARSSL_PEM_C)
2527 pem_free( &pem );
2528#endif
2529 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002530 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002531 }
2532
2533 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
2534 {
2535#if defined(POLARSSL_PEM_C)
2536 pem_free( &pem );
2537#endif
2538 rsa_free( rsa );
2539 return( ret );
2540 }
2541
2542 rsa->len = mpi_size( &rsa->N );
2543
2544#if defined(POLARSSL_PEM_C)
2545 pem_free( &pem );
2546#endif
2547
2548 return( 0 );
2549}
2550
Paul Bakkereaa89f82011-04-04 21:36:15 +00002551#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00002552/*
Paul Bakker1b57b062011-01-06 15:48:19 +00002553 * Parse DHM parameters
2554 */
Paul Bakker23986e52011-04-24 08:57:21 +00002555int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
Paul Bakker1b57b062011-01-06 15:48:19 +00002556{
Paul Bakker23986e52011-04-24 08:57:21 +00002557 int ret;
2558 size_t len;
Paul Bakker1b57b062011-01-06 15:48:19 +00002559 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00002560#if defined(POLARSSL_PEM_C)
2561 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00002562
Paul Bakker96743fc2011-02-12 14:30:57 +00002563 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00002564
Paul Bakker96743fc2011-02-12 14:30:57 +00002565 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02002566 (char *) "-----BEGIN DH PARAMETERS-----",
2567 (char *) "-----END DH PARAMETERS-----",
Paul Bakker96743fc2011-02-12 14:30:57 +00002568 dhmin, NULL, 0, &dhminlen );
2569
2570 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00002571 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002572 /*
2573 * Was PEM encoded
2574 */
2575 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00002576 }
Paul Bakker9255e832013-06-06 14:58:28 +02002577 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00002578 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002579 pem_free( &pem );
2580 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002581 }
2582
Paul Bakker96743fc2011-02-12 14:30:57 +00002583 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
2584#else
2585 p = (unsigned char *) dhmin;
2586#endif
2587 end = p + dhminlen;
2588
Paul Bakker1b57b062011-01-06 15:48:19 +00002589 memset( dhm, 0, sizeof( dhm_context ) );
2590
Paul Bakker1b57b062011-01-06 15:48:19 +00002591 /*
2592 * DHParams ::= SEQUENCE {
2593 * prime INTEGER, -- P
2594 * generator INTEGER, -- g
2595 * }
2596 */
2597 if( ( ret = asn1_get_tag( &p, end, &len,
2598 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2599 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002600#if defined(POLARSSL_PEM_C)
2601 pem_free( &pem );
2602#endif
Paul Bakker9d781402011-05-09 16:17:09 +00002603 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002604 }
2605
2606 end = p + len;
2607
2608 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
2609 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
2610 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002611#if defined(POLARSSL_PEM_C)
2612 pem_free( &pem );
2613#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002614 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002615 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002616 }
2617
2618 if( p != end )
2619 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002620#if defined(POLARSSL_PEM_C)
2621 pem_free( &pem );
2622#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002623 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002624 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker1b57b062011-01-06 15:48:19 +00002625 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
2626 }
2627
Paul Bakker96743fc2011-02-12 14:30:57 +00002628#if defined(POLARSSL_PEM_C)
2629 pem_free( &pem );
2630#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002631
2632 return( 0 );
2633}
2634
Paul Bakker335db3f2011-04-25 15:28:35 +00002635#if defined(POLARSSL_FS_IO)
Paul Bakker1b57b062011-01-06 15:48:19 +00002636/*
2637 * Load and parse a private RSA key
2638 */
2639int x509parse_dhmfile( dhm_context *dhm, const char *path )
2640{
2641 int ret;
2642 size_t n;
2643 unsigned char *buf;
2644
Paul Bakker69e095c2011-12-10 21:55:01 +00002645 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
2646 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002647
Paul Bakker27fdf462011-06-09 13:55:13 +00002648 ret = x509parse_dhm( dhm, buf, n );
Paul Bakker1b57b062011-01-06 15:48:19 +00002649
2650 memset( buf, 0, n + 1 );
2651 free( buf );
2652
2653 return( ret );
2654}
Paul Bakker335db3f2011-04-25 15:28:35 +00002655#endif /* POLARSSL_FS_IO */
Paul Bakkereaa89f82011-04-04 21:36:15 +00002656#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00002657
Paul Bakker5121ce52009-01-03 21:22:43 +00002658#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002659#include <stdarg.h>
2660
2661#if !defined vsnprintf
2662#define vsnprintf _vsnprintf
2663#endif // vsnprintf
2664
2665/*
2666 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2667 * Result value is not size of buffer needed, but -1 if no fit is possible.
2668 *
2669 * This fuction tries to 'fix' this by at least suggesting enlarging the
2670 * size by 20.
2671 */
2672int compat_snprintf(char *str, size_t size, const char *format, ...)
2673{
2674 va_list ap;
2675 int res = -1;
2676
2677 va_start( ap, format );
2678
2679 res = vsnprintf( str, size, format, ap );
2680
2681 va_end( ap );
2682
2683 // No quick fix possible
2684 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00002685 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002686
2687 return res;
2688}
2689
2690#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002691#endif
2692
Paul Bakkerd98030e2009-05-02 15:13:40 +00002693#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2694
2695#define SAFE_SNPRINTF() \
2696{ \
2697 if( ret == -1 ) \
2698 return( -1 ); \
2699 \
Paul Bakker23986e52011-04-24 08:57:21 +00002700 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002701 p[n - 1] = '\0'; \
2702 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2703 } \
2704 \
Paul Bakker23986e52011-04-24 08:57:21 +00002705 n -= (unsigned int) ret; \
2706 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002707}
2708
Paul Bakker5121ce52009-01-03 21:22:43 +00002709/*
2710 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002711 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002712 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002713int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002714{
Paul Bakker23986e52011-04-24 08:57:21 +00002715 int ret;
2716 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002717 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002718 const x509_name *name;
Paul Bakker5121ce52009-01-03 21:22:43 +00002719 char s[128], *p;
2720
2721 memset( s, 0, sizeof( s ) );
2722
2723 name = dn;
2724 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002725 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002726
2727 while( name != NULL )
2728 {
Paul Bakkercefb3962012-06-27 11:51:09 +00002729 if( !name->oid.p )
2730 {
2731 name = name->next;
2732 continue;
2733 }
2734
Paul Bakker74111d32011-01-15 16:57:55 +00002735 if( name != dn )
2736 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002737 ret = snprintf( p, n, ", " );
2738 SAFE_SNPRINTF();
2739 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002740
Paul Bakker535e97d2012-08-23 10:49:55 +00002741 if( name->oid.len == 3 &&
2742 memcmp( name->oid.p, OID_X520, 2 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002743 {
2744 switch( name->oid.p[2] )
2745 {
2746 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002747 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002748
2749 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002750 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002751
2752 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002753 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002754
2755 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002756 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002757
2758 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002759 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002760
2761 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002762 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002763
2764 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002765 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002766 name->oid.p[2] );
2767 break;
2768 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002769 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002770 }
Paul Bakker535e97d2012-08-23 10:49:55 +00002771 else if( name->oid.len == 9 &&
2772 memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002773 {
2774 switch( name->oid.p[8] )
2775 {
2776 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002777 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002778
2779 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002780 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002781 name->oid.p[8] );
2782 break;
2783 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002784 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002785 }
2786 else
Paul Bakker74111d32011-01-15 16:57:55 +00002787 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002788 ret = snprintf( p, n, "\?\?=" );
Paul Bakker74111d32011-01-15 16:57:55 +00002789 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002790 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002791
2792 for( i = 0; i < name->val.len; i++ )
2793 {
Paul Bakker27fdf462011-06-09 13:55:13 +00002794 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002795 break;
2796
2797 c = name->val.p[i];
2798 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2799 s[i] = '?';
2800 else s[i] = c;
2801 }
2802 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002803 ret = snprintf( p, n, "%s", s );
2804 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002805 name = name->next;
2806 }
2807
Paul Bakker23986e52011-04-24 08:57:21 +00002808 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002809}
2810
2811/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002812 * Store the serial in printable form into buf; no more
2813 * than size characters will be written
2814 */
2815int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2816{
Paul Bakker23986e52011-04-24 08:57:21 +00002817 int ret;
2818 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00002819 char *p;
2820
2821 p = buf;
2822 n = size;
2823
2824 nr = ( serial->len <= 32 )
Paul Bakker03c7c252011-11-25 12:37:37 +00002825 ? serial->len : 28;
Paul Bakkerdd476992011-01-16 21:34:59 +00002826
2827 for( i = 0; i < nr; i++ )
2828 {
Paul Bakker93048802011-12-05 14:38:06 +00002829 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002830 continue;
2831
Paul Bakkerdd476992011-01-16 21:34:59 +00002832 ret = snprintf( p, n, "%02X%s",
2833 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2834 SAFE_SNPRINTF();
2835 }
2836
Paul Bakker03c7c252011-11-25 12:37:37 +00002837 if( nr != serial->len )
2838 {
2839 ret = snprintf( p, n, "...." );
2840 SAFE_SNPRINTF();
2841 }
2842
Paul Bakker23986e52011-04-24 08:57:21 +00002843 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00002844}
2845
2846/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002847 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002848 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002849int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2850 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002851{
Paul Bakker23986e52011-04-24 08:57:21 +00002852 int ret;
2853 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002854 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00002855
2856 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002857 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002858
Paul Bakkerd98030e2009-05-02 15:13:40 +00002859 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002860 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002861 SAFE_SNPRINTF();
2862 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002863 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002864 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002865
Paul Bakkerdd476992011-01-16 21:34:59 +00002866 ret = x509parse_serial_gets( p, n, &crt->serial);
2867 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002868
Paul Bakkerd98030e2009-05-02 15:13:40 +00002869 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2870 SAFE_SNPRINTF();
2871 ret = x509parse_dn_gets( p, n, &crt->issuer );
2872 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002873
Paul Bakkerd98030e2009-05-02 15:13:40 +00002874 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2875 SAFE_SNPRINTF();
2876 ret = x509parse_dn_gets( p, n, &crt->subject );
2877 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002878
Paul Bakkerd98030e2009-05-02 15:13:40 +00002879 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002880 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2881 crt->valid_from.year, crt->valid_from.mon,
2882 crt->valid_from.day, crt->valid_from.hour,
2883 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002884 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002885
Paul Bakkerd98030e2009-05-02 15:13:40 +00002886 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002887 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2888 crt->valid_to.year, crt->valid_to.mon,
2889 crt->valid_to.day, crt->valid_to.hour,
2890 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002891 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002892
Paul Bakkerd98030e2009-05-02 15:13:40 +00002893 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2894 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002895
Paul Bakker27d66162010-03-17 06:56:01 +00002896 switch( crt->sig_alg )
Paul Bakker5121ce52009-01-03 21:22:43 +00002897 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002898 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2899 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2900 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2901 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2902 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2903 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2904 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2905 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2906 default: ret = snprintf( p, n, "???" ); break;
2907 }
2908 SAFE_SNPRINTF();
2909
2910 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
Paul Bakker5c2364c2012-10-01 14:41:15 +00002911 (int) crt->rsa.N.n * (int) sizeof( t_uint ) * 8 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002912 SAFE_SNPRINTF();
2913
Paul Bakker23986e52011-04-24 08:57:21 +00002914 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002915}
2916
Paul Bakker74111d32011-01-15 16:57:55 +00002917/*
2918 * Return an informational string describing the given OID
2919 */
2920const char *x509_oid_get_description( x509_buf *oid )
2921{
2922 if ( oid == NULL )
2923 return ( NULL );
2924
2925 else if( OID_CMP( OID_SERVER_AUTH, oid ) )
2926 return( STRING_SERVER_AUTH );
2927
2928 else if( OID_CMP( OID_CLIENT_AUTH, oid ) )
2929 return( STRING_CLIENT_AUTH );
2930
2931 else if( OID_CMP( OID_CODE_SIGNING, oid ) )
2932 return( STRING_CODE_SIGNING );
2933
2934 else if( OID_CMP( OID_EMAIL_PROTECTION, oid ) )
2935 return( STRING_EMAIL_PROTECTION );
2936
2937 else if( OID_CMP( OID_TIME_STAMPING, oid ) )
2938 return( STRING_TIME_STAMPING );
2939
2940 else if( OID_CMP( OID_OCSP_SIGNING, oid ) )
2941 return( STRING_OCSP_SIGNING );
2942
2943 return( NULL );
2944}
2945
2946/* Return the x.y.z.... style numeric string for the given OID */
2947int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2948{
Paul Bakker23986e52011-04-24 08:57:21 +00002949 int ret;
2950 size_t i, n;
Paul Bakker74111d32011-01-15 16:57:55 +00002951 unsigned int value;
2952 char *p;
2953
2954 p = buf;
2955 n = size;
2956
2957 /* First byte contains first two dots */
2958 if( oid->len > 0 )
2959 {
2960 ret = snprintf( p, n, "%d.%d", oid->p[0]/40, oid->p[0]%40 );
2961 SAFE_SNPRINTF();
2962 }
2963
2964 /* TODO: value can overflow in value. */
2965 value = 0;
Paul Bakker23986e52011-04-24 08:57:21 +00002966 for( i = 1; i < oid->len; i++ )
Paul Bakker74111d32011-01-15 16:57:55 +00002967 {
2968 value <<= 7;
2969 value += oid->p[i] & 0x7F;
2970
2971 if( !( oid->p[i] & 0x80 ) )
2972 {
2973 /* Last byte */
2974 ret = snprintf( p, n, ".%d", value );
2975 SAFE_SNPRINTF();
2976 value = 0;
2977 }
2978 }
2979
Paul Bakker23986e52011-04-24 08:57:21 +00002980 return( (int) ( size - n ) );
Paul Bakker74111d32011-01-15 16:57:55 +00002981}
2982
Paul Bakkerd98030e2009-05-02 15:13:40 +00002983/*
2984 * Return an informational string about the CRL.
2985 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002986int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2987 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002988{
Paul Bakker23986e52011-04-24 08:57:21 +00002989 int ret;
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002990 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002991 char *p;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002992 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002993
2994 p = buf;
2995 n = size;
2996
2997 ret = snprintf( p, n, "%sCRL version : %d",
2998 prefix, crl->version );
2999 SAFE_SNPRINTF();
3000
3001 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
3002 SAFE_SNPRINTF();
3003 ret = x509parse_dn_gets( p, n, &crl->issuer );
3004 SAFE_SNPRINTF();
3005
3006 ret = snprintf( p, n, "\n%sthis update : " \
3007 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3008 crl->this_update.year, crl->this_update.mon,
3009 crl->this_update.day, crl->this_update.hour,
3010 crl->this_update.min, crl->this_update.sec );
3011 SAFE_SNPRINTF();
3012
3013 ret = snprintf( p, n, "\n%snext update : " \
3014 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3015 crl->next_update.year, crl->next_update.mon,
3016 crl->next_update.day, crl->next_update.hour,
3017 crl->next_update.min, crl->next_update.sec );
3018 SAFE_SNPRINTF();
3019
3020 entry = &crl->entry;
3021
3022 ret = snprintf( p, n, "\n%sRevoked certificates:",
3023 prefix );
3024 SAFE_SNPRINTF();
3025
Paul Bakker9be19372009-07-27 20:21:53 +00003026 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003027 {
3028 ret = snprintf( p, n, "\n%sserial number: ",
3029 prefix );
3030 SAFE_SNPRINTF();
3031
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003032 ret = x509parse_serial_gets( p, n, &entry->serial);
3033 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003034
Paul Bakkerd98030e2009-05-02 15:13:40 +00003035 ret = snprintf( p, n, " revocation date: " \
3036 "%04d-%02d-%02d %02d:%02d:%02d",
3037 entry->revocation_date.year, entry->revocation_date.mon,
3038 entry->revocation_date.day, entry->revocation_date.hour,
3039 entry->revocation_date.min, entry->revocation_date.sec );
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003040 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003041
3042 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003043 }
3044
Paul Bakkerd98030e2009-05-02 15:13:40 +00003045 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
3046 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003047
Paul Bakker27d66162010-03-17 06:56:01 +00003048 switch( crl->sig_alg )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003049 {
3050 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
3051 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
3052 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
3053 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
3054 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
3055 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
3056 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
3057 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
3058 default: ret = snprintf( p, n, "???" ); break;
3059 }
3060 SAFE_SNPRINTF();
3061
Paul Bakker1e27bb22009-07-19 20:25:25 +00003062 ret = snprintf( p, n, "\n" );
3063 SAFE_SNPRINTF();
3064
Paul Bakker23986e52011-04-24 08:57:21 +00003065 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003066}
3067
3068/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00003069 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00003070 */
Paul Bakker0d844dd2014-07-07 17:44:14 +02003071static void x509_get_current_time( x509_time *now )
Paul Bakker5121ce52009-01-03 21:22:43 +00003072{
Paul Bakkercce9d772011-11-18 14:26:47 +00003073#if defined(_WIN32)
3074 SYSTEMTIME st;
3075
Paul Bakkerf48de952014-07-08 14:39:41 +02003076 GetSystemTime(&st);
Paul Bakkercce9d772011-11-18 14:26:47 +00003077
Paul Bakker0d844dd2014-07-07 17:44:14 +02003078 now->year = st.wYear;
3079 now->mon = st.wMonth;
3080 now->day = st.wDay;
3081 now->hour = st.wHour;
3082 now->min = st.wMinute;
3083 now->sec = st.wSecond;
Paul Bakkercce9d772011-11-18 14:26:47 +00003084#else
Paul Bakker358a8412014-07-08 12:14:37 +02003085 struct tm lt;
Paul Bakker5121ce52009-01-03 21:22:43 +00003086 time_t tt;
3087
3088 tt = time( NULL );
Paul Bakkerf48de952014-07-08 14:39:41 +02003089 gmtime_r( &tt, &lt );
Paul Bakker5121ce52009-01-03 21:22:43 +00003090
Paul Bakker358a8412014-07-08 12:14:37 +02003091 now->year = lt.tm_year + 1900;
3092 now->mon = lt.tm_mon + 1;
3093 now->day = lt.tm_mday;
3094 now->hour = lt.tm_hour;
3095 now->min = lt.tm_min;
3096 now->sec = lt.tm_sec;
Paul Bakkercce9d772011-11-18 14:26:47 +00003097#endif
Paul Bakker0d844dd2014-07-07 17:44:14 +02003098}
Paul Bakkercce9d772011-11-18 14:26:47 +00003099
Paul Bakker0d844dd2014-07-07 17:44:14 +02003100/*
3101 * Return 0 if before <= after, 1 otherwise
3102 */
3103static int x509_check_time( const x509_time *before, const x509_time *after )
3104{
3105 if( before->year > after->year )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003106 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003107
Paul Bakker0d844dd2014-07-07 17:44:14 +02003108 if( before->year == after->year &&
3109 before->mon > after->mon )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003110 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003111
Paul Bakker0d844dd2014-07-07 17:44:14 +02003112 if( before->year == after->year &&
3113 before->mon == after->mon &&
3114 before->day > after->day )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003115 return( 1 );
3116
Paul Bakker0d844dd2014-07-07 17:44:14 +02003117 if( before->year == after->year &&
3118 before->mon == after->mon &&
3119 before->day == after->day &&
3120 before->hour > after->hour )
Paul Bakkerb6194992011-01-16 21:40:22 +00003121 return( 1 );
3122
Paul Bakker0d844dd2014-07-07 17:44:14 +02003123 if( before->year == after->year &&
3124 before->mon == after->mon &&
3125 before->day == after->day &&
3126 before->hour == after->hour &&
3127 before->min > after->min )
Paul Bakkerb6194992011-01-16 21:40:22 +00003128 return( 1 );
3129
Paul Bakker0d844dd2014-07-07 17:44:14 +02003130 if( before->year == after->year &&
3131 before->mon == after->mon &&
3132 before->day == after->day &&
3133 before->hour == after->hour &&
3134 before->min == after->min &&
3135 before->sec > after->sec )
Paul Bakkerb6194992011-01-16 21:40:22 +00003136 return( 1 );
3137
Paul Bakker40ea7de2009-05-03 10:18:48 +00003138 return( 0 );
3139}
3140
Paul Bakker0d844dd2014-07-07 17:44:14 +02003141int x509parse_time_expired( const x509_time *to )
3142{
3143 x509_time now;
3144
3145 x509_get_current_time( &now );
3146
3147 return( x509_check_time( &now, to ) );
3148}
3149
3150int x509parse_time_future( const x509_time *from )
3151{
3152 x509_time now;
3153
3154 x509_get_current_time( &now );
3155
3156 return( x509_check_time( from, &now ) );
3157}
3158
Paul Bakker40ea7de2009-05-03 10:18:48 +00003159/*
3160 * Return 1 if the certificate is revoked, or 0 otherwise.
3161 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003162int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003163{
Paul Bakkerff60ee62010-03-16 21:09:09 +00003164 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00003165
3166 while( cur != NULL && cur->serial.len != 0 )
3167 {
Paul Bakkera056efc2011-01-16 21:38:35 +00003168 if( crt->serial.len == cur->serial.len &&
3169 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003170 {
3171 if( x509parse_time_expired( &cur->revocation_date ) )
3172 return( 1 );
3173 }
3174
3175 cur = cur->next;
3176 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003177
3178 return( 0 );
3179}
3180
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003181/*
3182 * Wrapper for x509 hashes.
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003183 */
Paul Bakker23986e52011-04-24 08:57:21 +00003184static void x509_hash( const unsigned char *in, size_t len, int alg,
Paul Bakker5121ce52009-01-03 21:22:43 +00003185 unsigned char *out )
3186{
3187 switch( alg )
3188 {
Paul Bakker40e46942009-01-03 21:51:57 +00003189#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003190 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003191#endif
Paul Bakker40e46942009-01-03 21:51:57 +00003192#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003193 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003194#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003195#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003196 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003197#endif
3198#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003199 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003200#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00003201#if defined(POLARSSL_SHA2_C)
3202 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
3203 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
3204#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00003205#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003206 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
3207 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
3208#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003209 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003210 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003211 break;
3212 }
3213}
3214
3215/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00003216 * Check that the given certificate is valid accoring to the CRL.
3217 */
3218static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
3219 x509_crl *crl_list)
3220{
3221 int flags = 0;
3222 int hash_id;
3223 unsigned char hash[64];
3224
Paul Bakker915275b2012-09-28 07:10:55 +00003225 if( ca == NULL )
3226 return( flags );
3227
Paul Bakker76fd75a2011-01-16 21:12:10 +00003228 /*
3229 * TODO: What happens if no CRL is present?
3230 * Suggestion: Revocation state should be unknown if no CRL is present.
3231 * For backwards compatibility this is not yet implemented.
3232 */
3233
Paul Bakker915275b2012-09-28 07:10:55 +00003234 while( crl_list != NULL )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003235 {
Paul Bakker915275b2012-09-28 07:10:55 +00003236 if( crl_list->version == 0 ||
3237 crl_list->issuer_raw.len != ca->subject_raw.len ||
Paul Bakker76fd75a2011-01-16 21:12:10 +00003238 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
3239 crl_list->issuer_raw.len ) != 0 )
3240 {
3241 crl_list = crl_list->next;
3242 continue;
3243 }
3244
3245 /*
3246 * Check if CRL is correctly signed by the trusted CA
3247 */
3248 hash_id = crl_list->sig_alg;
3249
3250 x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
3251
Paul Bakker43f97992013-09-23 11:23:31 +02003252 if( !rsa_pkcs1_verify( &ca->rsa, NULL, NULL, RSA_PUBLIC, hash_id,
Paul Bakker76fd75a2011-01-16 21:12:10 +00003253 0, hash, crl_list->sig.p ) == 0 )
3254 {
3255 /*
3256 * CRL is not trusted
3257 */
3258 flags |= BADCRL_NOT_TRUSTED;
3259 break;
3260 }
3261
3262 /*
3263 * Check for validity of CRL (Do not drop out)
3264 */
3265 if( x509parse_time_expired( &crl_list->next_update ) )
3266 flags |= BADCRL_EXPIRED;
3267
Paul Bakker50a5c532014-07-08 10:59:10 +02003268 if( x509parse_time_future( &crl_list->this_update ) )
3269 flags |= BADCRL_FUTURE;
3270
Paul Bakker76fd75a2011-01-16 21:12:10 +00003271 /*
3272 * Check if certificate is revoked
3273 */
3274 if( x509parse_revoked(crt, crl_list) )
3275 {
3276 flags |= BADCERT_REVOKED;
3277 break;
3278 }
3279
3280 crl_list = crl_list->next;
3281 }
3282 return flags;
3283}
3284
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003285// Equal == 0, inequal == 1
3286static int x509_name_cmp( const void *s1, const void *s2, size_t len )
3287{
3288 size_t i;
3289 unsigned char diff;
3290 const unsigned char *n1 = s1, *n2 = s2;
3291
3292 for( i = 0; i < len; i++ )
3293 {
3294 diff = n1[i] ^ n2[i];
3295
Paul Bakkerc941adb2014-07-07 14:17:24 +02003296 if( diff == 0 )
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003297 continue;
3298
Paul Bakkerc941adb2014-07-07 14:17:24 +02003299 if( diff == 32 &&
3300 ( ( n1[i] >= 'a' && n1[i] <= 'z' ) ||
3301 ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) )
3302 {
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003303 continue;
Paul Bakkerc941adb2014-07-07 14:17:24 +02003304 }
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003305
3306 return( 1 );
3307 }
3308
3309 return( 0 );
3310}
3311
Paul Bakker1d073c52014-07-08 20:15:51 +02003312static int x509_wildcard_verify( const char *cn, x509_buf *name )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003313{
3314 size_t i;
3315 size_t cn_idx = 0;
3316
Paul Bakker57b12982012-02-11 17:38:38 +00003317 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003318 return( 0 );
3319
3320 for( i = 0; i < strlen( cn ); ++i )
3321 {
3322 if( cn[i] == '.' )
3323 {
3324 cn_idx = i;
3325 break;
3326 }
3327 }
3328
3329 if( cn_idx == 0 )
3330 return( 0 );
3331
Paul Bakker535e97d2012-08-23 10:49:55 +00003332 if( strlen( cn ) - cn_idx == name->len - 1 &&
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003333 x509_name_cmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003334 {
3335 return( 1 );
3336 }
3337
3338 return( 0 );
3339}
3340
Paul Bakker915275b2012-09-28 07:10:55 +00003341static int x509parse_verify_top(
3342 x509_cert *child, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003343 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003344 int (*f_vrfy)(void *, x509_cert *, int, int *),
3345 void *p_vrfy )
3346{
3347 int hash_id, ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003348 int ca_flags = 0, check_path_cnt = path_cnt + 1;
Paul Bakker915275b2012-09-28 07:10:55 +00003349 unsigned char hash[64];
3350
3351 if( x509parse_time_expired( &child->valid_to ) )
3352 *flags |= BADCERT_EXPIRED;
3353
Paul Bakker50a5c532014-07-08 10:59:10 +02003354 if( x509parse_time_future( &child->valid_from ) )
3355 *flags |= BADCERT_FUTURE;
3356
Paul Bakker915275b2012-09-28 07:10:55 +00003357 /*
3358 * Child is the top of the chain. Check against the trust_ca list.
3359 */
3360 *flags |= BADCERT_NOT_TRUSTED;
3361
3362 while( trust_ca != NULL )
3363 {
3364 if( trust_ca->version == 0 ||
3365 child->issuer_raw.len != trust_ca->subject_raw.len ||
3366 memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
3367 child->issuer_raw.len ) != 0 )
3368 {
3369 trust_ca = trust_ca->next;
3370 continue;
3371 }
3372
Paul Bakker9a736322012-11-14 12:39:52 +00003373 /*
3374 * Reduce path_len to check against if top of the chain is
3375 * the same as the trusted CA
3376 */
3377 if( child->subject_raw.len == trust_ca->subject_raw.len &&
3378 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3379 child->issuer_raw.len ) == 0 )
3380 {
3381 check_path_cnt--;
3382 }
3383
Paul Bakker915275b2012-09-28 07:10:55 +00003384 if( trust_ca->max_pathlen > 0 &&
Paul Bakker9a736322012-11-14 12:39:52 +00003385 trust_ca->max_pathlen < check_path_cnt )
Paul Bakker915275b2012-09-28 07:10:55 +00003386 {
3387 trust_ca = trust_ca->next;
3388 continue;
3389 }
3390
3391 hash_id = child->sig_alg;
3392
3393 x509_hash( child->tbs.p, child->tbs.len, hash_id, hash );
3394
Paul Bakker43f97992013-09-23 11:23:31 +02003395 if( rsa_pkcs1_verify( &trust_ca->rsa, NULL, NULL, RSA_PUBLIC, hash_id,
Paul Bakker915275b2012-09-28 07:10:55 +00003396 0, hash, child->sig.p ) != 0 )
3397 {
3398 trust_ca = trust_ca->next;
3399 continue;
3400 }
3401
3402 /*
3403 * Top of chain is signed by a trusted CA
3404 */
3405 *flags &= ~BADCERT_NOT_TRUSTED;
3406 break;
3407 }
3408
Paul Bakker9a736322012-11-14 12:39:52 +00003409 /*
Paul Bakker3497d8c2012-11-24 11:53:17 +01003410 * If top of chain is not the same as the trusted CA send a verify request
3411 * to the callback for any issues with validity and CRL presence for the
3412 * trusted CA certificate.
Paul Bakker9a736322012-11-14 12:39:52 +00003413 */
3414 if( trust_ca != NULL &&
3415 ( child->subject_raw.len != trust_ca->subject_raw.len ||
3416 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3417 child->issuer_raw.len ) != 0 ) )
Paul Bakker915275b2012-09-28 07:10:55 +00003418 {
3419 /* Check trusted CA's CRL for then chain's top crt */
3420 *flags |= x509parse_verifycrl( child, trust_ca, ca_crl );
3421
3422 if( x509parse_time_expired( &trust_ca->valid_to ) )
3423 ca_flags |= BADCERT_EXPIRED;
3424
Paul Bakker50a5c532014-07-08 10:59:10 +02003425 if( x509parse_time_future( &trust_ca->valid_from ) )
3426 ca_flags |= BADCERT_FUTURE;
3427
Paul Bakker915275b2012-09-28 07:10:55 +00003428 if( NULL != f_vrfy )
3429 {
Paul Bakker9a736322012-11-14 12:39:52 +00003430 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003431 return( ret );
3432 }
3433 }
3434
3435 /* Call callback on top cert */
3436 if( NULL != f_vrfy )
3437 {
Paul Bakker9a736322012-11-14 12:39:52 +00003438 if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003439 return( ret );
3440 }
3441
Paul Bakker915275b2012-09-28 07:10:55 +00003442 *flags |= ca_flags;
3443
3444 return( 0 );
3445}
3446
3447static int x509parse_verify_child(
3448 x509_cert *child, x509_cert *parent, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003449 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003450 int (*f_vrfy)(void *, x509_cert *, int, int *),
3451 void *p_vrfy )
3452{
3453 int hash_id, ret;
3454 int parent_flags = 0;
3455 unsigned char hash[64];
3456 x509_cert *grandparent;
3457
3458 if( x509parse_time_expired( &child->valid_to ) )
3459 *flags |= BADCERT_EXPIRED;
3460
Paul Bakker50a5c532014-07-08 10:59:10 +02003461 if( x509parse_time_future( &child->valid_from ) )
3462 *flags |= BADCERT_FUTURE;
3463
Paul Bakker915275b2012-09-28 07:10:55 +00003464 hash_id = child->sig_alg;
3465
3466 x509_hash( child->tbs.p, child->tbs.len, hash_id, hash );
3467
Paul Bakker43f97992013-09-23 11:23:31 +02003468 if( rsa_pkcs1_verify( &parent->rsa, NULL, NULL, RSA_PUBLIC, hash_id, 0,
3469 hash, child->sig.p ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003470 *flags |= BADCERT_NOT_TRUSTED;
3471
3472 /* Check trusted CA's CRL for the given crt */
3473 *flags |= x509parse_verifycrl(child, parent, ca_crl);
3474
3475 grandparent = parent->next;
3476
3477 while( grandparent != NULL )
3478 {
3479 if( grandparent->version == 0 ||
3480 grandparent->ca_istrue == 0 ||
3481 parent->issuer_raw.len != grandparent->subject_raw.len ||
3482 memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
3483 parent->issuer_raw.len ) != 0 )
3484 {
3485 grandparent = grandparent->next;
3486 continue;
3487 }
3488 break;
3489 }
3490
Paul Bakker915275b2012-09-28 07:10:55 +00003491 if( grandparent != NULL )
3492 {
3493 /*
3494 * Part of the chain
3495 */
Paul Bakker9a736322012-11-14 12:39:52 +00003496 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 +00003497 if( ret != 0 )
3498 return( ret );
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003499 }
Paul Bakker915275b2012-09-28 07:10:55 +00003500 else
3501 {
Paul Bakker9a736322012-11-14 12:39:52 +00003502 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 +00003503 if( ret != 0 )
3504 return( ret );
3505 }
3506
3507 /* child is verified to be a child of the parent, call verify callback */
3508 if( NULL != f_vrfy )
Paul Bakker9a736322012-11-14 12:39:52 +00003509 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003510 return( ret );
Paul Bakker915275b2012-09-28 07:10:55 +00003511
3512 *flags |= parent_flags;
3513
3514 return( 0 );
3515}
3516
Paul Bakker76fd75a2011-01-16 21:12:10 +00003517/*
Paul Bakker5121ce52009-01-03 21:22:43 +00003518 * Verify the certificate validity
3519 */
3520int x509parse_verify( x509_cert *crt,
3521 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00003522 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003523 const char *cn, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003524 int (*f_vrfy)(void *, x509_cert *, int, int *),
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003525 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00003526{
Paul Bakker23986e52011-04-24 08:57:21 +00003527 size_t cn_len;
Paul Bakker915275b2012-09-28 07:10:55 +00003528 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003529 int pathlen = 0;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003530 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00003531 x509_name *name;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003532 x509_sequence *cur = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003533
Paul Bakker40ea7de2009-05-03 10:18:48 +00003534 *flags = 0;
3535
Paul Bakker5121ce52009-01-03 21:22:43 +00003536 if( cn != NULL )
3537 {
3538 name = &crt->subject;
3539 cn_len = strlen( cn );
3540
Paul Bakker4d2c1242012-05-10 14:12:46 +00003541 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
Paul Bakker5121ce52009-01-03 21:22:43 +00003542 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00003543 cur = &crt->subject_alt_names;
3544
3545 while( cur != NULL )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003546 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003547 if( cur->buf.len == cn_len &&
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003548 x509_name_cmp( cn, cur->buf.p, cn_len ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003549 break;
3550
Paul Bakker535e97d2012-08-23 10:49:55 +00003551 if( cur->buf.len > 2 &&
3552 memcmp( cur->buf.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003553 x509_wildcard_verify( cn, &cur->buf ) )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003554 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003555
Paul Bakker4d2c1242012-05-10 14:12:46 +00003556 cur = cur->next;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003557 }
3558
3559 if( cur == NULL )
3560 *flags |= BADCERT_CN_MISMATCH;
3561 }
Paul Bakker4d2c1242012-05-10 14:12:46 +00003562 else
3563 {
3564 while( name != NULL )
3565 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003566 if( name->oid.len == 3 &&
3567 memcmp( name->oid.p, OID_CN, 3 ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003568 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003569 if( name->val.len == cn_len &&
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003570 x509_name_cmp( name->val.p, cn, cn_len ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003571 break;
3572
Paul Bakker535e97d2012-08-23 10:49:55 +00003573 if( name->val.len > 2 &&
3574 memcmp( name->val.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003575 x509_wildcard_verify( cn, &name->val ) )
3576 break;
3577 }
3578
3579 name = name->next;
3580 }
3581
3582 if( name == NULL )
3583 *flags |= BADCERT_CN_MISMATCH;
3584 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003585 }
3586
Paul Bakker5121ce52009-01-03 21:22:43 +00003587 /*
Paul Bakker915275b2012-09-28 07:10:55 +00003588 * Iterate upwards in the given cert chain, to find our crt parent.
3589 * Ignore any upper cert with CA != TRUE.
Paul Bakker5121ce52009-01-03 21:22:43 +00003590 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003591 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003592
Paul Bakker76fd75a2011-01-16 21:12:10 +00003593 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003594 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003595 if( parent->ca_istrue == 0 ||
3596 crt->issuer_raw.len != parent->subject_raw.len ||
3597 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00003598 crt->issuer_raw.len ) != 0 )
3599 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003600 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003601 continue;
3602 }
Paul Bakker915275b2012-09-28 07:10:55 +00003603 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003604 }
3605
Paul Bakker915275b2012-09-28 07:10:55 +00003606 if( parent != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003607 {
Paul Bakker915275b2012-09-28 07:10:55 +00003608 /*
3609 * Part of the chain
3610 */
Paul Bakker9a736322012-11-14 12:39:52 +00003611 ret = x509parse_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003612 if( ret != 0 )
3613 return( ret );
3614 }
3615 else
Paul Bakker74111d32011-01-15 16:57:55 +00003616 {
Paul Bakker9a736322012-11-14 12:39:52 +00003617 ret = x509parse_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003618 if( ret != 0 )
3619 return( ret );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003620 }
Paul Bakker915275b2012-09-28 07:10:55 +00003621
3622 if( *flags != 0 )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003623 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003624
Paul Bakker5121ce52009-01-03 21:22:43 +00003625 return( 0 );
3626}
3627
3628/*
3629 * Unallocate all certificate data
3630 */
3631void x509_free( x509_cert *crt )
3632{
3633 x509_cert *cert_cur = crt;
3634 x509_cert *cert_prv;
3635 x509_name *name_cur;
3636 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00003637 x509_sequence *seq_cur;
3638 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00003639
3640 if( crt == NULL )
3641 return;
3642
3643 do
3644 {
3645 rsa_free( &cert_cur->rsa );
3646
3647 name_cur = cert_cur->issuer.next;
3648 while( name_cur != NULL )
3649 {
3650 name_prv = name_cur;
3651 name_cur = name_cur->next;
3652 memset( name_prv, 0, sizeof( x509_name ) );
3653 free( name_prv );
3654 }
3655
3656 name_cur = cert_cur->subject.next;
3657 while( name_cur != NULL )
3658 {
3659 name_prv = name_cur;
3660 name_cur = name_cur->next;
3661 memset( name_prv, 0, sizeof( x509_name ) );
3662 free( name_prv );
3663 }
3664
Paul Bakker74111d32011-01-15 16:57:55 +00003665 seq_cur = cert_cur->ext_key_usage.next;
3666 while( seq_cur != NULL )
3667 {
3668 seq_prv = seq_cur;
3669 seq_cur = seq_cur->next;
3670 memset( seq_prv, 0, sizeof( x509_sequence ) );
3671 free( seq_prv );
3672 }
3673
Paul Bakker8afa70d2012-02-11 18:42:45 +00003674 seq_cur = cert_cur->subject_alt_names.next;
3675 while( seq_cur != NULL )
3676 {
3677 seq_prv = seq_cur;
3678 seq_cur = seq_cur->next;
3679 memset( seq_prv, 0, sizeof( x509_sequence ) );
3680 free( seq_prv );
3681 }
3682
Paul Bakker5121ce52009-01-03 21:22:43 +00003683 if( cert_cur->raw.p != NULL )
3684 {
3685 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
3686 free( cert_cur->raw.p );
3687 }
3688
3689 cert_cur = cert_cur->next;
3690 }
3691 while( cert_cur != NULL );
3692
3693 cert_cur = crt;
3694 do
3695 {
3696 cert_prv = cert_cur;
3697 cert_cur = cert_cur->next;
3698
3699 memset( cert_prv, 0, sizeof( x509_cert ) );
3700 if( cert_prv != crt )
3701 free( cert_prv );
3702 }
3703 while( cert_cur != NULL );
3704}
3705
Paul Bakkerd98030e2009-05-02 15:13:40 +00003706/*
3707 * Unallocate all CRL data
3708 */
3709void x509_crl_free( x509_crl *crl )
3710{
3711 x509_crl *crl_cur = crl;
3712 x509_crl *crl_prv;
3713 x509_name *name_cur;
3714 x509_name *name_prv;
3715 x509_crl_entry *entry_cur;
3716 x509_crl_entry *entry_prv;
3717
3718 if( crl == NULL )
3719 return;
3720
3721 do
3722 {
3723 name_cur = crl_cur->issuer.next;
3724 while( name_cur != NULL )
3725 {
3726 name_prv = name_cur;
3727 name_cur = name_cur->next;
3728 memset( name_prv, 0, sizeof( x509_name ) );
3729 free( name_prv );
3730 }
3731
3732 entry_cur = crl_cur->entry.next;
3733 while( entry_cur != NULL )
3734 {
3735 entry_prv = entry_cur;
3736 entry_cur = entry_cur->next;
3737 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
3738 free( entry_prv );
3739 }
3740
3741 if( crl_cur->raw.p != NULL )
3742 {
3743 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
3744 free( crl_cur->raw.p );
3745 }
3746
3747 crl_cur = crl_cur->next;
3748 }
3749 while( crl_cur != NULL );
3750
3751 crl_cur = crl;
3752 do
3753 {
3754 crl_prv = crl_cur;
3755 crl_cur = crl_cur->next;
3756
3757 memset( crl_prv, 0, sizeof( x509_crl ) );
3758 if( crl_prv != crl )
3759 free( crl_prv );
3760 }
3761 while( crl_cur != NULL );
3762}
3763
Paul Bakker40e46942009-01-03 21:51:57 +00003764#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00003765
Paul Bakker40e46942009-01-03 21:51:57 +00003766#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00003767
3768/*
3769 * Checkup routine
3770 */
3771int x509_self_test( int verbose )
3772{
Paul Bakker5690efc2011-05-26 13:16:06 +00003773#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00003774 int ret;
3775 int flags;
3776 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00003777 x509_cert cacert;
3778 x509_cert clicert;
3779 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00003780#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003781 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00003782#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003783
3784 if( verbose != 0 )
3785 printf( " X.509 certificate load: " );
3786
3787 memset( &clicert, 0, sizeof( x509_cert ) );
3788
Paul Bakkereae09db2013-06-06 12:35:54 +02003789 ret = x509parse_crt( &clicert, (const unsigned char *) test_cli_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003790 strlen( test_cli_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003791 if( ret != 0 )
3792 {
3793 if( verbose != 0 )
3794 printf( "failed\n" );
3795
3796 return( ret );
3797 }
3798
3799 memset( &cacert, 0, sizeof( x509_cert ) );
3800
Paul Bakkereae09db2013-06-06 12:35:54 +02003801 ret = x509parse_crt( &cacert, (const unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003802 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003803 if( ret != 0 )
3804 {
3805 if( verbose != 0 )
3806 printf( "failed\n" );
3807
3808 return( ret );
3809 }
3810
3811 if( verbose != 0 )
3812 printf( "passed\n X.509 private key load: " );
3813
3814 i = strlen( test_ca_key );
3815 j = strlen( test_ca_pwd );
3816
Paul Bakker66b78b22011-03-25 14:22:50 +00003817 rsa_init( &rsa, RSA_PKCS_V15, 0 );
3818
Paul Bakker5121ce52009-01-03 21:22:43 +00003819 if( ( ret = x509parse_key( &rsa,
Paul Bakkereae09db2013-06-06 12:35:54 +02003820 (const unsigned char *) test_ca_key, i,
3821 (const unsigned char *) test_ca_pwd, j ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003822 {
3823 if( verbose != 0 )
3824 printf( "failed\n" );
3825
3826 return( ret );
3827 }
3828
3829 if( verbose != 0 )
3830 printf( "passed\n X.509 signature verify: ");
3831
Paul Bakker23986e52011-04-24 08:57:21 +00003832 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003833 if( ret != 0 )
3834 {
3835 if( verbose != 0 )
3836 printf( "failed\n" );
3837
3838 return( ret );
3839 }
3840
Paul Bakker5690efc2011-05-26 13:16:06 +00003841#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003842 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003843 printf( "passed\n X.509 DHM parameter load: " );
3844
3845 i = strlen( test_dhm_params );
3846 j = strlen( test_ca_pwd );
3847
Paul Bakkereae09db2013-06-06 12:35:54 +02003848 if( ( ret = x509parse_dhm( &dhm, (const unsigned char *) test_dhm_params, i ) ) != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003849 {
3850 if( verbose != 0 )
3851 printf( "failed\n" );
3852
3853 return( ret );
3854 }
3855
3856 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003857 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00003858#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003859
3860 x509_free( &cacert );
3861 x509_free( &clicert );
3862 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00003863#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003864 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00003865#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003866
3867 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003868#else
3869 ((void) verbose);
3870 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3871#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003872}
3873
3874#endif
3875
3876#endif