blob: 40520110a5e0462f7ffb88c7f8c36f12dda107d1 [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
1493 continue;
1494 }
1495 else
1496 break;
1497
Paul Bakkerd6d41092013-06-13 09:00:25 +02001498 ret = x509parse_crt_der( chain, pem.buf, pem.buflen );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001499
1500 pem_free( &pem );
1501
1502 if( ret != 0 )
1503 {
1504 /*
Paul Bakkerd6d41092013-06-13 09:00:25 +02001505 * Quit parsing on a memory error
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001506 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001507 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001508 return( ret );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001509
1510 if( first_error == 0 )
1511 first_error = ret;
1512
Paul Bakkerd6d41092013-06-13 09:00:25 +02001513 total_failed++;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001514 continue;
1515 }
1516
1517 success = 1;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001518 }
1519 }
1520#endif
1521
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001522 if( success )
Paul Bakker69e095c2011-12-10 21:55:01 +00001523 return( total_failed );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001524 else if( first_error )
1525 return( first_error );
1526 else
1527 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001528}
1529
1530/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001531 * Parse one or more CRLs and add them to the chained list
1532 */
Paul Bakker23986e52011-04-24 08:57:21 +00001533int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001534{
Paul Bakker23986e52011-04-24 08:57:21 +00001535 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001536 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001537 unsigned char *p, *end;
1538 x509_crl *crl;
Paul Bakker96743fc2011-02-12 14:30:57 +00001539#if defined(POLARSSL_PEM_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00001540 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001541 pem_context pem;
1542#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001543
1544 crl = chain;
1545
1546 /*
1547 * Check for valid input
1548 */
1549 if( crl == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001550 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001551
1552 while( crl->version != 0 && crl->next != NULL )
1553 crl = crl->next;
1554
1555 /*
1556 * Add new CRL on the end of the chain if needed.
1557 */
1558 if ( crl->version != 0 && crl->next == NULL)
1559 {
1560 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1561
Paul Bakker7d06ad22009-05-02 15:53:56 +00001562 if( crl->next == NULL )
1563 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001564 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001565 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001566 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001567
Paul Bakker7d06ad22009-05-02 15:53:56 +00001568 crl = crl->next;
1569 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001570 }
1571
Paul Bakker96743fc2011-02-12 14:30:57 +00001572#if defined(POLARSSL_PEM_C)
1573 pem_init( &pem );
1574 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02001575 (char *) "-----BEGIN X509 CRL-----",
1576 (char *) "-----END X509 CRL-----",
Paul Bakker96743fc2011-02-12 14:30:57 +00001577 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001578
Paul Bakker96743fc2011-02-12 14:30:57 +00001579 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001580 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001581 /*
1582 * Was PEM encoded
1583 */
1584 buflen -= use_len;
1585 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001586
1587 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001588 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001589 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001590 p = pem.buf;
1591 pem.buf = NULL;
1592 len = pem.buflen;
1593 pem_free( &pem );
1594 }
Paul Bakker9255e832013-06-06 14:58:28 +02001595 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker96743fc2011-02-12 14:30:57 +00001596 {
1597 pem_free( &pem );
1598 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001599 }
1600 else
1601 {
1602 /*
1603 * nope, copy the raw DER data
1604 */
1605 p = (unsigned char *) malloc( len = buflen );
1606
1607 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001608 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001609
1610 memcpy( p, buf, buflen );
1611
1612 buflen = 0;
1613 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001614#else
1615 p = (unsigned char *) malloc( len = buflen );
1616
1617 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001618 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001619
1620 memcpy( p, buf, buflen );
1621
1622 buflen = 0;
1623#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001624
1625 crl->raw.p = p;
1626 crl->raw.len = len;
1627 end = p + len;
1628
1629 /*
1630 * CertificateList ::= SEQUENCE {
1631 * tbsCertList TBSCertList,
1632 * signatureAlgorithm AlgorithmIdentifier,
1633 * signatureValue BIT STRING }
1634 */
1635 if( ( ret = asn1_get_tag( &p, end, &len,
1636 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1637 {
1638 x509_crl_free( crl );
1639 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1640 }
1641
Paul Bakker23986e52011-04-24 08:57:21 +00001642 if( len != (size_t) ( end - p ) )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001643 {
1644 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001645 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001646 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1647 }
1648
1649 /*
1650 * TBSCertList ::= SEQUENCE {
1651 */
1652 crl->tbs.p = p;
1653
1654 if( ( ret = asn1_get_tag( &p, end, &len,
1655 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1656 {
1657 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001658 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001659 }
1660
1661 end = p + len;
1662 crl->tbs.len = end - crl->tbs.p;
1663
1664 /*
1665 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1666 * -- if present, MUST be v2
1667 *
1668 * signature AlgorithmIdentifier
1669 */
Paul Bakker3329d1f2011-10-12 09:55:01 +00001670 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
Paul Bakkerd98030e2009-05-02 15:13:40 +00001671 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1672 {
1673 x509_crl_free( crl );
1674 return( ret );
1675 }
1676
1677 crl->version++;
1678
1679 if( crl->version > 2 )
1680 {
1681 x509_crl_free( crl );
1682 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1683 }
1684
Paul Bakker27d66162010-03-17 06:56:01 +00001685 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_alg ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001686 {
1687 x509_crl_free( crl );
1688 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1689 }
1690
1691 /*
1692 * issuer Name
1693 */
1694 crl->issuer_raw.p = p;
1695
1696 if( ( ret = asn1_get_tag( &p, end, &len,
1697 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1698 {
1699 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001700 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001701 }
1702
1703 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1704 {
1705 x509_crl_free( crl );
1706 return( ret );
1707 }
1708
1709 crl->issuer_raw.len = p - crl->issuer_raw.p;
1710
1711 /*
1712 * thisUpdate Time
1713 * nextUpdate Time OPTIONAL
1714 */
Paul Bakker91200182010-02-18 21:26:15 +00001715 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001716 {
1717 x509_crl_free( crl );
1718 return( ret );
1719 }
1720
Paul Bakker91200182010-02-18 21:26:15 +00001721 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001722 {
Paul Bakker9d781402011-05-09 16:17:09 +00001723 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001724 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker9d781402011-05-09 16:17:09 +00001725 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001726 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001727 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001728 x509_crl_free( crl );
1729 return( ret );
1730 }
1731 }
1732
1733 /*
1734 * revokedCertificates SEQUENCE OF SEQUENCE {
1735 * userCertificate CertificateSerialNumber,
1736 * revocationDate Time,
1737 * crlEntryExtensions Extensions OPTIONAL
1738 * -- if present, MUST be v2
1739 * } OPTIONAL
1740 */
1741 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1742 {
1743 x509_crl_free( crl );
1744 return( ret );
1745 }
1746
1747 /*
1748 * crlExtensions EXPLICIT Extensions OPTIONAL
1749 * -- if present, MUST be v2
1750 */
1751 if( crl->version == 2 )
1752 {
1753 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1754
1755 if( ret != 0 )
1756 {
1757 x509_crl_free( crl );
1758 return( ret );
1759 }
1760 }
1761
1762 if( p != end )
1763 {
1764 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001765 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001766 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1767 }
1768
1769 end = crl->raw.p + crl->raw.len;
1770
1771 /*
1772 * signatureAlgorithm AlgorithmIdentifier,
1773 * signatureValue BIT STRING
1774 */
1775 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1776 {
1777 x509_crl_free( crl );
1778 return( ret );
1779 }
1780
Paul Bakker535e97d2012-08-23 10:49:55 +00001781 if( crl->sig_oid1.len != crl->sig_oid2.len ||
1782 memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001783 {
1784 x509_crl_free( crl );
1785 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1786 }
1787
1788 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1789 {
1790 x509_crl_free( crl );
1791 return( ret );
1792 }
1793
1794 if( p != end )
1795 {
1796 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001797 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001798 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1799 }
1800
1801 if( buflen > 0 )
1802 {
1803 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1804
Paul Bakker7d06ad22009-05-02 15:53:56 +00001805 if( crl->next == NULL )
1806 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001807 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001808 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001809 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001810
Paul Bakker7d06ad22009-05-02 15:53:56 +00001811 crl = crl->next;
1812 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001813
1814 return( x509parse_crl( crl, buf, buflen ) );
1815 }
1816
1817 return( 0 );
1818}
1819
Paul Bakker335db3f2011-04-25 15:28:35 +00001820#if defined(POLARSSL_FS_IO)
Paul Bakkerd98030e2009-05-02 15:13:40 +00001821/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001822 * Load all data from a file into a given buffer.
1823 */
Paul Bakker1d073c52014-07-08 20:15:51 +02001824static int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001825{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001826 FILE *f;
Paul Bakkerfe7c24c2013-09-11 11:37:33 +02001827 long size;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001828
Paul Bakkerd98030e2009-05-02 15:13:40 +00001829 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001830 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001831
Paul Bakkerd98030e2009-05-02 15:13:40 +00001832 fseek( f, 0, SEEK_END );
Paul Bakkerfe7c24c2013-09-11 11:37:33 +02001833 if( ( size = ftell( f ) ) == -1 )
1834 {
1835 fclose( f );
1836 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1837 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001838 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001839
Paul Bakkerfe7c24c2013-09-11 11:37:33 +02001840 *n = (size_t) size;
1841
1842 if( *n + 1 == 0 ||
1843 ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
1844 {
1845 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +00001846 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerfe7c24c2013-09-11 11:37:33 +02001847 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001848
Paul Bakkerd98030e2009-05-02 15:13:40 +00001849 if( fread( *buf, 1, *n, f ) != *n )
1850 {
1851 fclose( f );
1852 free( *buf );
Paul Bakker69e095c2011-12-10 21:55:01 +00001853 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001854 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001855
Paul Bakkerd98030e2009-05-02 15:13:40 +00001856 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001857
Paul Bakkerd98030e2009-05-02 15:13:40 +00001858 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001859
Paul Bakkerd98030e2009-05-02 15:13:40 +00001860 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001861}
1862
1863/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001864 * Load one or more certificates and add them to the chained list
1865 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001866int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001867{
1868 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001869 size_t n;
1870 unsigned char *buf;
1871
Paul Bakker69e095c2011-12-10 21:55:01 +00001872 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1873 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001874
Paul Bakker69e095c2011-12-10 21:55:01 +00001875 ret = x509parse_crt( chain, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001876
1877 memset( buf, 0, n + 1 );
1878 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001879
1880 return( ret );
1881}
1882
Paul Bakker8d914582012-06-04 12:46:42 +00001883int x509parse_crtpath( x509_cert *chain, const char *path )
1884{
1885 int ret = 0;
1886#if defined(_WIN32)
Paul Bakker3338b792012-10-01 21:13:10 +00001887 int w_ret;
1888 WCHAR szDir[MAX_PATH];
1889 char filename[MAX_PATH];
1890 char *p;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001891 int len = strlen( path );
Paul Bakker3338b792012-10-01 21:13:10 +00001892
Paul Bakker97872ac2012-11-02 12:53:26 +00001893 WIN32_FIND_DATAW file_data;
Paul Bakker8d914582012-06-04 12:46:42 +00001894 HANDLE hFind;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001895
1896 if( len > MAX_PATH - 3 )
1897 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker8d914582012-06-04 12:46:42 +00001898
Paul Bakker3338b792012-10-01 21:13:10 +00001899 memset( szDir, 0, sizeof(szDir) );
1900 memset( filename, 0, MAX_PATH );
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001901 memcpy( filename, path, len );
1902 filename[len++] = '\\';
1903 p = filename + len;
1904 filename[len++] = '*';
Paul Bakker3338b792012-10-01 21:13:10 +00001905
Paul Bakker40cc9142014-07-07 15:16:47 +02001906 w_ret = MultiByteToWideChar( CP_ACP, 0, filename, len, szDir, MAX_PATH - 3 );
Paul Bakker8d914582012-06-04 12:46:42 +00001907
Paul Bakker97872ac2012-11-02 12:53:26 +00001908 hFind = FindFirstFileW( szDir, &file_data );
Paul Bakker8d914582012-06-04 12:46:42 +00001909 if (hFind == INVALID_HANDLE_VALUE)
1910 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1911
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001912 len = MAX_PATH - len;
Paul Bakker8d914582012-06-04 12:46:42 +00001913 do
1914 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001915 memset( p, 0, len );
Paul Bakker3338b792012-10-01 21:13:10 +00001916
Paul Bakkere4791f32012-06-04 21:29:15 +00001917 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
Paul Bakker8d914582012-06-04 12:46:42 +00001918 continue;
1919
Paul Bakker3338b792012-10-01 21:13:10 +00001920 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
1921 lstrlenW(file_data.cFileName),
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001922 p, len - 1,
1923 NULL, NULL );
Paul Bakker8d914582012-06-04 12:46:42 +00001924
Paul Bakker3338b792012-10-01 21:13:10 +00001925 w_ret = x509parse_crtfile( chain, filename );
1926 if( w_ret < 0 )
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001927 ret++;
1928 else
1929 ret += w_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001930 }
Paul Bakker97872ac2012-11-02 12:53:26 +00001931 while( FindNextFileW( hFind, &file_data ) != 0 );
Paul Bakker8d914582012-06-04 12:46:42 +00001932
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001933 if (GetLastError() != ERROR_NO_MORE_FILES)
1934 ret = POLARSSL_ERR_X509_FILE_IO_ERROR;
Paul Bakker8d914582012-06-04 12:46:42 +00001935
1936 FindClose( hFind );
1937#else
Paul Bakker9ccb2112014-07-07 13:43:31 +02001938#if defined(POLARSSL_HAVE_READDIR_R)
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001939 int t_ret, i;
1940 struct stat sb;
1941 struct dirent entry, *result = NULL;
Paul Bakker8d914582012-06-04 12:46:42 +00001942 char entry_name[255];
1943 DIR *dir = opendir( path );
1944
1945 if( dir == NULL)
1946 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1947
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001948 while( ( t_ret = readdir_r( dir, &entry, &result ) ) == 0 )
Paul Bakker8d914582012-06-04 12:46:42 +00001949 {
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001950 if( result == NULL )
1951 break;
1952
1953 snprintf( entry_name, sizeof(entry_name), "%s/%s", path, entry.d_name );
1954
1955 i = stat( entry_name, &sb );
1956
1957 if( i == -1 )
Paul Bakker88a22642013-09-11 12:14:16 +02001958 {
1959 closedir( dir );
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001960 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker88a22642013-09-11 12:14:16 +02001961 }
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001962
1963 if( !S_ISREG( sb.st_mode ) )
Paul Bakker8d914582012-06-04 12:46:42 +00001964 continue;
1965
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001966 // Ignore parse errors
1967 //
Paul Bakker8d914582012-06-04 12:46:42 +00001968 t_ret = x509parse_crtfile( chain, entry_name );
1969 if( t_ret < 0 )
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001970 ret++;
1971 else
1972 ret += t_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001973 }
1974 closedir( dir );
Paul Bakker9ccb2112014-07-07 13:43:31 +02001975#else /* POLARSSL_HAVE_READDIR_R */
1976 ((void) chain);
1977 ((void) path);
1978 ret = POLARSSL_ERR_X509_FEATURE_UNAVAILABLE;
1979#endif /* POLARSSL_HAVE_READDIR_R */
1980#endif /* _WIN32 */
Paul Bakker8d914582012-06-04 12:46:42 +00001981
1982 return( ret );
1983}
1984
Paul Bakkerd98030e2009-05-02 15:13:40 +00001985/*
1986 * Load one or more CRLs and add them to the chained list
1987 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001988int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001989{
1990 int ret;
1991 size_t n;
1992 unsigned char *buf;
1993
Paul Bakker69e095c2011-12-10 21:55:01 +00001994 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1995 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001996
Paul Bakker27fdf462011-06-09 13:55:13 +00001997 ret = x509parse_crl( chain, buf, n );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001998
1999 memset( buf, 0, n + 1 );
2000 free( buf );
2001
2002 return( ret );
2003}
2004
Paul Bakker5121ce52009-01-03 21:22:43 +00002005/*
Paul Bakker335db3f2011-04-25 15:28:35 +00002006 * Load and parse a private RSA key
2007 */
2008int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
2009{
2010 int ret;
2011 size_t n;
2012 unsigned char *buf;
2013
Paul Bakker69e095c2011-12-10 21:55:01 +00002014 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2015 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002016
2017 if( pwd == NULL )
Paul Bakker27fdf462011-06-09 13:55:13 +00002018 ret = x509parse_key( rsa, buf, n, NULL, 0 );
Paul Bakker335db3f2011-04-25 15:28:35 +00002019 else
Paul Bakker27fdf462011-06-09 13:55:13 +00002020 ret = x509parse_key( rsa, buf, n,
Paul Bakker335db3f2011-04-25 15:28:35 +00002021 (unsigned char *) pwd, strlen( pwd ) );
2022
2023 memset( buf, 0, n + 1 );
2024 free( buf );
2025
2026 return( ret );
2027}
2028
2029/*
2030 * Load and parse a public RSA key
2031 */
2032int x509parse_public_keyfile( rsa_context *rsa, const char *path )
2033{
2034 int ret;
2035 size_t n;
2036 unsigned char *buf;
2037
Paul Bakker69e095c2011-12-10 21:55:01 +00002038 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2039 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002040
Paul Bakker27fdf462011-06-09 13:55:13 +00002041 ret = x509parse_public_key( rsa, buf, n );
Paul Bakker335db3f2011-04-25 15:28:35 +00002042
2043 memset( buf, 0, n + 1 );
2044 free( buf );
2045
2046 return( ret );
2047}
2048#endif /* POLARSSL_FS_IO */
2049
2050/*
Paul Bakker65a19092013-06-06 21:14:58 +02002051 * Parse a PKCS#1 encoded private RSA key
Paul Bakker5121ce52009-01-03 21:22:43 +00002052 */
Paul Bakker65a19092013-06-06 21:14:58 +02002053static int x509parse_key_pkcs1_der( rsa_context *rsa,
2054 const unsigned char *key,
2055 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +00002056{
Paul Bakker23986e52011-04-24 08:57:21 +00002057 int ret;
2058 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00002059 unsigned char *p, *end;
Paul Bakkered56b222011-07-13 11:26:43 +00002060
Paul Bakker96743fc2011-02-12 14:30:57 +00002061 p = (unsigned char *) key;
Paul Bakker96743fc2011-02-12 14:30:57 +00002062 end = p + keylen;
2063
Paul Bakker5121ce52009-01-03 21:22:43 +00002064 /*
Paul Bakker65a19092013-06-06 21:14:58 +02002065 * This function parses the RSAPrivateKey (PKCS#1)
Paul Bakkered56b222011-07-13 11:26:43 +00002066 *
Paul Bakker5121ce52009-01-03 21:22:43 +00002067 * RSAPrivateKey ::= SEQUENCE {
2068 * version Version,
2069 * modulus INTEGER, -- n
2070 * publicExponent INTEGER, -- e
2071 * privateExponent INTEGER, -- d
2072 * prime1 INTEGER, -- p
2073 * prime2 INTEGER, -- q
2074 * exponent1 INTEGER, -- d mod (p-1)
2075 * exponent2 INTEGER, -- d mod (q-1)
2076 * coefficient INTEGER, -- (inverse of q) mod p
2077 * otherPrimeInfos OtherPrimeInfos OPTIONAL
2078 * }
2079 */
2080 if( ( ret = asn1_get_tag( &p, end, &len,
2081 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2082 {
Paul Bakker9d781402011-05-09 16:17:09 +00002083 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002084 }
2085
2086 end = p + len;
2087
2088 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2089 {
Paul Bakker9d781402011-05-09 16:17:09 +00002090 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002091 }
2092
2093 if( rsa->ver != 0 )
2094 {
Paul Bakker9d781402011-05-09 16:17:09 +00002095 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002096 }
2097
2098 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
2099 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
2100 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
2101 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
2102 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
2103 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
2104 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
2105 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
2106 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002107 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002108 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002109 }
2110
2111 rsa->len = mpi_size( &rsa->N );
2112
2113 if( p != end )
2114 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002115 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002116 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00002117 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002118 }
2119
2120 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2121 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002122 rsa_free( rsa );
2123 return( ret );
2124 }
2125
Paul Bakker65a19092013-06-06 21:14:58 +02002126 return( 0 );
2127}
2128
2129/*
2130 * Parse an unencrypted PKCS#8 encoded private RSA key
2131 */
2132static int x509parse_key_pkcs8_unencrypted_der(
2133 rsa_context *rsa,
2134 const unsigned char *key,
2135 size_t keylen )
2136{
2137 int ret;
2138 size_t len;
2139 unsigned char *p, *end;
2140 x509_buf pk_alg_oid;
2141
2142 p = (unsigned char *) key;
2143 end = p + keylen;
2144
2145 /*
2146 * This function parses the PrivatKeyInfo object (PKCS#8)
2147 *
2148 * PrivateKeyInfo ::= SEQUENCE {
2149 * version Version,
2150 * algorithm AlgorithmIdentifier,
2151 * PrivateKey BIT STRING
2152 * }
2153 *
2154 * AlgorithmIdentifier ::= SEQUENCE {
2155 * algorithm OBJECT IDENTIFIER,
2156 * parameters ANY DEFINED BY algorithm OPTIONAL
2157 * }
2158 *
2159 * The PrivateKey BIT STRING is a PKCS#1 RSAPrivateKey
2160 */
2161 if( ( ret = asn1_get_tag( &p, end, &len,
2162 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2163 {
2164 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2165 }
2166
2167 end = p + len;
2168
2169 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2170 {
2171 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2172 }
2173
2174 if( rsa->ver != 0 )
2175 {
2176 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2177 }
2178
2179 if( ( ret = x509_get_alg( &p, end, &pk_alg_oid ) ) != 0 )
2180 {
2181 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2182 }
2183
2184 /*
2185 * only RSA keys handled at this time
2186 */
2187 if( pk_alg_oid.len != 9 ||
2188 memcmp( pk_alg_oid.p, OID_PKCS1_RSA, 9 ) != 0 )
2189 {
2190 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
2191 }
2192
2193 /*
2194 * Get the OCTET STRING and parse the PKCS#1 format inside
2195 */
2196 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2197 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2198
2199 if( ( end - p ) < 1 )
2200 {
2201 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
2202 POLARSSL_ERR_ASN1_OUT_OF_DATA );
2203 }
2204
2205 end = p + len;
2206
2207 if( ( ret = x509parse_key_pkcs1_der( rsa, p, end - p ) ) != 0 )
2208 return( ret );
2209
2210 return( 0 );
2211}
2212
2213/*
Paul Bakkerda7fdbd2013-06-19 11:15:43 +02002214 * Parse an encrypted PKCS#8 encoded private RSA key
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002215 */
2216static int x509parse_key_pkcs8_encrypted_der(
2217 rsa_context *rsa,
2218 const unsigned char *key,
2219 size_t keylen,
2220 const unsigned char *pwd,
2221 size_t pwdlen )
2222{
2223 int ret;
2224 size_t len;
2225 unsigned char *p, *end, *end2;
2226 x509_buf pbe_alg_oid, pbe_params;
2227 unsigned char buf[2048];
2228
2229 memset(buf, 0, 2048);
2230
2231 p = (unsigned char *) key;
2232 end = p + keylen;
2233
Paul Bakker1fd43212013-06-17 15:14:42 +02002234 if( pwdlen == 0 )
2235 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
2236
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002237 /*
2238 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
2239 *
2240 * EncryptedPrivateKeyInfo ::= SEQUENCE {
2241 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
2242 * encryptedData EncryptedData
2243 * }
2244 *
2245 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
2246 *
2247 * EncryptedData ::= OCTET STRING
2248 *
2249 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
2250 */
2251 if( ( ret = asn1_get_tag( &p, end, &len,
2252 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2253 {
2254 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2255 }
2256
2257 end = p + len;
2258
2259 if( ( ret = asn1_get_tag( &p, end, &len,
2260 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2261 {
2262 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2263 }
2264
2265 end2 = p + len;
2266
2267 if( ( ret = asn1_get_tag( &p, end, &pbe_alg_oid.len, ASN1_OID ) ) != 0 )
2268 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2269
2270 pbe_alg_oid.p = p;
2271 p += pbe_alg_oid.len;
2272
2273 /*
2274 * Store the algorithm parameters
2275 */
2276 pbe_params.p = p;
2277 pbe_params.len = end2 - p;
2278 p += pbe_params.len;
2279
2280 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2281 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2282
2283 // buf has been sized to 2048 bytes
2284 if( len > 2048 )
2285 return( POLARSSL_ERR_X509_INVALID_INPUT );
2286
2287 /*
2288 * Decrypt EncryptedData with appropriate PDE
2289 */
Paul Bakker14a222c2013-06-18 16:35:48 +02002290#if defined(POLARSSL_PKCS12_C)
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002291 if( OID_CMP( OID_PKCS12_PBE_SHA1_DES3_EDE_CBC, &pbe_alg_oid ) )
2292 {
Paul Bakker14a222c2013-06-18 16:35:48 +02002293 if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
2294 POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1,
2295 pwd, pwdlen, p, len, buf ) ) != 0 )
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002296 {
Paul Bakker14a222c2013-06-18 16:35:48 +02002297 if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH )
2298 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2299
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002300 return( ret );
2301 }
2302 }
2303 else if( OID_CMP( OID_PKCS12_PBE_SHA1_DES2_EDE_CBC, &pbe_alg_oid ) )
2304 {
Paul Bakker14a222c2013-06-18 16:35:48 +02002305 if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
2306 POLARSSL_CIPHER_DES_EDE_CBC, POLARSSL_MD_SHA1,
2307 pwd, pwdlen, p, len, buf ) ) != 0 )
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002308 {
Paul Bakker14a222c2013-06-18 16:35:48 +02002309 if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH )
2310 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2311
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002312 return( ret );
2313 }
2314 }
2315 else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) )
2316 {
2317 if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params,
2318 PKCS12_PBE_DECRYPT,
2319 pwd, pwdlen,
2320 p, len, buf ) ) != 0 )
2321 {
2322 return( ret );
2323 }
Paul Bakker14a222c2013-06-18 16:35:48 +02002324
2325 // Best guess for password mismatch when using RC4. If first tag is
2326 // not ASN1_CONSTRUCTED | ASN1_SEQUENCE
2327 //
2328 if( *buf != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
2329 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002330 }
Paul Bakker14a222c2013-06-18 16:35:48 +02002331 else
2332#endif /* POLARSSL_PKCS12_C */
Paul Bakker1fd43212013-06-17 15:14:42 +02002333#if defined(POLARSSL_PKCS5_C)
Paul Bakker14a222c2013-06-18 16:35:48 +02002334 if( OID_CMP( OID_PKCS5_PBES2, &pbe_alg_oid ) )
Paul Bakker1fd43212013-06-17 15:14:42 +02002335 {
2336 if( ( ret = pkcs5_pbes2( &pbe_params, PKCS5_DECRYPT, pwd, pwdlen,
2337 p, len, buf ) ) != 0 )
2338 {
2339 if( ret == POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH )
2340 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2341
2342 return( ret );
2343 }
2344 }
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002345 else
Paul Bakker14a222c2013-06-18 16:35:48 +02002346#endif /* POLARSSL_PKCS5_C */
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002347 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
2348
2349 return x509parse_key_pkcs8_unencrypted_der( rsa, buf, len );
2350}
2351
2352/*
Paul Bakker65a19092013-06-06 21:14:58 +02002353 * Parse a private RSA key
2354 */
2355int x509parse_key( rsa_context *rsa, const unsigned char *key, size_t keylen,
2356 const unsigned char *pwd, size_t pwdlen )
2357{
2358 int ret;
2359
Paul Bakker96743fc2011-02-12 14:30:57 +00002360#if defined(POLARSSL_PEM_C)
Paul Bakker65a19092013-06-06 21:14:58 +02002361 size_t len;
2362 pem_context pem;
2363
2364 pem_init( &pem );
2365 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02002366 (char *) "-----BEGIN RSA PRIVATE KEY-----",
2367 (char *) "-----END RSA PRIVATE KEY-----",
Paul Bakker65a19092013-06-06 21:14:58 +02002368 key, pwd, pwdlen, &len );
2369 if( ret == 0 )
2370 {
2371 if( ( ret = x509parse_key_pkcs1_der( rsa, pem.buf, pem.buflen ) ) != 0 )
2372 {
2373 rsa_free( rsa );
2374 }
2375
2376 pem_free( &pem );
2377 return( ret );
2378 }
Paul Bakkerb495d3a2013-06-17 15:58:04 +02002379 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
2380 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2381 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
2382 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
Paul Bakker65a19092013-06-06 21:14:58 +02002383 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker65a19092013-06-06 21:14:58 +02002384 return( ret );
Paul Bakker65a19092013-06-06 21:14:58 +02002385
2386 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02002387 (char *) "-----BEGIN PRIVATE KEY-----",
2388 (char *) "-----END PRIVATE KEY-----",
Paul Bakker65a19092013-06-06 21:14:58 +02002389 key, NULL, 0, &len );
2390 if( ret == 0 )
2391 {
2392 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa,
2393 pem.buf, pem.buflen ) ) != 0 )
2394 {
2395 rsa_free( rsa );
2396 }
2397
2398 pem_free( &pem );
2399 return( ret );
2400 }
2401 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker65a19092013-06-06 21:14:58 +02002402 return( ret );
Paul Bakker65a19092013-06-06 21:14:58 +02002403
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002404 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02002405 (char *) "-----BEGIN ENCRYPTED PRIVATE KEY-----",
2406 (char *) "-----END ENCRYPTED PRIVATE KEY-----",
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002407 key, NULL, 0, &len );
2408 if( ret == 0 )
2409 {
2410 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa,
2411 pem.buf, pem.buflen,
2412 pwd, pwdlen ) ) != 0 )
2413 {
2414 rsa_free( rsa );
2415 }
2416
2417 pem_free( &pem );
2418 return( ret );
2419 }
2420 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002421 return( ret );
Paul Bakker65a19092013-06-06 21:14:58 +02002422#else
2423 ((void) pwd);
2424 ((void) pwdlen);
2425#endif /* POLARSSL_PEM_C */
2426
2427 // At this point we only know it's not a PEM formatted key. Could be any
2428 // of the known DER encoded private key formats
2429 //
2430 // We try the different DER format parsers to see if one passes without
2431 // error
2432 //
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002433 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa, key, keylen,
2434 pwd, pwdlen ) ) == 0 )
Paul Bakker65a19092013-06-06 21:14:58 +02002435 {
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002436 return( 0 );
Paul Bakker65a19092013-06-06 21:14:58 +02002437 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002438
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002439 rsa_free( rsa );
Paul Bakker1fd43212013-06-17 15:14:42 +02002440
2441 if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH )
2442 {
2443 return( ret );
2444 }
2445
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002446 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa, key, keylen ) ) == 0 )
2447 return( 0 );
2448
2449 rsa_free( rsa );
Paul Bakker1fd43212013-06-17 15:14:42 +02002450
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002451 if( ( ret = x509parse_key_pkcs1_der( rsa, key, keylen ) ) == 0 )
2452 return( 0 );
2453
2454 rsa_free( rsa );
Paul Bakker1fd43212013-06-17 15:14:42 +02002455
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002456 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00002457}
2458
2459/*
Paul Bakker53019ae2011-03-25 13:58:48 +00002460 * Parse a public RSA key
2461 */
Paul Bakker23986e52011-04-24 08:57:21 +00002462int x509parse_public_key( rsa_context *rsa, const unsigned char *key, size_t keylen )
Paul Bakker53019ae2011-03-25 13:58:48 +00002463{
Paul Bakker23986e52011-04-24 08:57:21 +00002464 int ret;
2465 size_t len;
Paul Bakker53019ae2011-03-25 13:58:48 +00002466 unsigned char *p, *end;
2467 x509_buf alg_oid;
2468#if defined(POLARSSL_PEM_C)
2469 pem_context pem;
2470
2471 pem_init( &pem );
2472 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02002473 (char *) "-----BEGIN PUBLIC KEY-----",
2474 (char *) "-----END PUBLIC KEY-----",
Paul Bakker53019ae2011-03-25 13:58:48 +00002475 key, NULL, 0, &len );
2476
2477 if( ret == 0 )
2478 {
2479 /*
2480 * Was PEM encoded
2481 */
2482 keylen = pem.buflen;
2483 }
Paul Bakker9255e832013-06-06 14:58:28 +02002484 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker53019ae2011-03-25 13:58:48 +00002485 {
2486 pem_free( &pem );
2487 return( ret );
2488 }
2489
2490 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2491#else
2492 p = (unsigned char *) key;
2493#endif
2494 end = p + keylen;
2495
2496 /*
2497 * PublicKeyInfo ::= SEQUENCE {
2498 * algorithm AlgorithmIdentifier,
2499 * PublicKey BIT STRING
2500 * }
2501 *
2502 * AlgorithmIdentifier ::= SEQUENCE {
2503 * algorithm OBJECT IDENTIFIER,
2504 * parameters ANY DEFINED BY algorithm OPTIONAL
2505 * }
2506 *
2507 * RSAPublicKey ::= SEQUENCE {
2508 * modulus INTEGER, -- n
2509 * publicExponent INTEGER -- e
2510 * }
2511 */
2512
2513 if( ( ret = asn1_get_tag( &p, end, &len,
2514 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2515 {
2516#if defined(POLARSSL_PEM_C)
2517 pem_free( &pem );
2518#endif
2519 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002520 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002521 }
2522
2523 if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
2524 {
2525#if defined(POLARSSL_PEM_C)
2526 pem_free( &pem );
2527#endif
2528 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002529 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002530 }
2531
2532 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
2533 {
2534#if defined(POLARSSL_PEM_C)
2535 pem_free( &pem );
2536#endif
2537 rsa_free( rsa );
2538 return( ret );
2539 }
2540
2541 rsa->len = mpi_size( &rsa->N );
2542
2543#if defined(POLARSSL_PEM_C)
2544 pem_free( &pem );
2545#endif
2546
2547 return( 0 );
2548}
2549
Paul Bakkereaa89f82011-04-04 21:36:15 +00002550#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00002551/*
Paul Bakker1b57b062011-01-06 15:48:19 +00002552 * Parse DHM parameters
2553 */
Paul Bakker23986e52011-04-24 08:57:21 +00002554int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
Paul Bakker1b57b062011-01-06 15:48:19 +00002555{
Paul Bakker23986e52011-04-24 08:57:21 +00002556 int ret;
2557 size_t len;
Paul Bakker1b57b062011-01-06 15:48:19 +00002558 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00002559#if defined(POLARSSL_PEM_C)
2560 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00002561
Paul Bakker96743fc2011-02-12 14:30:57 +00002562 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00002563
Paul Bakker96743fc2011-02-12 14:30:57 +00002564 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02002565 (char *) "-----BEGIN DH PARAMETERS-----",
2566 (char *) "-----END DH PARAMETERS-----",
Paul Bakker96743fc2011-02-12 14:30:57 +00002567 dhmin, NULL, 0, &dhminlen );
2568
2569 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00002570 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002571 /*
2572 * Was PEM encoded
2573 */
2574 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00002575 }
Paul Bakker9255e832013-06-06 14:58:28 +02002576 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00002577 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002578 pem_free( &pem );
2579 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002580 }
2581
Paul Bakker96743fc2011-02-12 14:30:57 +00002582 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
2583#else
2584 p = (unsigned char *) dhmin;
2585#endif
2586 end = p + dhminlen;
2587
Paul Bakker1b57b062011-01-06 15:48:19 +00002588 memset( dhm, 0, sizeof( dhm_context ) );
2589
Paul Bakker1b57b062011-01-06 15:48:19 +00002590 /*
2591 * DHParams ::= SEQUENCE {
2592 * prime INTEGER, -- P
2593 * generator INTEGER, -- g
2594 * }
2595 */
2596 if( ( ret = asn1_get_tag( &p, end, &len,
2597 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2598 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002599#if defined(POLARSSL_PEM_C)
2600 pem_free( &pem );
2601#endif
Paul Bakker9d781402011-05-09 16:17:09 +00002602 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002603 }
2604
2605 end = p + len;
2606
2607 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
2608 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
2609 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002610#if defined(POLARSSL_PEM_C)
2611 pem_free( &pem );
2612#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002613 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002614 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002615 }
2616
2617 if( p != end )
2618 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002619#if defined(POLARSSL_PEM_C)
2620 pem_free( &pem );
2621#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002622 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002623 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker1b57b062011-01-06 15:48:19 +00002624 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
2625 }
2626
Paul Bakker96743fc2011-02-12 14:30:57 +00002627#if defined(POLARSSL_PEM_C)
2628 pem_free( &pem );
2629#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002630
2631 return( 0 );
2632}
2633
Paul Bakker335db3f2011-04-25 15:28:35 +00002634#if defined(POLARSSL_FS_IO)
Paul Bakker1b57b062011-01-06 15:48:19 +00002635/*
2636 * Load and parse a private RSA key
2637 */
2638int x509parse_dhmfile( dhm_context *dhm, const char *path )
2639{
2640 int ret;
2641 size_t n;
2642 unsigned char *buf;
2643
Paul Bakker69e095c2011-12-10 21:55:01 +00002644 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
2645 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002646
Paul Bakker27fdf462011-06-09 13:55:13 +00002647 ret = x509parse_dhm( dhm, buf, n );
Paul Bakker1b57b062011-01-06 15:48:19 +00002648
2649 memset( buf, 0, n + 1 );
2650 free( buf );
2651
2652 return( ret );
2653}
Paul Bakker335db3f2011-04-25 15:28:35 +00002654#endif /* POLARSSL_FS_IO */
Paul Bakkereaa89f82011-04-04 21:36:15 +00002655#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00002656
Paul Bakker5121ce52009-01-03 21:22:43 +00002657#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002658#include <stdarg.h>
2659
2660#if !defined vsnprintf
2661#define vsnprintf _vsnprintf
2662#endif // vsnprintf
2663
2664/*
2665 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2666 * Result value is not size of buffer needed, but -1 if no fit is possible.
2667 *
2668 * This fuction tries to 'fix' this by at least suggesting enlarging the
2669 * size by 20.
2670 */
2671int compat_snprintf(char *str, size_t size, const char *format, ...)
2672{
2673 va_list ap;
2674 int res = -1;
2675
2676 va_start( ap, format );
2677
2678 res = vsnprintf( str, size, format, ap );
2679
2680 va_end( ap );
2681
2682 // No quick fix possible
2683 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00002684 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002685
2686 return res;
2687}
2688
2689#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002690#endif
2691
Paul Bakkerd98030e2009-05-02 15:13:40 +00002692#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2693
2694#define SAFE_SNPRINTF() \
2695{ \
2696 if( ret == -1 ) \
2697 return( -1 ); \
2698 \
Paul Bakker23986e52011-04-24 08:57:21 +00002699 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002700 p[n - 1] = '\0'; \
2701 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2702 } \
2703 \
Paul Bakker23986e52011-04-24 08:57:21 +00002704 n -= (unsigned int) ret; \
2705 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002706}
2707
Paul Bakker5121ce52009-01-03 21:22:43 +00002708/*
2709 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002710 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002711 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002712int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002713{
Paul Bakker23986e52011-04-24 08:57:21 +00002714 int ret;
2715 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002716 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002717 const x509_name *name;
Paul Bakker5121ce52009-01-03 21:22:43 +00002718 char s[128], *p;
2719
2720 memset( s, 0, sizeof( s ) );
2721
2722 name = dn;
2723 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002724 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002725
2726 while( name != NULL )
2727 {
Paul Bakkercefb3962012-06-27 11:51:09 +00002728 if( !name->oid.p )
2729 {
2730 name = name->next;
2731 continue;
2732 }
2733
Paul Bakker74111d32011-01-15 16:57:55 +00002734 if( name != dn )
2735 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002736 ret = snprintf( p, n, ", " );
2737 SAFE_SNPRINTF();
2738 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002739
Paul Bakker535e97d2012-08-23 10:49:55 +00002740 if( name->oid.len == 3 &&
2741 memcmp( name->oid.p, OID_X520, 2 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002742 {
2743 switch( name->oid.p[2] )
2744 {
2745 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002746 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002747
2748 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002749 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002750
2751 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002752 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002753
2754 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002755 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002756
2757 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002758 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002759
2760 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002761 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002762
2763 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002764 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002765 name->oid.p[2] );
2766 break;
2767 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002768 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002769 }
Paul Bakker535e97d2012-08-23 10:49:55 +00002770 else if( name->oid.len == 9 &&
2771 memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002772 {
2773 switch( name->oid.p[8] )
2774 {
2775 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002776 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002777
2778 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002779 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002780 name->oid.p[8] );
2781 break;
2782 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002783 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002784 }
2785 else
Paul Bakker74111d32011-01-15 16:57:55 +00002786 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002787 ret = snprintf( p, n, "\?\?=" );
Paul Bakker74111d32011-01-15 16:57:55 +00002788 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002789 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002790
2791 for( i = 0; i < name->val.len; i++ )
2792 {
Paul Bakker27fdf462011-06-09 13:55:13 +00002793 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002794 break;
2795
2796 c = name->val.p[i];
2797 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2798 s[i] = '?';
2799 else s[i] = c;
2800 }
2801 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002802 ret = snprintf( p, n, "%s", s );
2803 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002804 name = name->next;
2805 }
2806
Paul Bakker23986e52011-04-24 08:57:21 +00002807 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002808}
2809
2810/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002811 * Store the serial in printable form into buf; no more
2812 * than size characters will be written
2813 */
2814int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2815{
Paul Bakker23986e52011-04-24 08:57:21 +00002816 int ret;
2817 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00002818 char *p;
2819
2820 p = buf;
2821 n = size;
2822
2823 nr = ( serial->len <= 32 )
Paul Bakker03c7c252011-11-25 12:37:37 +00002824 ? serial->len : 28;
Paul Bakkerdd476992011-01-16 21:34:59 +00002825
2826 for( i = 0; i < nr; i++ )
2827 {
Paul Bakker93048802011-12-05 14:38:06 +00002828 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002829 continue;
2830
Paul Bakkerdd476992011-01-16 21:34:59 +00002831 ret = snprintf( p, n, "%02X%s",
2832 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2833 SAFE_SNPRINTF();
2834 }
2835
Paul Bakker03c7c252011-11-25 12:37:37 +00002836 if( nr != serial->len )
2837 {
2838 ret = snprintf( p, n, "...." );
2839 SAFE_SNPRINTF();
2840 }
2841
Paul Bakker23986e52011-04-24 08:57:21 +00002842 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00002843}
2844
2845/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002846 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002847 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002848int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2849 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002850{
Paul Bakker23986e52011-04-24 08:57:21 +00002851 int ret;
2852 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002853 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00002854
2855 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002856 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002857
Paul Bakkerd98030e2009-05-02 15:13:40 +00002858 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002859 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002860 SAFE_SNPRINTF();
2861 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002862 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002863 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002864
Paul Bakkerdd476992011-01-16 21:34:59 +00002865 ret = x509parse_serial_gets( p, n, &crt->serial);
2866 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002867
Paul Bakkerd98030e2009-05-02 15:13:40 +00002868 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2869 SAFE_SNPRINTF();
2870 ret = x509parse_dn_gets( p, n, &crt->issuer );
2871 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002872
Paul Bakkerd98030e2009-05-02 15:13:40 +00002873 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2874 SAFE_SNPRINTF();
2875 ret = x509parse_dn_gets( p, n, &crt->subject );
2876 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002877
Paul Bakkerd98030e2009-05-02 15:13:40 +00002878 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002879 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2880 crt->valid_from.year, crt->valid_from.mon,
2881 crt->valid_from.day, crt->valid_from.hour,
2882 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002883 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002884
Paul Bakkerd98030e2009-05-02 15:13:40 +00002885 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002886 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2887 crt->valid_to.year, crt->valid_to.mon,
2888 crt->valid_to.day, crt->valid_to.hour,
2889 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002890 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002891
Paul Bakkerd98030e2009-05-02 15:13:40 +00002892 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2893 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002894
Paul Bakker27d66162010-03-17 06:56:01 +00002895 switch( crt->sig_alg )
Paul Bakker5121ce52009-01-03 21:22:43 +00002896 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002897 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2898 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2899 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2900 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2901 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2902 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2903 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2904 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2905 default: ret = snprintf( p, n, "???" ); break;
2906 }
2907 SAFE_SNPRINTF();
2908
2909 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
Paul Bakker5c2364c2012-10-01 14:41:15 +00002910 (int) crt->rsa.N.n * (int) sizeof( t_uint ) * 8 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002911 SAFE_SNPRINTF();
2912
Paul Bakker23986e52011-04-24 08:57:21 +00002913 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002914}
2915
Paul Bakker74111d32011-01-15 16:57:55 +00002916/*
2917 * Return an informational string describing the given OID
2918 */
2919const char *x509_oid_get_description( x509_buf *oid )
2920{
2921 if ( oid == NULL )
2922 return ( NULL );
2923
2924 else if( OID_CMP( OID_SERVER_AUTH, oid ) )
2925 return( STRING_SERVER_AUTH );
2926
2927 else if( OID_CMP( OID_CLIENT_AUTH, oid ) )
2928 return( STRING_CLIENT_AUTH );
2929
2930 else if( OID_CMP( OID_CODE_SIGNING, oid ) )
2931 return( STRING_CODE_SIGNING );
2932
2933 else if( OID_CMP( OID_EMAIL_PROTECTION, oid ) )
2934 return( STRING_EMAIL_PROTECTION );
2935
2936 else if( OID_CMP( OID_TIME_STAMPING, oid ) )
2937 return( STRING_TIME_STAMPING );
2938
2939 else if( OID_CMP( OID_OCSP_SIGNING, oid ) )
2940 return( STRING_OCSP_SIGNING );
2941
2942 return( NULL );
2943}
2944
2945/* Return the x.y.z.... style numeric string for the given OID */
2946int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2947{
Paul Bakker23986e52011-04-24 08:57:21 +00002948 int ret;
2949 size_t i, n;
Paul Bakker74111d32011-01-15 16:57:55 +00002950 unsigned int value;
2951 char *p;
2952
2953 p = buf;
2954 n = size;
2955
2956 /* First byte contains first two dots */
2957 if( oid->len > 0 )
2958 {
2959 ret = snprintf( p, n, "%d.%d", oid->p[0]/40, oid->p[0]%40 );
2960 SAFE_SNPRINTF();
2961 }
2962
2963 /* TODO: value can overflow in value. */
2964 value = 0;
Paul Bakker23986e52011-04-24 08:57:21 +00002965 for( i = 1; i < oid->len; i++ )
Paul Bakker74111d32011-01-15 16:57:55 +00002966 {
2967 value <<= 7;
2968 value += oid->p[i] & 0x7F;
2969
2970 if( !( oid->p[i] & 0x80 ) )
2971 {
2972 /* Last byte */
2973 ret = snprintf( p, n, ".%d", value );
2974 SAFE_SNPRINTF();
2975 value = 0;
2976 }
2977 }
2978
Paul Bakker23986e52011-04-24 08:57:21 +00002979 return( (int) ( size - n ) );
Paul Bakker74111d32011-01-15 16:57:55 +00002980}
2981
Paul Bakkerd98030e2009-05-02 15:13:40 +00002982/*
2983 * Return an informational string about the CRL.
2984 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002985int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2986 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002987{
Paul Bakker23986e52011-04-24 08:57:21 +00002988 int ret;
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002989 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002990 char *p;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002991 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002992
2993 p = buf;
2994 n = size;
2995
2996 ret = snprintf( p, n, "%sCRL version : %d",
2997 prefix, crl->version );
2998 SAFE_SNPRINTF();
2999
3000 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
3001 SAFE_SNPRINTF();
3002 ret = x509parse_dn_gets( p, n, &crl->issuer );
3003 SAFE_SNPRINTF();
3004
3005 ret = snprintf( p, n, "\n%sthis update : " \
3006 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3007 crl->this_update.year, crl->this_update.mon,
3008 crl->this_update.day, crl->this_update.hour,
3009 crl->this_update.min, crl->this_update.sec );
3010 SAFE_SNPRINTF();
3011
3012 ret = snprintf( p, n, "\n%snext update : " \
3013 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3014 crl->next_update.year, crl->next_update.mon,
3015 crl->next_update.day, crl->next_update.hour,
3016 crl->next_update.min, crl->next_update.sec );
3017 SAFE_SNPRINTF();
3018
3019 entry = &crl->entry;
3020
3021 ret = snprintf( p, n, "\n%sRevoked certificates:",
3022 prefix );
3023 SAFE_SNPRINTF();
3024
Paul Bakker9be19372009-07-27 20:21:53 +00003025 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003026 {
3027 ret = snprintf( p, n, "\n%sserial number: ",
3028 prefix );
3029 SAFE_SNPRINTF();
3030
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003031 ret = x509parse_serial_gets( p, n, &entry->serial);
3032 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003033
Paul Bakkerd98030e2009-05-02 15:13:40 +00003034 ret = snprintf( p, n, " revocation date: " \
3035 "%04d-%02d-%02d %02d:%02d:%02d",
3036 entry->revocation_date.year, entry->revocation_date.mon,
3037 entry->revocation_date.day, entry->revocation_date.hour,
3038 entry->revocation_date.min, entry->revocation_date.sec );
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003039 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003040
3041 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003042 }
3043
Paul Bakkerd98030e2009-05-02 15:13:40 +00003044 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
3045 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003046
Paul Bakker27d66162010-03-17 06:56:01 +00003047 switch( crl->sig_alg )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003048 {
3049 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
3050 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
3051 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
3052 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
3053 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
3054 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
3055 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
3056 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
3057 default: ret = snprintf( p, n, "???" ); break;
3058 }
3059 SAFE_SNPRINTF();
3060
Paul Bakker1e27bb22009-07-19 20:25:25 +00003061 ret = snprintf( p, n, "\n" );
3062 SAFE_SNPRINTF();
3063
Paul Bakker23986e52011-04-24 08:57:21 +00003064 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003065}
3066
3067/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00003068 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00003069 */
Paul Bakker0d844dd2014-07-07 17:44:14 +02003070static void x509_get_current_time( x509_time *now )
Paul Bakker5121ce52009-01-03 21:22:43 +00003071{
Paul Bakkercce9d772011-11-18 14:26:47 +00003072#if defined(_WIN32)
3073 SYSTEMTIME st;
3074
Paul Bakkerf48de952014-07-08 14:39:41 +02003075 GetSystemTime(&st);
Paul Bakkercce9d772011-11-18 14:26:47 +00003076
Paul Bakker0d844dd2014-07-07 17:44:14 +02003077 now->year = st.wYear;
3078 now->mon = st.wMonth;
3079 now->day = st.wDay;
3080 now->hour = st.wHour;
3081 now->min = st.wMinute;
3082 now->sec = st.wSecond;
Paul Bakkercce9d772011-11-18 14:26:47 +00003083#else
Paul Bakker358a8412014-07-08 12:14:37 +02003084 struct tm lt;
Paul Bakker5121ce52009-01-03 21:22:43 +00003085 time_t tt;
3086
3087 tt = time( NULL );
Paul Bakkerf48de952014-07-08 14:39:41 +02003088 gmtime_r( &tt, &lt );
Paul Bakker5121ce52009-01-03 21:22:43 +00003089
Paul Bakker358a8412014-07-08 12:14:37 +02003090 now->year = lt.tm_year + 1900;
3091 now->mon = lt.tm_mon + 1;
3092 now->day = lt.tm_mday;
3093 now->hour = lt.tm_hour;
3094 now->min = lt.tm_min;
3095 now->sec = lt.tm_sec;
Paul Bakkercce9d772011-11-18 14:26:47 +00003096#endif
Paul Bakker0d844dd2014-07-07 17:44:14 +02003097}
Paul Bakkercce9d772011-11-18 14:26:47 +00003098
Paul Bakker0d844dd2014-07-07 17:44:14 +02003099/*
3100 * Return 0 if before <= after, 1 otherwise
3101 */
3102static int x509_check_time( const x509_time *before, const x509_time *after )
3103{
3104 if( before->year > after->year )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003105 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003106
Paul Bakker0d844dd2014-07-07 17:44:14 +02003107 if( before->year == after->year &&
3108 before->mon > after->mon )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003109 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003110
Paul Bakker0d844dd2014-07-07 17:44:14 +02003111 if( before->year == after->year &&
3112 before->mon == after->mon &&
3113 before->day > after->day )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003114 return( 1 );
3115
Paul Bakker0d844dd2014-07-07 17:44:14 +02003116 if( before->year == after->year &&
3117 before->mon == after->mon &&
3118 before->day == after->day &&
3119 before->hour > after->hour )
Paul Bakkerb6194992011-01-16 21:40:22 +00003120 return( 1 );
3121
Paul Bakker0d844dd2014-07-07 17:44:14 +02003122 if( before->year == after->year &&
3123 before->mon == after->mon &&
3124 before->day == after->day &&
3125 before->hour == after->hour &&
3126 before->min > after->min )
Paul Bakkerb6194992011-01-16 21:40:22 +00003127 return( 1 );
3128
Paul Bakker0d844dd2014-07-07 17:44:14 +02003129 if( before->year == after->year &&
3130 before->mon == after->mon &&
3131 before->day == after->day &&
3132 before->hour == after->hour &&
3133 before->min == after->min &&
3134 before->sec > after->sec )
Paul Bakkerb6194992011-01-16 21:40:22 +00003135 return( 1 );
3136
Paul Bakker40ea7de2009-05-03 10:18:48 +00003137 return( 0 );
3138}
3139
Paul Bakker0d844dd2014-07-07 17:44:14 +02003140int x509parse_time_expired( const x509_time *to )
3141{
3142 x509_time now;
3143
3144 x509_get_current_time( &now );
3145
3146 return( x509_check_time( &now, to ) );
3147}
3148
3149int x509parse_time_future( const x509_time *from )
3150{
3151 x509_time now;
3152
3153 x509_get_current_time( &now );
3154
3155 return( x509_check_time( from, &now ) );
3156}
3157
Paul Bakker40ea7de2009-05-03 10:18:48 +00003158/*
3159 * Return 1 if the certificate is revoked, or 0 otherwise.
3160 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003161int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003162{
Paul Bakkerff60ee62010-03-16 21:09:09 +00003163 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00003164
3165 while( cur != NULL && cur->serial.len != 0 )
3166 {
Paul Bakkera056efc2011-01-16 21:38:35 +00003167 if( crt->serial.len == cur->serial.len &&
3168 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003169 {
3170 if( x509parse_time_expired( &cur->revocation_date ) )
3171 return( 1 );
3172 }
3173
3174 cur = cur->next;
3175 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003176
3177 return( 0 );
3178}
3179
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003180/*
3181 * Wrapper for x509 hashes.
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003182 */
Paul Bakker23986e52011-04-24 08:57:21 +00003183static void x509_hash( const unsigned char *in, size_t len, int alg,
Paul Bakker5121ce52009-01-03 21:22:43 +00003184 unsigned char *out )
3185{
3186 switch( alg )
3187 {
Paul Bakker40e46942009-01-03 21:51:57 +00003188#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003189 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003190#endif
Paul Bakker40e46942009-01-03 21:51:57 +00003191#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003192 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003193#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003194#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003195 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003196#endif
3197#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003198 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003199#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00003200#if defined(POLARSSL_SHA2_C)
3201 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
3202 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
3203#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00003204#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003205 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
3206 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
3207#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003208 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003209 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003210 break;
3211 }
3212}
3213
3214/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00003215 * Check that the given certificate is valid accoring to the CRL.
3216 */
3217static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
3218 x509_crl *crl_list)
3219{
3220 int flags = 0;
3221 int hash_id;
3222 unsigned char hash[64];
3223
Paul Bakker915275b2012-09-28 07:10:55 +00003224 if( ca == NULL )
3225 return( flags );
3226
Paul Bakker76fd75a2011-01-16 21:12:10 +00003227 /*
3228 * TODO: What happens if no CRL is present?
3229 * Suggestion: Revocation state should be unknown if no CRL is present.
3230 * For backwards compatibility this is not yet implemented.
3231 */
3232
Paul Bakker915275b2012-09-28 07:10:55 +00003233 while( crl_list != NULL )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003234 {
Paul Bakker915275b2012-09-28 07:10:55 +00003235 if( crl_list->version == 0 ||
3236 crl_list->issuer_raw.len != ca->subject_raw.len ||
Paul Bakker76fd75a2011-01-16 21:12:10 +00003237 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
3238 crl_list->issuer_raw.len ) != 0 )
3239 {
3240 crl_list = crl_list->next;
3241 continue;
3242 }
3243
3244 /*
3245 * Check if CRL is correctly signed by the trusted CA
3246 */
3247 hash_id = crl_list->sig_alg;
3248
3249 x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
3250
Paul Bakker43f97992013-09-23 11:23:31 +02003251 if( !rsa_pkcs1_verify( &ca->rsa, NULL, NULL, RSA_PUBLIC, hash_id,
Paul Bakker76fd75a2011-01-16 21:12:10 +00003252 0, hash, crl_list->sig.p ) == 0 )
3253 {
3254 /*
3255 * CRL is not trusted
3256 */
3257 flags |= BADCRL_NOT_TRUSTED;
3258 break;
3259 }
3260
3261 /*
3262 * Check for validity of CRL (Do not drop out)
3263 */
3264 if( x509parse_time_expired( &crl_list->next_update ) )
3265 flags |= BADCRL_EXPIRED;
3266
Paul Bakker50a5c532014-07-08 10:59:10 +02003267 if( x509parse_time_future( &crl_list->this_update ) )
3268 flags |= BADCRL_FUTURE;
3269
Paul Bakker76fd75a2011-01-16 21:12:10 +00003270 /*
3271 * Check if certificate is revoked
3272 */
3273 if( x509parse_revoked(crt, crl_list) )
3274 {
3275 flags |= BADCERT_REVOKED;
3276 break;
3277 }
3278
3279 crl_list = crl_list->next;
3280 }
3281 return flags;
3282}
3283
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003284// Equal == 0, inequal == 1
3285static int x509_name_cmp( const void *s1, const void *s2, size_t len )
3286{
3287 size_t i;
3288 unsigned char diff;
3289 const unsigned char *n1 = s1, *n2 = s2;
3290
3291 for( i = 0; i < len; i++ )
3292 {
3293 diff = n1[i] ^ n2[i];
3294
Paul Bakkerc941adb2014-07-07 14:17:24 +02003295 if( diff == 0 )
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003296 continue;
3297
Paul Bakkerc941adb2014-07-07 14:17:24 +02003298 if( diff == 32 &&
3299 ( ( n1[i] >= 'a' && n1[i] <= 'z' ) ||
3300 ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) )
3301 {
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003302 continue;
Paul Bakkerc941adb2014-07-07 14:17:24 +02003303 }
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003304
3305 return( 1 );
3306 }
3307
3308 return( 0 );
3309}
3310
Paul Bakker1d073c52014-07-08 20:15:51 +02003311static int x509_wildcard_verify( const char *cn, x509_buf *name )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003312{
3313 size_t i;
3314 size_t cn_idx = 0;
3315
Paul Bakker57b12982012-02-11 17:38:38 +00003316 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003317 return( 0 );
3318
3319 for( i = 0; i < strlen( cn ); ++i )
3320 {
3321 if( cn[i] == '.' )
3322 {
3323 cn_idx = i;
3324 break;
3325 }
3326 }
3327
3328 if( cn_idx == 0 )
3329 return( 0 );
3330
Paul Bakker535e97d2012-08-23 10:49:55 +00003331 if( strlen( cn ) - cn_idx == name->len - 1 &&
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003332 x509_name_cmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003333 {
3334 return( 1 );
3335 }
3336
3337 return( 0 );
3338}
3339
Paul Bakker915275b2012-09-28 07:10:55 +00003340static int x509parse_verify_top(
3341 x509_cert *child, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003342 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003343 int (*f_vrfy)(void *, x509_cert *, int, int *),
3344 void *p_vrfy )
3345{
3346 int hash_id, ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003347 int ca_flags = 0, check_path_cnt = path_cnt + 1;
Paul Bakker915275b2012-09-28 07:10:55 +00003348 unsigned char hash[64];
3349
3350 if( x509parse_time_expired( &child->valid_to ) )
3351 *flags |= BADCERT_EXPIRED;
3352
Paul Bakker50a5c532014-07-08 10:59:10 +02003353 if( x509parse_time_future( &child->valid_from ) )
3354 *flags |= BADCERT_FUTURE;
3355
Paul Bakker915275b2012-09-28 07:10:55 +00003356 /*
3357 * Child is the top of the chain. Check against the trust_ca list.
3358 */
3359 *flags |= BADCERT_NOT_TRUSTED;
3360
3361 while( trust_ca != NULL )
3362 {
3363 if( trust_ca->version == 0 ||
3364 child->issuer_raw.len != trust_ca->subject_raw.len ||
3365 memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
3366 child->issuer_raw.len ) != 0 )
3367 {
3368 trust_ca = trust_ca->next;
3369 continue;
3370 }
3371
Paul Bakker9a736322012-11-14 12:39:52 +00003372 /*
3373 * Reduce path_len to check against if top of the chain is
3374 * the same as the trusted CA
3375 */
3376 if( child->subject_raw.len == trust_ca->subject_raw.len &&
3377 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3378 child->issuer_raw.len ) == 0 )
3379 {
3380 check_path_cnt--;
3381 }
3382
Paul Bakker915275b2012-09-28 07:10:55 +00003383 if( trust_ca->max_pathlen > 0 &&
Paul Bakker9a736322012-11-14 12:39:52 +00003384 trust_ca->max_pathlen < check_path_cnt )
Paul Bakker915275b2012-09-28 07:10:55 +00003385 {
3386 trust_ca = trust_ca->next;
3387 continue;
3388 }
3389
3390 hash_id = child->sig_alg;
3391
3392 x509_hash( child->tbs.p, child->tbs.len, hash_id, hash );
3393
Paul Bakker43f97992013-09-23 11:23:31 +02003394 if( rsa_pkcs1_verify( &trust_ca->rsa, NULL, NULL, RSA_PUBLIC, hash_id,
Paul Bakker915275b2012-09-28 07:10:55 +00003395 0, hash, child->sig.p ) != 0 )
3396 {
3397 trust_ca = trust_ca->next;
3398 continue;
3399 }
3400
3401 /*
3402 * Top of chain is signed by a trusted CA
3403 */
3404 *flags &= ~BADCERT_NOT_TRUSTED;
3405 break;
3406 }
3407
Paul Bakker9a736322012-11-14 12:39:52 +00003408 /*
Paul Bakker3497d8c2012-11-24 11:53:17 +01003409 * If top of chain is not the same as the trusted CA send a verify request
3410 * to the callback for any issues with validity and CRL presence for the
3411 * trusted CA certificate.
Paul Bakker9a736322012-11-14 12:39:52 +00003412 */
3413 if( trust_ca != NULL &&
3414 ( child->subject_raw.len != trust_ca->subject_raw.len ||
3415 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3416 child->issuer_raw.len ) != 0 ) )
Paul Bakker915275b2012-09-28 07:10:55 +00003417 {
3418 /* Check trusted CA's CRL for then chain's top crt */
3419 *flags |= x509parse_verifycrl( child, trust_ca, ca_crl );
3420
3421 if( x509parse_time_expired( &trust_ca->valid_to ) )
3422 ca_flags |= BADCERT_EXPIRED;
3423
Paul Bakker50a5c532014-07-08 10:59:10 +02003424 if( x509parse_time_future( &trust_ca->valid_from ) )
3425 ca_flags |= BADCERT_FUTURE;
3426
Paul Bakker915275b2012-09-28 07:10:55 +00003427 if( NULL != f_vrfy )
3428 {
Paul Bakker9a736322012-11-14 12:39:52 +00003429 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003430 return( ret );
3431 }
3432 }
3433
3434 /* Call callback on top cert */
3435 if( NULL != f_vrfy )
3436 {
Paul Bakker9a736322012-11-14 12:39:52 +00003437 if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003438 return( ret );
3439 }
3440
Paul Bakker915275b2012-09-28 07:10:55 +00003441 *flags |= ca_flags;
3442
3443 return( 0 );
3444}
3445
3446static int x509parse_verify_child(
3447 x509_cert *child, x509_cert *parent, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003448 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003449 int (*f_vrfy)(void *, x509_cert *, int, int *),
3450 void *p_vrfy )
3451{
3452 int hash_id, ret;
3453 int parent_flags = 0;
3454 unsigned char hash[64];
3455 x509_cert *grandparent;
3456
3457 if( x509parse_time_expired( &child->valid_to ) )
3458 *flags |= BADCERT_EXPIRED;
3459
Paul Bakker50a5c532014-07-08 10:59:10 +02003460 if( x509parse_time_future( &child->valid_from ) )
3461 *flags |= BADCERT_FUTURE;
3462
Paul Bakker915275b2012-09-28 07:10:55 +00003463 hash_id = child->sig_alg;
3464
3465 x509_hash( child->tbs.p, child->tbs.len, hash_id, hash );
3466
Paul Bakker43f97992013-09-23 11:23:31 +02003467 if( rsa_pkcs1_verify( &parent->rsa, NULL, NULL, RSA_PUBLIC, hash_id, 0,
3468 hash, child->sig.p ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003469 *flags |= BADCERT_NOT_TRUSTED;
3470
3471 /* Check trusted CA's CRL for the given crt */
3472 *flags |= x509parse_verifycrl(child, parent, ca_crl);
3473
3474 grandparent = parent->next;
3475
3476 while( grandparent != NULL )
3477 {
3478 if( grandparent->version == 0 ||
3479 grandparent->ca_istrue == 0 ||
3480 parent->issuer_raw.len != grandparent->subject_raw.len ||
3481 memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
3482 parent->issuer_raw.len ) != 0 )
3483 {
3484 grandparent = grandparent->next;
3485 continue;
3486 }
3487 break;
3488 }
3489
Paul Bakker915275b2012-09-28 07:10:55 +00003490 if( grandparent != NULL )
3491 {
3492 /*
3493 * Part of the chain
3494 */
Paul Bakker9a736322012-11-14 12:39:52 +00003495 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 +00003496 if( ret != 0 )
3497 return( ret );
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003498 }
Paul Bakker915275b2012-09-28 07:10:55 +00003499 else
3500 {
Paul Bakker9a736322012-11-14 12:39:52 +00003501 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 +00003502 if( ret != 0 )
3503 return( ret );
3504 }
3505
3506 /* child is verified to be a child of the parent, call verify callback */
3507 if( NULL != f_vrfy )
Paul Bakker9a736322012-11-14 12:39:52 +00003508 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003509 return( ret );
Paul Bakker915275b2012-09-28 07:10:55 +00003510
3511 *flags |= parent_flags;
3512
3513 return( 0 );
3514}
3515
Paul Bakker76fd75a2011-01-16 21:12:10 +00003516/*
Paul Bakker5121ce52009-01-03 21:22:43 +00003517 * Verify the certificate validity
3518 */
3519int x509parse_verify( x509_cert *crt,
3520 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00003521 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003522 const char *cn, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003523 int (*f_vrfy)(void *, x509_cert *, int, int *),
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003524 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00003525{
Paul Bakker23986e52011-04-24 08:57:21 +00003526 size_t cn_len;
Paul Bakker915275b2012-09-28 07:10:55 +00003527 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003528 int pathlen = 0;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003529 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00003530 x509_name *name;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003531 x509_sequence *cur = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003532
Paul Bakker40ea7de2009-05-03 10:18:48 +00003533 *flags = 0;
3534
Paul Bakker5121ce52009-01-03 21:22:43 +00003535 if( cn != NULL )
3536 {
3537 name = &crt->subject;
3538 cn_len = strlen( cn );
3539
Paul Bakker4d2c1242012-05-10 14:12:46 +00003540 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
Paul Bakker5121ce52009-01-03 21:22:43 +00003541 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00003542 cur = &crt->subject_alt_names;
3543
3544 while( cur != NULL )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003545 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003546 if( cur->buf.len == cn_len &&
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003547 x509_name_cmp( cn, cur->buf.p, cn_len ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003548 break;
3549
Paul Bakker535e97d2012-08-23 10:49:55 +00003550 if( cur->buf.len > 2 &&
3551 memcmp( cur->buf.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003552 x509_wildcard_verify( cn, &cur->buf ) )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003553 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003554
Paul Bakker4d2c1242012-05-10 14:12:46 +00003555 cur = cur->next;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003556 }
3557
3558 if( cur == NULL )
3559 *flags |= BADCERT_CN_MISMATCH;
3560 }
Paul Bakker4d2c1242012-05-10 14:12:46 +00003561 else
3562 {
3563 while( name != NULL )
3564 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003565 if( name->oid.len == 3 &&
3566 memcmp( name->oid.p, OID_CN, 3 ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003567 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003568 if( name->val.len == cn_len &&
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003569 x509_name_cmp( name->val.p, cn, cn_len ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003570 break;
3571
Paul Bakker535e97d2012-08-23 10:49:55 +00003572 if( name->val.len > 2 &&
3573 memcmp( name->val.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003574 x509_wildcard_verify( cn, &name->val ) )
3575 break;
3576 }
3577
3578 name = name->next;
3579 }
3580
3581 if( name == NULL )
3582 *flags |= BADCERT_CN_MISMATCH;
3583 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003584 }
3585
Paul Bakker5121ce52009-01-03 21:22:43 +00003586 /*
Paul Bakker915275b2012-09-28 07:10:55 +00003587 * Iterate upwards in the given cert chain, to find our crt parent.
3588 * Ignore any upper cert with CA != TRUE.
Paul Bakker5121ce52009-01-03 21:22:43 +00003589 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003590 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003591
Paul Bakker76fd75a2011-01-16 21:12:10 +00003592 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003593 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003594 if( parent->ca_istrue == 0 ||
3595 crt->issuer_raw.len != parent->subject_raw.len ||
3596 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00003597 crt->issuer_raw.len ) != 0 )
3598 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003599 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003600 continue;
3601 }
Paul Bakker915275b2012-09-28 07:10:55 +00003602 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003603 }
3604
Paul Bakker915275b2012-09-28 07:10:55 +00003605 if( parent != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003606 {
Paul Bakker915275b2012-09-28 07:10:55 +00003607 /*
3608 * Part of the chain
3609 */
Paul Bakker9a736322012-11-14 12:39:52 +00003610 ret = x509parse_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003611 if( ret != 0 )
3612 return( ret );
3613 }
3614 else
Paul Bakker74111d32011-01-15 16:57:55 +00003615 {
Paul Bakker9a736322012-11-14 12:39:52 +00003616 ret = x509parse_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003617 if( ret != 0 )
3618 return( ret );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003619 }
Paul Bakker915275b2012-09-28 07:10:55 +00003620
3621 if( *flags != 0 )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003622 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003623
Paul Bakker5121ce52009-01-03 21:22:43 +00003624 return( 0 );
3625}
3626
3627/*
3628 * Unallocate all certificate data
3629 */
3630void x509_free( x509_cert *crt )
3631{
3632 x509_cert *cert_cur = crt;
3633 x509_cert *cert_prv;
3634 x509_name *name_cur;
3635 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00003636 x509_sequence *seq_cur;
3637 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00003638
3639 if( crt == NULL )
3640 return;
3641
3642 do
3643 {
3644 rsa_free( &cert_cur->rsa );
3645
3646 name_cur = cert_cur->issuer.next;
3647 while( name_cur != NULL )
3648 {
3649 name_prv = name_cur;
3650 name_cur = name_cur->next;
3651 memset( name_prv, 0, sizeof( x509_name ) );
3652 free( name_prv );
3653 }
3654
3655 name_cur = cert_cur->subject.next;
3656 while( name_cur != NULL )
3657 {
3658 name_prv = name_cur;
3659 name_cur = name_cur->next;
3660 memset( name_prv, 0, sizeof( x509_name ) );
3661 free( name_prv );
3662 }
3663
Paul Bakker74111d32011-01-15 16:57:55 +00003664 seq_cur = cert_cur->ext_key_usage.next;
3665 while( seq_cur != NULL )
3666 {
3667 seq_prv = seq_cur;
3668 seq_cur = seq_cur->next;
3669 memset( seq_prv, 0, sizeof( x509_sequence ) );
3670 free( seq_prv );
3671 }
3672
Paul Bakker8afa70d2012-02-11 18:42:45 +00003673 seq_cur = cert_cur->subject_alt_names.next;
3674 while( seq_cur != NULL )
3675 {
3676 seq_prv = seq_cur;
3677 seq_cur = seq_cur->next;
3678 memset( seq_prv, 0, sizeof( x509_sequence ) );
3679 free( seq_prv );
3680 }
3681
Paul Bakker5121ce52009-01-03 21:22:43 +00003682 if( cert_cur->raw.p != NULL )
3683 {
3684 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
3685 free( cert_cur->raw.p );
3686 }
3687
3688 cert_cur = cert_cur->next;
3689 }
3690 while( cert_cur != NULL );
3691
3692 cert_cur = crt;
3693 do
3694 {
3695 cert_prv = cert_cur;
3696 cert_cur = cert_cur->next;
3697
3698 memset( cert_prv, 0, sizeof( x509_cert ) );
3699 if( cert_prv != crt )
3700 free( cert_prv );
3701 }
3702 while( cert_cur != NULL );
3703}
3704
Paul Bakkerd98030e2009-05-02 15:13:40 +00003705/*
3706 * Unallocate all CRL data
3707 */
3708void x509_crl_free( x509_crl *crl )
3709{
3710 x509_crl *crl_cur = crl;
3711 x509_crl *crl_prv;
3712 x509_name *name_cur;
3713 x509_name *name_prv;
3714 x509_crl_entry *entry_cur;
3715 x509_crl_entry *entry_prv;
3716
3717 if( crl == NULL )
3718 return;
3719
3720 do
3721 {
3722 name_cur = crl_cur->issuer.next;
3723 while( name_cur != NULL )
3724 {
3725 name_prv = name_cur;
3726 name_cur = name_cur->next;
3727 memset( name_prv, 0, sizeof( x509_name ) );
3728 free( name_prv );
3729 }
3730
3731 entry_cur = crl_cur->entry.next;
3732 while( entry_cur != NULL )
3733 {
3734 entry_prv = entry_cur;
3735 entry_cur = entry_cur->next;
3736 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
3737 free( entry_prv );
3738 }
3739
3740 if( crl_cur->raw.p != NULL )
3741 {
3742 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
3743 free( crl_cur->raw.p );
3744 }
3745
3746 crl_cur = crl_cur->next;
3747 }
3748 while( crl_cur != NULL );
3749
3750 crl_cur = crl;
3751 do
3752 {
3753 crl_prv = crl_cur;
3754 crl_cur = crl_cur->next;
3755
3756 memset( crl_prv, 0, sizeof( x509_crl ) );
3757 if( crl_prv != crl )
3758 free( crl_prv );
3759 }
3760 while( crl_cur != NULL );
3761}
3762
Paul Bakker40e46942009-01-03 21:51:57 +00003763#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00003764
Paul Bakker40e46942009-01-03 21:51:57 +00003765#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00003766
3767/*
3768 * Checkup routine
3769 */
3770int x509_self_test( int verbose )
3771{
Paul Bakker5690efc2011-05-26 13:16:06 +00003772#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00003773 int ret;
3774 int flags;
3775 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00003776 x509_cert cacert;
3777 x509_cert clicert;
3778 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00003779#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003780 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00003781#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003782
3783 if( verbose != 0 )
3784 printf( " X.509 certificate load: " );
3785
3786 memset( &clicert, 0, sizeof( x509_cert ) );
3787
Paul Bakkereae09db2013-06-06 12:35:54 +02003788 ret = x509parse_crt( &clicert, (const unsigned char *) test_cli_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003789 strlen( test_cli_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003790 if( ret != 0 )
3791 {
3792 if( verbose != 0 )
3793 printf( "failed\n" );
3794
3795 return( ret );
3796 }
3797
3798 memset( &cacert, 0, sizeof( x509_cert ) );
3799
Paul Bakkereae09db2013-06-06 12:35:54 +02003800 ret = x509parse_crt( &cacert, (const unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003801 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003802 if( ret != 0 )
3803 {
3804 if( verbose != 0 )
3805 printf( "failed\n" );
3806
3807 return( ret );
3808 }
3809
3810 if( verbose != 0 )
3811 printf( "passed\n X.509 private key load: " );
3812
3813 i = strlen( test_ca_key );
3814 j = strlen( test_ca_pwd );
3815
Paul Bakker66b78b22011-03-25 14:22:50 +00003816 rsa_init( &rsa, RSA_PKCS_V15, 0 );
3817
Paul Bakker5121ce52009-01-03 21:22:43 +00003818 if( ( ret = x509parse_key( &rsa,
Paul Bakkereae09db2013-06-06 12:35:54 +02003819 (const unsigned char *) test_ca_key, i,
3820 (const unsigned char *) test_ca_pwd, j ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003821 {
3822 if( verbose != 0 )
3823 printf( "failed\n" );
3824
3825 return( ret );
3826 }
3827
3828 if( verbose != 0 )
3829 printf( "passed\n X.509 signature verify: ");
3830
Paul Bakker23986e52011-04-24 08:57:21 +00003831 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003832 if( ret != 0 )
3833 {
3834 if( verbose != 0 )
3835 printf( "failed\n" );
3836
3837 return( ret );
3838 }
3839
Paul Bakker5690efc2011-05-26 13:16:06 +00003840#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003841 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003842 printf( "passed\n X.509 DHM parameter load: " );
3843
3844 i = strlen( test_dhm_params );
3845 j = strlen( test_ca_pwd );
3846
Paul Bakkereae09db2013-06-06 12:35:54 +02003847 if( ( ret = x509parse_dhm( &dhm, (const unsigned char *) test_dhm_params, i ) ) != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003848 {
3849 if( verbose != 0 )
3850 printf( "failed\n" );
3851
3852 return( ret );
3853 }
3854
3855 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003856 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00003857#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003858
3859 x509_free( &cacert );
3860 x509_free( &clicert );
3861 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00003862#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003863 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00003864#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003865
3866 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003867#else
3868 ((void) verbose);
3869 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3870#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003871}
3872
3873#endif
3874
3875#endif