blob: c00c5db22f3953eac693acdd97f1c5c6fd2000a4 [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 {
Manuel Pégourié-Gonnardfdec9572014-11-11 23:11:16 +0100869 if( cur->next != NULL )
870 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS );
871
Paul Bakkera8cd2392012-02-11 16:09:32 +0000872 cur->next = (asn1_sequence *) malloc(
873 sizeof( asn1_sequence ) );
874
875 if( cur->next == NULL )
876 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
877 POLARSSL_ERR_ASN1_MALLOC_FAILED );
878
Paul Bakker535e97d2012-08-23 10:49:55 +0000879 memset( cur->next, 0, sizeof( asn1_sequence ) );
Paul Bakkera8cd2392012-02-11 16:09:32 +0000880 cur = cur->next;
881 }
882 }
883
884 /* Set final sequence entry's next pointer to NULL */
885 cur->next = NULL;
886
887 if( *p != end )
888 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
889 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
890
891 return( 0 );
892}
893
894/*
Paul Bakker74111d32011-01-15 16:57:55 +0000895 * X.509 v3 extensions
896 *
897 * TODO: Perform all of the basic constraints tests required by the RFC
898 * TODO: Set values for undetected extensions to a sane default?
899 *
Paul Bakkerd98030e2009-05-02 15:13:40 +0000900 */
901static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000902 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000903 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000904{
Paul Bakker23986e52011-04-24 08:57:21 +0000905 int ret;
906 size_t len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000907 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000908
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000909 if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000910 {
911 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
912 return( 0 );
913
914 return( ret );
915 }
916
Paul Bakker5121ce52009-01-03 21:22:43 +0000917 while( *p < end )
918 {
Paul Bakker74111d32011-01-15 16:57:55 +0000919 /*
920 * Extension ::= SEQUENCE {
921 * extnID OBJECT IDENTIFIER,
922 * critical BOOLEAN DEFAULT FALSE,
923 * extnValue OCTET STRING }
924 */
925 x509_buf extn_oid = {0, 0, NULL};
926 int is_critical = 0; /* DEFAULT FALSE */
927
Paul Bakker5121ce52009-01-03 21:22:43 +0000928 if( ( ret = asn1_get_tag( p, end, &len,
929 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000930 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000931
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000932 end_ext_data = *p + len;
933
Paul Bakker74111d32011-01-15 16:57:55 +0000934 /* Get extension ID */
935 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000936
Paul Bakker74111d32011-01-15 16:57:55 +0000937 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000938 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000939
Paul Bakker74111d32011-01-15 16:57:55 +0000940 extn_oid.p = *p;
941 *p += extn_oid.len;
942
943 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000944 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000945 POLARSSL_ERR_ASN1_OUT_OF_DATA );
946
947 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000948 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000949 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
Paul Bakker9d781402011-05-09 16:17:09 +0000950 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000951
Paul Bakker74111d32011-01-15 16:57:55 +0000952 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000953 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000954 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000955 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000956
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000957 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000958
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000959 if( end_ext_octet != end_ext_data )
Paul Bakker9d781402011-05-09 16:17:09 +0000960 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000961 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000962
Paul Bakker74111d32011-01-15 16:57:55 +0000963 /*
964 * Detect supported extensions
965 */
966 if( ( OID_SIZE( OID_BASIC_CONSTRAINTS ) == extn_oid.len ) &&
967 memcmp( extn_oid.p, OID_BASIC_CONSTRAINTS, extn_oid.len ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000968 {
Paul Bakker74111d32011-01-15 16:57:55 +0000969 /* Parse basic constraints */
970 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
Paul Bakker3cccddb2011-01-16 21:46:31 +0000971 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000972 return ( ret );
973 crt->ext_types |= EXT_BASIC_CONSTRAINTS;
Paul Bakker5121ce52009-01-03 21:22:43 +0000974 }
Paul Bakker74111d32011-01-15 16:57:55 +0000975 else if( ( OID_SIZE( OID_NS_CERT_TYPE ) == extn_oid.len ) &&
976 memcmp( extn_oid.p, OID_NS_CERT_TYPE, extn_oid.len ) == 0 )
977 {
978 /* Parse netscape certificate type */
979 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
980 &crt->ns_cert_type ) ) != 0 )
981 return ( ret );
982 crt->ext_types |= EXT_NS_CERT_TYPE;
983 }
984 else if( ( OID_SIZE( OID_KEY_USAGE ) == extn_oid.len ) &&
985 memcmp( extn_oid.p, OID_KEY_USAGE, extn_oid.len ) == 0 )
986 {
987 /* Parse key usage */
988 if( ( ret = x509_get_key_usage( p, end_ext_octet,
989 &crt->key_usage ) ) != 0 )
990 return ( ret );
991 crt->ext_types |= EXT_KEY_USAGE;
992 }
993 else if( ( OID_SIZE( OID_EXTENDED_KEY_USAGE ) == extn_oid.len ) &&
994 memcmp( extn_oid.p, OID_EXTENDED_KEY_USAGE, extn_oid.len ) == 0 )
995 {
996 /* Parse extended key usage */
997 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
998 &crt->ext_key_usage ) ) != 0 )
999 return ( ret );
1000 crt->ext_types |= EXT_EXTENDED_KEY_USAGE;
1001 }
Paul Bakkera8cd2392012-02-11 16:09:32 +00001002 else if( ( OID_SIZE( OID_SUBJECT_ALT_NAME ) == extn_oid.len ) &&
1003 memcmp( extn_oid.p, OID_SUBJECT_ALT_NAME, extn_oid.len ) == 0 )
1004 {
1005 /* Parse extended key usage */
1006 if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
1007 &crt->subject_alt_names ) ) != 0 )
1008 return ( ret );
1009 crt->ext_types |= EXT_SUBJECT_ALT_NAME;
1010 }
Paul Bakker74111d32011-01-15 16:57:55 +00001011 else
1012 {
1013 /* No parser found, skip extension */
1014 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +00001015
Paul Bakker5c721f92011-07-27 16:51:09 +00001016#if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
Paul Bakker74111d32011-01-15 16:57:55 +00001017 if( is_critical )
1018 {
1019 /* Data is marked as critical: fail */
Paul Bakker9d781402011-05-09 16:17:09 +00001020 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +00001021 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
1022 }
Paul Bakker5c721f92011-07-27 16:51:09 +00001023#endif
Paul Bakker74111d32011-01-15 16:57:55 +00001024 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001025 }
1026
1027 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +00001028 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +00001029 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001030
Paul Bakker5121ce52009-01-03 21:22:43 +00001031 return( 0 );
1032}
1033
1034/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001035 * X.509 CRL Entries
1036 */
1037static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001038 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001039 x509_crl_entry *entry )
1040{
Paul Bakker23986e52011-04-24 08:57:21 +00001041 int ret;
1042 size_t entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001043 x509_crl_entry *cur_entry = entry;
1044
1045 if( *p == end )
1046 return( 0 );
1047
Paul Bakker9be19372009-07-27 20:21:53 +00001048 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001049 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1050 {
1051 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
1052 return( 0 );
1053
1054 return( ret );
1055 }
1056
Paul Bakker9be19372009-07-27 20:21:53 +00001057 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001058
1059 while( *p < end )
1060 {
Paul Bakker23986e52011-04-24 08:57:21 +00001061 size_t len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001062 const unsigned char *end2;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001063
1064 if( ( ret = asn1_get_tag( p, end, &len2,
1065 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1066 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001067 return( ret );
1068 }
1069
Paul Bakker9be19372009-07-27 20:21:53 +00001070 cur_entry->raw.tag = **p;
1071 cur_entry->raw.p = *p;
1072 cur_entry->raw.len = len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001073 end2 = *p + len2;
Paul Bakker9be19372009-07-27 20:21:53 +00001074
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001075 if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001076 return( ret );
1077
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001078 if( ( ret = x509_get_time( p, end2, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001079 return( ret );
1080
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001081 if( ( ret = x509_get_crl_entry_ext( p, end2, &cur_entry->entry_ext ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001082 return( ret );
1083
Paul Bakker74111d32011-01-15 16:57:55 +00001084 if ( *p < end )
1085 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001086 cur_entry->next = malloc( sizeof( x509_crl_entry ) );
Paul Bakkerb15b8512012-01-13 13:44:06 +00001087
1088 if( cur_entry->next == NULL )
1089 return( POLARSSL_ERR_X509_MALLOC_FAILED );
1090
Paul Bakkerd98030e2009-05-02 15:13:40 +00001091 cur_entry = cur_entry->next;
1092 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
1093 }
1094 }
1095
1096 return( 0 );
1097}
1098
Paul Bakker27d66162010-03-17 06:56:01 +00001099static int x509_get_sig_alg( const x509_buf *sig_oid, int *sig_alg )
1100{
1101 if( sig_oid->len == 9 &&
1102 memcmp( sig_oid->p, OID_PKCS1, 8 ) == 0 )
1103 {
1104 if( sig_oid->p[8] >= 2 && sig_oid->p[8] <= 5 )
1105 {
1106 *sig_alg = sig_oid->p[8];
1107 return( 0 );
1108 }
1109
1110 if ( sig_oid->p[8] >= 11 && sig_oid->p[8] <= 14 )
1111 {
1112 *sig_alg = sig_oid->p[8];
1113 return( 0 );
1114 }
1115
1116 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1117 }
Paul Bakker400ff6f2011-02-20 10:40:16 +00001118 if( sig_oid->len == 5 &&
1119 memcmp( sig_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
1120 {
1121 *sig_alg = SIG_RSA_SHA1;
1122 return( 0 );
1123 }
Paul Bakker27d66162010-03-17 06:56:01 +00001124
1125 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1126}
1127
Paul Bakkerd98030e2009-05-02 15:13:40 +00001128/*
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001129 * Parse and fill a single X.509 certificate in DER format
Paul Bakker5121ce52009-01-03 21:22:43 +00001130 */
Paul Bakker1d073c52014-07-08 20:15:51 +02001131static int x509parse_crt_der_core( x509_cert *crt, const unsigned char *buf,
1132 size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001133{
Paul Bakker23986e52011-04-24 08:57:21 +00001134 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001135 size_t len;
Paul Bakkerb00ca422012-09-25 12:10:00 +00001136 unsigned char *p, *end, *crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001137
Paul Bakker320a4b52009-03-28 18:52:39 +00001138 /*
1139 * Check for valid input
1140 */
1141 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001142 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker320a4b52009-03-28 18:52:39 +00001143
Paul Bakker96743fc2011-02-12 14:30:57 +00001144 p = (unsigned char *) malloc( len = buflen );
1145
1146 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001147 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001148
1149 memcpy( p, buf, buflen );
1150
Paul Bakker5121ce52009-01-03 21:22:43 +00001151 crt->raw.p = p;
1152 crt->raw.len = len;
1153 end = p + len;
1154
1155 /*
1156 * Certificate ::= SEQUENCE {
1157 * tbsCertificate TBSCertificate,
1158 * signatureAlgorithm AlgorithmIdentifier,
1159 * signatureValue BIT STRING }
1160 */
1161 if( ( ret = asn1_get_tag( &p, end, &len,
1162 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1163 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001164 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001165 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001166 }
1167
Paul Bakkerb00ca422012-09-25 12:10:00 +00001168 if( len > (size_t) ( end - p ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001169 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001170 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001171 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001172 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001173 }
Paul Bakkerb00ca422012-09-25 12:10:00 +00001174 crt_end = p + len;
Paul Bakkerd6d41092013-06-13 09:00:25 +02001175
Paul Bakker5121ce52009-01-03 21:22:43 +00001176 /*
1177 * TBSCertificate ::= SEQUENCE {
1178 */
1179 crt->tbs.p = p;
1180
1181 if( ( ret = asn1_get_tag( &p, end, &len,
1182 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1183 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001184 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001185 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001186 }
1187
1188 end = p + len;
1189 crt->tbs.len = end - crt->tbs.p;
1190
1191 /*
1192 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1193 *
1194 * CertificateSerialNumber ::= INTEGER
1195 *
1196 * signature AlgorithmIdentifier
1197 */
1198 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1199 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1200 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
1201 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001202 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001203 return( ret );
1204 }
1205
1206 crt->version++;
1207
1208 if( crt->version > 3 )
1209 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001210 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001211 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001212 }
1213
Paul Bakker27d66162010-03-17 06:56:01 +00001214 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_alg ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001215 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001216 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001217 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001218 }
1219
1220 /*
1221 * issuer Name
1222 */
1223 crt->issuer_raw.p = p;
1224
1225 if( ( ret = asn1_get_tag( &p, end, &len,
1226 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1227 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001228 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001229 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001230 }
1231
1232 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1233 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001234 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001235 return( ret );
1236 }
1237
1238 crt->issuer_raw.len = p - crt->issuer_raw.p;
1239
1240 /*
1241 * Validity ::= SEQUENCE {
1242 * notBefore Time,
1243 * notAfter Time }
1244 *
1245 */
1246 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1247 &crt->valid_to ) ) != 0 )
1248 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001249 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001250 return( ret );
1251 }
1252
1253 /*
1254 * subject Name
1255 */
1256 crt->subject_raw.p = p;
1257
1258 if( ( ret = asn1_get_tag( &p, end, &len,
1259 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1260 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001261 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001262 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001263 }
1264
Paul Bakkercefb3962012-06-27 11:51:09 +00001265 if( len && ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001266 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001267 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001268 return( ret );
1269 }
1270
1271 crt->subject_raw.len = p - crt->subject_raw.p;
1272
1273 /*
1274 * SubjectPublicKeyInfo ::= SEQUENCE
1275 * algorithm AlgorithmIdentifier,
1276 * subjectPublicKey BIT STRING }
1277 */
1278 if( ( ret = asn1_get_tag( &p, end, &len,
1279 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1280 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001281 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001282 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001283 }
1284
1285 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1286 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1287 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001288 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001289 return( ret );
1290 }
1291
1292 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1293 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001294 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001295 return( ret );
1296 }
1297
1298 crt->rsa.len = mpi_size( &crt->rsa.N );
1299
1300 /*
1301 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1302 * -- If present, version shall be v2 or v3
1303 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1304 * -- If present, version shall be v2 or v3
1305 * extensions [3] EXPLICIT Extensions OPTIONAL
1306 * -- If present, version shall be v3
1307 */
1308 if( crt->version == 2 || crt->version == 3 )
1309 {
1310 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1311 if( ret != 0 )
1312 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001313 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001314 return( ret );
1315 }
1316 }
1317
1318 if( crt->version == 2 || crt->version == 3 )
1319 {
1320 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1321 if( ret != 0 )
1322 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001323 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001324 return( ret );
1325 }
1326 }
1327
1328 if( crt->version == 3 )
1329 {
Paul Bakker74111d32011-01-15 16:57:55 +00001330 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001331 if( ret != 0 )
1332 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001333 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001334 return( ret );
1335 }
1336 }
1337
1338 if( p != end )
1339 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001340 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001341 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001342 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001343 }
1344
Paul Bakkerb00ca422012-09-25 12:10:00 +00001345 end = crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001346
1347 /*
1348 * signatureAlgorithm AlgorithmIdentifier,
1349 * signatureValue BIT STRING
1350 */
1351 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1352 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001353 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001354 return( ret );
1355 }
1356
Paul Bakker535e97d2012-08-23 10:49:55 +00001357 if( crt->sig_oid1.len != crt->sig_oid2.len ||
1358 memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001359 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001360 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001361 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001362 }
1363
1364 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1365 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001366 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001367 return( ret );
1368 }
1369
1370 if( p != end )
1371 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001372 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001373 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001374 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001375 }
1376
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001377 return( 0 );
1378}
1379
1380/*
Paul Bakkerd6d41092013-06-13 09:00:25 +02001381 * Parse one X.509 certificate in DER format from a buffer and add them to a
1382 * chained list
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001383 */
Paul Bakkerd6d41092013-06-13 09:00:25 +02001384int x509parse_crt_der( x509_cert *chain, const unsigned char *buf, size_t buflen )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001385{
Paul Bakkerd6d41092013-06-13 09:00:25 +02001386 int ret;
1387 x509_cert *crt = chain, *prev = NULL;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001388
1389 /*
1390 * Check for valid input
1391 */
1392 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001393 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001394
1395 while( crt->version != 0 && crt->next != NULL )
1396 {
1397 prev = crt;
1398 crt = crt->next;
1399 }
1400
1401 /*
1402 * Add new certificate on the end of the chain if needed.
1403 */
1404 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001405 {
1406 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1407
Paul Bakker7d06ad22009-05-02 15:53:56 +00001408 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001409 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker320a4b52009-03-28 18:52:39 +00001410
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001411 prev = crt;
Paul Bakker7d06ad22009-05-02 15:53:56 +00001412 crt = crt->next;
1413 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001414 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001415
Paul Bakkerd6d41092013-06-13 09:00:25 +02001416 if( ( ret = x509parse_crt_der_core( crt, buf, buflen ) ) != 0 )
1417 {
1418 if( prev )
1419 prev->next = NULL;
1420
1421 if( crt != chain )
1422 free( crt );
1423
1424 return( ret );
1425 }
1426
1427 return( 0 );
1428}
1429
1430/*
1431 * Parse one or more PEM certificates from a buffer and add them to the chained list
1432 */
1433int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
1434{
1435 int ret, success = 0, first_error = 0, total_failed = 0;
1436 int buf_format = X509_FORMAT_DER;
1437
1438 /*
1439 * Check for valid input
1440 */
1441 if( chain == NULL || buf == NULL )
1442 return( POLARSSL_ERR_X509_INVALID_INPUT );
1443
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001444 /*
1445 * Determine buffer content. Buffer contains either one DER certificate or
1446 * one or more PEM certificates.
1447 */
1448#if defined(POLARSSL_PEM_C)
Paul Bakkereae09db2013-06-06 12:35:54 +02001449 if( strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001450 buf_format = X509_FORMAT_PEM;
1451#endif
1452
1453 if( buf_format == X509_FORMAT_DER )
Paul Bakkerd6d41092013-06-13 09:00:25 +02001454 return x509parse_crt_der( chain, buf, buflen );
1455
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001456#if defined(POLARSSL_PEM_C)
1457 if( buf_format == X509_FORMAT_PEM )
1458 {
1459 pem_context pem;
1460
1461 while( buflen > 0 )
1462 {
1463 size_t use_len;
1464 pem_init( &pem );
1465
1466 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02001467 (char *) "-----BEGIN CERTIFICATE-----",
1468 (char *) "-----END CERTIFICATE-----",
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001469 buf, NULL, 0, &use_len );
1470
1471 if( ret == 0 )
1472 {
1473 /*
1474 * Was PEM encoded
1475 */
1476 buflen -= use_len;
1477 buf += use_len;
1478 }
Paul Bakker64171862013-06-06 15:01:18 +02001479 else if( ret == POLARSSL_ERR_PEM_BAD_INPUT_DATA )
1480 {
1481 return( ret );
1482 }
Paul Bakker9255e832013-06-06 14:58:28 +02001483 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001484 {
1485 pem_free( &pem );
1486
Paul Bakker64171862013-06-06 15:01:18 +02001487 /*
1488 * PEM header and footer were found
1489 */
1490 buflen -= use_len;
1491 buf += use_len;
1492
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001493 if( first_error == 0 )
1494 first_error = ret;
1495
Manuel Pégourié-Gonnard7d75ea42014-10-23 15:13:39 +02001496 total_failed++;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001497 continue;
1498 }
1499 else
1500 break;
1501
Paul Bakkerd6d41092013-06-13 09:00:25 +02001502 ret = x509parse_crt_der( chain, pem.buf, pem.buflen );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001503
1504 pem_free( &pem );
1505
1506 if( ret != 0 )
1507 {
1508 /*
Paul Bakkerd6d41092013-06-13 09:00:25 +02001509 * Quit parsing on a memory error
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001510 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001511 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001512 return( ret );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001513
1514 if( first_error == 0 )
1515 first_error = ret;
1516
Paul Bakkerd6d41092013-06-13 09:00:25 +02001517 total_failed++;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001518 continue;
1519 }
1520
1521 success = 1;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001522 }
1523 }
1524#endif
1525
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001526 if( success )
Paul Bakker69e095c2011-12-10 21:55:01 +00001527 return( total_failed );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001528 else if( first_error )
1529 return( first_error );
1530 else
1531 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001532}
1533
1534/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001535 * Parse one or more CRLs and add them to the chained list
1536 */
Paul Bakker23986e52011-04-24 08:57:21 +00001537int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001538{
Paul Bakker23986e52011-04-24 08:57:21 +00001539 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001540 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001541 unsigned char *p, *end;
1542 x509_crl *crl;
Paul Bakker96743fc2011-02-12 14:30:57 +00001543#if defined(POLARSSL_PEM_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00001544 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001545 pem_context pem;
1546#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001547
1548 crl = chain;
1549
1550 /*
1551 * Check for valid input
1552 */
1553 if( crl == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001554 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001555
1556 while( crl->version != 0 && crl->next != NULL )
1557 crl = crl->next;
1558
1559 /*
1560 * Add new CRL on the end of the chain if needed.
1561 */
1562 if ( crl->version != 0 && crl->next == NULL)
1563 {
1564 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1565
Paul Bakker7d06ad22009-05-02 15:53:56 +00001566 if( crl->next == NULL )
1567 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001568 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001569 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001570 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001571
Paul Bakker7d06ad22009-05-02 15:53:56 +00001572 crl = crl->next;
1573 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001574 }
1575
Paul Bakker96743fc2011-02-12 14:30:57 +00001576#if defined(POLARSSL_PEM_C)
1577 pem_init( &pem );
1578 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02001579 (char *) "-----BEGIN X509 CRL-----",
1580 (char *) "-----END X509 CRL-----",
Paul Bakker96743fc2011-02-12 14:30:57 +00001581 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001582
Paul Bakker96743fc2011-02-12 14:30:57 +00001583 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001584 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001585 /*
1586 * Was PEM encoded
1587 */
1588 buflen -= use_len;
1589 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001590
1591 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001592 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001593 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001594 p = pem.buf;
1595 pem.buf = NULL;
1596 len = pem.buflen;
1597 pem_free( &pem );
1598 }
Paul Bakker9255e832013-06-06 14:58:28 +02001599 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker96743fc2011-02-12 14:30:57 +00001600 {
1601 pem_free( &pem );
1602 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001603 }
1604 else
1605 {
1606 /*
1607 * nope, copy the raw DER data
1608 */
1609 p = (unsigned char *) malloc( len = buflen );
1610
1611 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001612 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001613
1614 memcpy( p, buf, buflen );
1615
1616 buflen = 0;
1617 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001618#else
1619 p = (unsigned char *) malloc( len = buflen );
1620
1621 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001622 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001623
1624 memcpy( p, buf, buflen );
1625
1626 buflen = 0;
1627#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001628
1629 crl->raw.p = p;
1630 crl->raw.len = len;
1631 end = p + len;
1632
1633 /*
1634 * CertificateList ::= SEQUENCE {
1635 * tbsCertList TBSCertList,
1636 * signatureAlgorithm AlgorithmIdentifier,
1637 * signatureValue BIT STRING }
1638 */
1639 if( ( ret = asn1_get_tag( &p, end, &len,
1640 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1641 {
1642 x509_crl_free( crl );
1643 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1644 }
1645
Paul Bakker23986e52011-04-24 08:57:21 +00001646 if( len != (size_t) ( end - p ) )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001647 {
1648 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001649 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001650 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1651 }
1652
1653 /*
1654 * TBSCertList ::= SEQUENCE {
1655 */
1656 crl->tbs.p = p;
1657
1658 if( ( ret = asn1_get_tag( &p, end, &len,
1659 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1660 {
1661 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001662 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001663 }
1664
1665 end = p + len;
1666 crl->tbs.len = end - crl->tbs.p;
1667
1668 /*
1669 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1670 * -- if present, MUST be v2
1671 *
1672 * signature AlgorithmIdentifier
1673 */
Paul Bakker3329d1f2011-10-12 09:55:01 +00001674 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
Paul Bakkerd98030e2009-05-02 15:13:40 +00001675 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1676 {
1677 x509_crl_free( crl );
1678 return( ret );
1679 }
1680
1681 crl->version++;
1682
1683 if( crl->version > 2 )
1684 {
1685 x509_crl_free( crl );
1686 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1687 }
1688
Paul Bakker27d66162010-03-17 06:56:01 +00001689 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_alg ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001690 {
1691 x509_crl_free( crl );
1692 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1693 }
1694
1695 /*
1696 * issuer Name
1697 */
1698 crl->issuer_raw.p = p;
1699
1700 if( ( ret = asn1_get_tag( &p, end, &len,
1701 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1702 {
1703 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001704 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001705 }
1706
1707 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1708 {
1709 x509_crl_free( crl );
1710 return( ret );
1711 }
1712
1713 crl->issuer_raw.len = p - crl->issuer_raw.p;
1714
1715 /*
1716 * thisUpdate Time
1717 * nextUpdate Time OPTIONAL
1718 */
Paul Bakker91200182010-02-18 21:26:15 +00001719 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001720 {
1721 x509_crl_free( crl );
1722 return( ret );
1723 }
1724
Paul Bakker91200182010-02-18 21:26:15 +00001725 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001726 {
Paul Bakker9d781402011-05-09 16:17:09 +00001727 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001728 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker9d781402011-05-09 16:17:09 +00001729 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001730 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001731 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001732 x509_crl_free( crl );
1733 return( ret );
1734 }
1735 }
1736
1737 /*
1738 * revokedCertificates SEQUENCE OF SEQUENCE {
1739 * userCertificate CertificateSerialNumber,
1740 * revocationDate Time,
1741 * crlEntryExtensions Extensions OPTIONAL
1742 * -- if present, MUST be v2
1743 * } OPTIONAL
1744 */
1745 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1746 {
1747 x509_crl_free( crl );
1748 return( ret );
1749 }
1750
1751 /*
1752 * crlExtensions EXPLICIT Extensions OPTIONAL
1753 * -- if present, MUST be v2
1754 */
1755 if( crl->version == 2 )
1756 {
1757 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1758
1759 if( ret != 0 )
1760 {
1761 x509_crl_free( crl );
1762 return( ret );
1763 }
1764 }
1765
1766 if( p != end )
1767 {
1768 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001769 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001770 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1771 }
1772
1773 end = crl->raw.p + crl->raw.len;
1774
1775 /*
1776 * signatureAlgorithm AlgorithmIdentifier,
1777 * signatureValue BIT STRING
1778 */
1779 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1780 {
1781 x509_crl_free( crl );
1782 return( ret );
1783 }
1784
Paul Bakker535e97d2012-08-23 10:49:55 +00001785 if( crl->sig_oid1.len != crl->sig_oid2.len ||
1786 memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001787 {
1788 x509_crl_free( crl );
1789 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1790 }
1791
1792 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1793 {
1794 x509_crl_free( crl );
1795 return( ret );
1796 }
1797
1798 if( p != end )
1799 {
1800 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001801 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001802 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1803 }
1804
1805 if( buflen > 0 )
1806 {
1807 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1808
Paul Bakker7d06ad22009-05-02 15:53:56 +00001809 if( crl->next == NULL )
1810 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001811 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001812 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001813 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001814
Paul Bakker7d06ad22009-05-02 15:53:56 +00001815 crl = crl->next;
1816 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001817
1818 return( x509parse_crl( crl, buf, buflen ) );
1819 }
1820
1821 return( 0 );
1822}
1823
Paul Bakker335db3f2011-04-25 15:28:35 +00001824#if defined(POLARSSL_FS_IO)
Paul Bakkerd98030e2009-05-02 15:13:40 +00001825/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001826 * Load all data from a file into a given buffer.
1827 */
Paul Bakker1d073c52014-07-08 20:15:51 +02001828static int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001829{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001830 FILE *f;
Paul Bakkerfe7c24c2013-09-11 11:37:33 +02001831 long size;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001832
Paul Bakkerd98030e2009-05-02 15:13:40 +00001833 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001834 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001835
Paul Bakkerd98030e2009-05-02 15:13:40 +00001836 fseek( f, 0, SEEK_END );
Paul Bakkerfe7c24c2013-09-11 11:37:33 +02001837 if( ( size = ftell( f ) ) == -1 )
1838 {
1839 fclose( f );
1840 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1841 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001842 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001843
Paul Bakkerfe7c24c2013-09-11 11:37:33 +02001844 *n = (size_t) size;
1845
1846 if( *n + 1 == 0 ||
1847 ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
1848 {
1849 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +00001850 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerfe7c24c2013-09-11 11:37:33 +02001851 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001852
Paul Bakkerd98030e2009-05-02 15:13:40 +00001853 if( fread( *buf, 1, *n, f ) != *n )
1854 {
1855 fclose( f );
1856 free( *buf );
Paul Bakker69e095c2011-12-10 21:55:01 +00001857 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001858 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001859
Paul Bakkerd98030e2009-05-02 15:13:40 +00001860 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001861
Paul Bakkerd98030e2009-05-02 15:13:40 +00001862 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001863
Paul Bakkerd98030e2009-05-02 15:13:40 +00001864 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001865}
1866
1867/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001868 * Load one or more certificates and add them to the chained list
1869 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001870int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001871{
1872 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001873 size_t n;
1874 unsigned char *buf;
1875
Paul Bakker69e095c2011-12-10 21:55:01 +00001876 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1877 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001878
Paul Bakker69e095c2011-12-10 21:55:01 +00001879 ret = x509parse_crt( chain, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001880
1881 memset( buf, 0, n + 1 );
1882 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001883
1884 return( ret );
1885}
1886
Paul Bakker8d914582012-06-04 12:46:42 +00001887int x509parse_crtpath( x509_cert *chain, const char *path )
1888{
1889 int ret = 0;
1890#if defined(_WIN32)
Paul Bakker3338b792012-10-01 21:13:10 +00001891 int w_ret;
1892 WCHAR szDir[MAX_PATH];
1893 char filename[MAX_PATH];
1894 char *p;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001895 int len = strlen( path );
Paul Bakker3338b792012-10-01 21:13:10 +00001896
Paul Bakker97872ac2012-11-02 12:53:26 +00001897 WIN32_FIND_DATAW file_data;
Paul Bakker8d914582012-06-04 12:46:42 +00001898 HANDLE hFind;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001899
1900 if( len > MAX_PATH - 3 )
1901 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker8d914582012-06-04 12:46:42 +00001902
Paul Bakker3338b792012-10-01 21:13:10 +00001903 memset( szDir, 0, sizeof(szDir) );
1904 memset( filename, 0, MAX_PATH );
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001905 memcpy( filename, path, len );
1906 filename[len++] = '\\';
1907 p = filename + len;
1908 filename[len++] = '*';
Paul Bakker3338b792012-10-01 21:13:10 +00001909
Paul Bakker40cc9142014-07-07 15:16:47 +02001910 w_ret = MultiByteToWideChar( CP_ACP, 0, filename, len, szDir, MAX_PATH - 3 );
Paul Bakker8d914582012-06-04 12:46:42 +00001911
Paul Bakker97872ac2012-11-02 12:53:26 +00001912 hFind = FindFirstFileW( szDir, &file_data );
Paul Bakker8d914582012-06-04 12:46:42 +00001913 if (hFind == INVALID_HANDLE_VALUE)
1914 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1915
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001916 len = MAX_PATH - len;
Paul Bakker8d914582012-06-04 12:46:42 +00001917 do
1918 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001919 memset( p, 0, len );
Paul Bakker3338b792012-10-01 21:13:10 +00001920
Paul Bakkere4791f32012-06-04 21:29:15 +00001921 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
Paul Bakker8d914582012-06-04 12:46:42 +00001922 continue;
1923
Paul Bakker3338b792012-10-01 21:13:10 +00001924 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
1925 lstrlenW(file_data.cFileName),
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001926 p, len - 1,
1927 NULL, NULL );
Paul Bakker8d914582012-06-04 12:46:42 +00001928
Paul Bakker3338b792012-10-01 21:13:10 +00001929 w_ret = x509parse_crtfile( chain, filename );
1930 if( w_ret < 0 )
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001931 ret++;
1932 else
1933 ret += w_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001934 }
Paul Bakker97872ac2012-11-02 12:53:26 +00001935 while( FindNextFileW( hFind, &file_data ) != 0 );
Paul Bakker8d914582012-06-04 12:46:42 +00001936
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001937 if (GetLastError() != ERROR_NO_MORE_FILES)
1938 ret = POLARSSL_ERR_X509_FILE_IO_ERROR;
Paul Bakker8d914582012-06-04 12:46:42 +00001939
1940 FindClose( hFind );
1941#else
Paul Bakker9ccb2112014-07-07 13:43:31 +02001942#if defined(POLARSSL_HAVE_READDIR_R)
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001943 int t_ret, i;
1944 struct stat sb;
1945 struct dirent entry, *result = NULL;
Paul Bakker8d914582012-06-04 12:46:42 +00001946 char entry_name[255];
1947 DIR *dir = opendir( path );
1948
1949 if( dir == NULL)
1950 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1951
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001952 while( ( t_ret = readdir_r( dir, &entry, &result ) ) == 0 )
Paul Bakker8d914582012-06-04 12:46:42 +00001953 {
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001954 if( result == NULL )
1955 break;
1956
1957 snprintf( entry_name, sizeof(entry_name), "%s/%s", path, entry.d_name );
1958
1959 i = stat( entry_name, &sb );
1960
1961 if( i == -1 )
Paul Bakker88a22642013-09-11 12:14:16 +02001962 {
1963 closedir( dir );
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001964 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker88a22642013-09-11 12:14:16 +02001965 }
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001966
1967 if( !S_ISREG( sb.st_mode ) )
Paul Bakker8d914582012-06-04 12:46:42 +00001968 continue;
1969
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001970 // Ignore parse errors
1971 //
Paul Bakker8d914582012-06-04 12:46:42 +00001972 t_ret = x509parse_crtfile( chain, entry_name );
1973 if( t_ret < 0 )
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001974 ret++;
1975 else
1976 ret += t_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001977 }
1978 closedir( dir );
Paul Bakker9ccb2112014-07-07 13:43:31 +02001979#else /* POLARSSL_HAVE_READDIR_R */
1980 ((void) chain);
1981 ((void) path);
1982 ret = POLARSSL_ERR_X509_FEATURE_UNAVAILABLE;
1983#endif /* POLARSSL_HAVE_READDIR_R */
1984#endif /* _WIN32 */
Paul Bakker8d914582012-06-04 12:46:42 +00001985
1986 return( ret );
1987}
1988
Paul Bakkerd98030e2009-05-02 15:13:40 +00001989/*
1990 * Load one or more CRLs and add them to the chained list
1991 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001992int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001993{
1994 int ret;
1995 size_t n;
1996 unsigned char *buf;
1997
Paul Bakker69e095c2011-12-10 21:55:01 +00001998 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1999 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002000
Paul Bakker27fdf462011-06-09 13:55:13 +00002001 ret = x509parse_crl( chain, buf, n );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002002
2003 memset( buf, 0, n + 1 );
2004 free( buf );
2005
2006 return( ret );
2007}
2008
Paul Bakker5121ce52009-01-03 21:22:43 +00002009/*
Paul Bakker335db3f2011-04-25 15:28:35 +00002010 * Load and parse a private RSA key
2011 */
2012int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
2013{
2014 int ret;
2015 size_t n;
2016 unsigned char *buf;
2017
Paul Bakker69e095c2011-12-10 21:55:01 +00002018 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2019 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002020
2021 if( pwd == NULL )
Paul Bakker27fdf462011-06-09 13:55:13 +00002022 ret = x509parse_key( rsa, buf, n, NULL, 0 );
Paul Bakker335db3f2011-04-25 15:28:35 +00002023 else
Paul Bakker27fdf462011-06-09 13:55:13 +00002024 ret = x509parse_key( rsa, buf, n,
Paul Bakker335db3f2011-04-25 15:28:35 +00002025 (unsigned char *) pwd, strlen( pwd ) );
2026
2027 memset( buf, 0, n + 1 );
2028 free( buf );
2029
2030 return( ret );
2031}
2032
2033/*
2034 * Load and parse a public RSA key
2035 */
2036int x509parse_public_keyfile( rsa_context *rsa, const char *path )
2037{
2038 int ret;
2039 size_t n;
2040 unsigned char *buf;
2041
Paul Bakker69e095c2011-12-10 21:55:01 +00002042 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2043 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002044
Paul Bakker27fdf462011-06-09 13:55:13 +00002045 ret = x509parse_public_key( rsa, buf, n );
Paul Bakker335db3f2011-04-25 15:28:35 +00002046
2047 memset( buf, 0, n + 1 );
2048 free( buf );
2049
2050 return( ret );
2051}
2052#endif /* POLARSSL_FS_IO */
2053
2054/*
Paul Bakker65a19092013-06-06 21:14:58 +02002055 * Parse a PKCS#1 encoded private RSA key
Paul Bakker5121ce52009-01-03 21:22:43 +00002056 */
Paul Bakker65a19092013-06-06 21:14:58 +02002057static int x509parse_key_pkcs1_der( rsa_context *rsa,
2058 const unsigned char *key,
2059 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +00002060{
Paul Bakker23986e52011-04-24 08:57:21 +00002061 int ret;
2062 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00002063 unsigned char *p, *end;
Paul Bakkered56b222011-07-13 11:26:43 +00002064
Paul Bakker96743fc2011-02-12 14:30:57 +00002065 p = (unsigned char *) key;
Paul Bakker96743fc2011-02-12 14:30:57 +00002066 end = p + keylen;
2067
Paul Bakker5121ce52009-01-03 21:22:43 +00002068 /*
Paul Bakker65a19092013-06-06 21:14:58 +02002069 * This function parses the RSAPrivateKey (PKCS#1)
Paul Bakkered56b222011-07-13 11:26:43 +00002070 *
Paul Bakker5121ce52009-01-03 21:22:43 +00002071 * RSAPrivateKey ::= SEQUENCE {
2072 * version Version,
2073 * modulus INTEGER, -- n
2074 * publicExponent INTEGER, -- e
2075 * privateExponent INTEGER, -- d
2076 * prime1 INTEGER, -- p
2077 * prime2 INTEGER, -- q
2078 * exponent1 INTEGER, -- d mod (p-1)
2079 * exponent2 INTEGER, -- d mod (q-1)
2080 * coefficient INTEGER, -- (inverse of q) mod p
2081 * otherPrimeInfos OtherPrimeInfos OPTIONAL
2082 * }
2083 */
2084 if( ( ret = asn1_get_tag( &p, end, &len,
2085 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2086 {
Paul Bakker9d781402011-05-09 16:17:09 +00002087 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002088 }
2089
2090 end = p + len;
2091
2092 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2093 {
Paul Bakker9d781402011-05-09 16:17:09 +00002094 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002095 }
2096
2097 if( rsa->ver != 0 )
2098 {
Paul Bakker9d781402011-05-09 16:17:09 +00002099 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002100 }
2101
2102 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
2103 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
2104 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
2105 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
2106 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
2107 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
2108 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
2109 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
2110 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002111 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002112 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002113 }
2114
2115 rsa->len = mpi_size( &rsa->N );
2116
2117 if( p != end )
2118 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002119 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002120 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00002121 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002122 }
2123
2124 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2125 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002126 rsa_free( rsa );
2127 return( ret );
2128 }
2129
Paul Bakker65a19092013-06-06 21:14:58 +02002130 return( 0 );
2131}
2132
2133/*
2134 * Parse an unencrypted PKCS#8 encoded private RSA key
2135 */
2136static int x509parse_key_pkcs8_unencrypted_der(
2137 rsa_context *rsa,
2138 const unsigned char *key,
2139 size_t keylen )
2140{
2141 int ret;
2142 size_t len;
2143 unsigned char *p, *end;
2144 x509_buf pk_alg_oid;
2145
2146 p = (unsigned char *) key;
2147 end = p + keylen;
2148
2149 /*
2150 * This function parses the PrivatKeyInfo object (PKCS#8)
2151 *
2152 * PrivateKeyInfo ::= SEQUENCE {
2153 * version Version,
2154 * algorithm AlgorithmIdentifier,
2155 * PrivateKey BIT STRING
2156 * }
2157 *
2158 * AlgorithmIdentifier ::= SEQUENCE {
2159 * algorithm OBJECT IDENTIFIER,
2160 * parameters ANY DEFINED BY algorithm OPTIONAL
2161 * }
2162 *
2163 * The PrivateKey BIT STRING is a PKCS#1 RSAPrivateKey
2164 */
2165 if( ( ret = asn1_get_tag( &p, end, &len,
2166 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2167 {
2168 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2169 }
2170
2171 end = p + len;
2172
2173 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2174 {
2175 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2176 }
2177
2178 if( rsa->ver != 0 )
2179 {
2180 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2181 }
2182
2183 if( ( ret = x509_get_alg( &p, end, &pk_alg_oid ) ) != 0 )
2184 {
2185 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2186 }
2187
2188 /*
2189 * only RSA keys handled at this time
2190 */
2191 if( pk_alg_oid.len != 9 ||
2192 memcmp( pk_alg_oid.p, OID_PKCS1_RSA, 9 ) != 0 )
2193 {
2194 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
2195 }
2196
2197 /*
2198 * Get the OCTET STRING and parse the PKCS#1 format inside
2199 */
2200 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2201 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2202
2203 if( ( end - p ) < 1 )
2204 {
2205 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
2206 POLARSSL_ERR_ASN1_OUT_OF_DATA );
2207 }
2208
2209 end = p + len;
2210
2211 if( ( ret = x509parse_key_pkcs1_der( rsa, p, end - p ) ) != 0 )
2212 return( ret );
2213
2214 return( 0 );
2215}
2216
2217/*
Paul Bakkerda7fdbd2013-06-19 11:15:43 +02002218 * Parse an encrypted PKCS#8 encoded private RSA key
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002219 */
2220static int x509parse_key_pkcs8_encrypted_der(
2221 rsa_context *rsa,
2222 const unsigned char *key,
2223 size_t keylen,
2224 const unsigned char *pwd,
2225 size_t pwdlen )
2226{
2227 int ret;
2228 size_t len;
2229 unsigned char *p, *end, *end2;
2230 x509_buf pbe_alg_oid, pbe_params;
2231 unsigned char buf[2048];
2232
2233 memset(buf, 0, 2048);
2234
2235 p = (unsigned char *) key;
2236 end = p + keylen;
2237
Paul Bakker1fd43212013-06-17 15:14:42 +02002238 if( pwdlen == 0 )
2239 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
2240
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002241 /*
2242 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
2243 *
2244 * EncryptedPrivateKeyInfo ::= SEQUENCE {
2245 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
2246 * encryptedData EncryptedData
2247 * }
2248 *
2249 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
2250 *
2251 * EncryptedData ::= OCTET STRING
2252 *
2253 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
2254 */
2255 if( ( ret = asn1_get_tag( &p, end, &len,
2256 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2257 {
2258 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2259 }
2260
2261 end = p + len;
2262
2263 if( ( ret = asn1_get_tag( &p, end, &len,
2264 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2265 {
2266 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2267 }
2268
2269 end2 = p + len;
2270
2271 if( ( ret = asn1_get_tag( &p, end, &pbe_alg_oid.len, ASN1_OID ) ) != 0 )
2272 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2273
2274 pbe_alg_oid.p = p;
2275 p += pbe_alg_oid.len;
2276
2277 /*
2278 * Store the algorithm parameters
2279 */
2280 pbe_params.p = p;
2281 pbe_params.len = end2 - p;
2282 p += pbe_params.len;
2283
2284 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2285 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2286
2287 // buf has been sized to 2048 bytes
2288 if( len > 2048 )
2289 return( POLARSSL_ERR_X509_INVALID_INPUT );
2290
2291 /*
2292 * Decrypt EncryptedData with appropriate PDE
2293 */
Paul Bakker14a222c2013-06-18 16:35:48 +02002294#if defined(POLARSSL_PKCS12_C)
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002295 if( OID_CMP( OID_PKCS12_PBE_SHA1_DES3_EDE_CBC, &pbe_alg_oid ) )
2296 {
Paul Bakker14a222c2013-06-18 16:35:48 +02002297 if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
2298 POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1,
2299 pwd, pwdlen, p, len, buf ) ) != 0 )
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002300 {
Paul Bakker14a222c2013-06-18 16:35:48 +02002301 if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH )
2302 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2303
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002304 return( ret );
2305 }
2306 }
2307 else if( OID_CMP( OID_PKCS12_PBE_SHA1_DES2_EDE_CBC, &pbe_alg_oid ) )
2308 {
Paul Bakker14a222c2013-06-18 16:35:48 +02002309 if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
2310 POLARSSL_CIPHER_DES_EDE_CBC, POLARSSL_MD_SHA1,
2311 pwd, pwdlen, p, len, buf ) ) != 0 )
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002312 {
Paul Bakker14a222c2013-06-18 16:35:48 +02002313 if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH )
2314 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2315
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002316 return( ret );
2317 }
2318 }
2319 else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) )
2320 {
2321 if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params,
2322 PKCS12_PBE_DECRYPT,
2323 pwd, pwdlen,
2324 p, len, buf ) ) != 0 )
2325 {
2326 return( ret );
2327 }
Paul Bakker14a222c2013-06-18 16:35:48 +02002328
2329 // Best guess for password mismatch when using RC4. If first tag is
2330 // not ASN1_CONSTRUCTED | ASN1_SEQUENCE
2331 //
2332 if( *buf != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
2333 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002334 }
Paul Bakker14a222c2013-06-18 16:35:48 +02002335 else
2336#endif /* POLARSSL_PKCS12_C */
Paul Bakker1fd43212013-06-17 15:14:42 +02002337#if defined(POLARSSL_PKCS5_C)
Paul Bakker14a222c2013-06-18 16:35:48 +02002338 if( OID_CMP( OID_PKCS5_PBES2, &pbe_alg_oid ) )
Paul Bakker1fd43212013-06-17 15:14:42 +02002339 {
2340 if( ( ret = pkcs5_pbes2( &pbe_params, PKCS5_DECRYPT, pwd, pwdlen,
2341 p, len, buf ) ) != 0 )
2342 {
2343 if( ret == POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH )
2344 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2345
2346 return( ret );
2347 }
2348 }
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002349 else
Paul Bakker14a222c2013-06-18 16:35:48 +02002350#endif /* POLARSSL_PKCS5_C */
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002351 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
2352
2353 return x509parse_key_pkcs8_unencrypted_der( rsa, buf, len );
2354}
2355
2356/*
Paul Bakker65a19092013-06-06 21:14:58 +02002357 * Parse a private RSA key
2358 */
2359int x509parse_key( rsa_context *rsa, const unsigned char *key, size_t keylen,
2360 const unsigned char *pwd, size_t pwdlen )
2361{
2362 int ret;
2363
Paul Bakker96743fc2011-02-12 14:30:57 +00002364#if defined(POLARSSL_PEM_C)
Paul Bakker65a19092013-06-06 21:14:58 +02002365 size_t len;
2366 pem_context pem;
2367
2368 pem_init( &pem );
2369 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02002370 (char *) "-----BEGIN RSA PRIVATE KEY-----",
2371 (char *) "-----END RSA PRIVATE KEY-----",
Paul Bakker65a19092013-06-06 21:14:58 +02002372 key, pwd, pwdlen, &len );
2373 if( ret == 0 )
2374 {
2375 if( ( ret = x509parse_key_pkcs1_der( rsa, pem.buf, pem.buflen ) ) != 0 )
2376 {
2377 rsa_free( rsa );
2378 }
2379
2380 pem_free( &pem );
2381 return( ret );
2382 }
Paul Bakkerb495d3a2013-06-17 15:58:04 +02002383 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
2384 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2385 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
2386 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
Paul Bakker65a19092013-06-06 21:14:58 +02002387 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker65a19092013-06-06 21:14:58 +02002388 return( ret );
Paul Bakker65a19092013-06-06 21:14:58 +02002389
2390 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02002391 (char *) "-----BEGIN PRIVATE KEY-----",
2392 (char *) "-----END PRIVATE KEY-----",
Paul Bakker65a19092013-06-06 21:14:58 +02002393 key, NULL, 0, &len );
2394 if( ret == 0 )
2395 {
2396 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa,
2397 pem.buf, pem.buflen ) ) != 0 )
2398 {
2399 rsa_free( rsa );
2400 }
2401
2402 pem_free( &pem );
2403 return( ret );
2404 }
2405 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker65a19092013-06-06 21:14:58 +02002406 return( ret );
Paul Bakker65a19092013-06-06 21:14:58 +02002407
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002408 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02002409 (char *) "-----BEGIN ENCRYPTED PRIVATE KEY-----",
2410 (char *) "-----END ENCRYPTED PRIVATE KEY-----",
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002411 key, NULL, 0, &len );
2412 if( ret == 0 )
2413 {
2414 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa,
2415 pem.buf, pem.buflen,
2416 pwd, pwdlen ) ) != 0 )
2417 {
2418 rsa_free( rsa );
2419 }
2420
2421 pem_free( &pem );
2422 return( ret );
2423 }
2424 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002425 return( ret );
Paul Bakker65a19092013-06-06 21:14:58 +02002426#else
2427 ((void) pwd);
2428 ((void) pwdlen);
2429#endif /* POLARSSL_PEM_C */
2430
2431 // At this point we only know it's not a PEM formatted key. Could be any
2432 // of the known DER encoded private key formats
2433 //
2434 // We try the different DER format parsers to see if one passes without
2435 // error
2436 //
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002437 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa, key, keylen,
2438 pwd, pwdlen ) ) == 0 )
Paul Bakker65a19092013-06-06 21:14:58 +02002439 {
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002440 return( 0 );
Paul Bakker65a19092013-06-06 21:14:58 +02002441 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002442
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002443 rsa_free( rsa );
Paul Bakker1fd43212013-06-17 15:14:42 +02002444
2445 if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH )
2446 {
2447 return( ret );
2448 }
2449
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002450 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa, key, keylen ) ) == 0 )
2451 return( 0 );
2452
2453 rsa_free( rsa );
Paul Bakker1fd43212013-06-17 15:14:42 +02002454
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002455 if( ( ret = x509parse_key_pkcs1_der( rsa, key, keylen ) ) == 0 )
2456 return( 0 );
2457
2458 rsa_free( rsa );
Paul Bakker1fd43212013-06-17 15:14:42 +02002459
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002460 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00002461}
2462
2463/*
Paul Bakker53019ae2011-03-25 13:58:48 +00002464 * Parse a public RSA key
2465 */
Paul Bakker23986e52011-04-24 08:57:21 +00002466int x509parse_public_key( rsa_context *rsa, const unsigned char *key, size_t keylen )
Paul Bakker53019ae2011-03-25 13:58:48 +00002467{
Paul Bakker23986e52011-04-24 08:57:21 +00002468 int ret;
2469 size_t len;
Paul Bakker53019ae2011-03-25 13:58:48 +00002470 unsigned char *p, *end;
2471 x509_buf alg_oid;
2472#if defined(POLARSSL_PEM_C)
2473 pem_context pem;
2474
2475 pem_init( &pem );
2476 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02002477 (char *) "-----BEGIN PUBLIC KEY-----",
2478 (char *) "-----END PUBLIC KEY-----",
Paul Bakker53019ae2011-03-25 13:58:48 +00002479 key, NULL, 0, &len );
2480
2481 if( ret == 0 )
2482 {
2483 /*
2484 * Was PEM encoded
2485 */
2486 keylen = pem.buflen;
2487 }
Paul Bakker9255e832013-06-06 14:58:28 +02002488 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker53019ae2011-03-25 13:58:48 +00002489 {
2490 pem_free( &pem );
2491 return( ret );
2492 }
2493
2494 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2495#else
2496 p = (unsigned char *) key;
2497#endif
2498 end = p + keylen;
2499
2500 /*
2501 * PublicKeyInfo ::= SEQUENCE {
2502 * algorithm AlgorithmIdentifier,
2503 * PublicKey BIT STRING
2504 * }
2505 *
2506 * AlgorithmIdentifier ::= SEQUENCE {
2507 * algorithm OBJECT IDENTIFIER,
2508 * parameters ANY DEFINED BY algorithm OPTIONAL
2509 * }
2510 *
2511 * RSAPublicKey ::= SEQUENCE {
2512 * modulus INTEGER, -- n
2513 * publicExponent INTEGER -- e
2514 * }
2515 */
2516
2517 if( ( ret = asn1_get_tag( &p, end, &len,
2518 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2519 {
2520#if defined(POLARSSL_PEM_C)
2521 pem_free( &pem );
2522#endif
2523 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002524 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002525 }
2526
2527 if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
2528 {
2529#if defined(POLARSSL_PEM_C)
2530 pem_free( &pem );
2531#endif
2532 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002533 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002534 }
2535
2536 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
2537 {
2538#if defined(POLARSSL_PEM_C)
2539 pem_free( &pem );
2540#endif
2541 rsa_free( rsa );
2542 return( ret );
2543 }
2544
2545 rsa->len = mpi_size( &rsa->N );
2546
2547#if defined(POLARSSL_PEM_C)
2548 pem_free( &pem );
2549#endif
2550
2551 return( 0 );
2552}
2553
Paul Bakkereaa89f82011-04-04 21:36:15 +00002554#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00002555/*
Paul Bakker1b57b062011-01-06 15:48:19 +00002556 * Parse DHM parameters
2557 */
Paul Bakker23986e52011-04-24 08:57:21 +00002558int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
Paul Bakker1b57b062011-01-06 15:48:19 +00002559{
Paul Bakker23986e52011-04-24 08:57:21 +00002560 int ret;
2561 size_t len;
Paul Bakker1b57b062011-01-06 15:48:19 +00002562 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00002563#if defined(POLARSSL_PEM_C)
2564 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00002565
Paul Bakker96743fc2011-02-12 14:30:57 +00002566 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00002567
Paul Bakker96743fc2011-02-12 14:30:57 +00002568 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02002569 (char *) "-----BEGIN DH PARAMETERS-----",
2570 (char *) "-----END DH PARAMETERS-----",
Paul Bakker96743fc2011-02-12 14:30:57 +00002571 dhmin, NULL, 0, &dhminlen );
2572
2573 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00002574 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002575 /*
2576 * Was PEM encoded
2577 */
2578 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00002579 }
Paul Bakker9255e832013-06-06 14:58:28 +02002580 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00002581 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002582 pem_free( &pem );
2583 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002584 }
2585
Paul Bakker96743fc2011-02-12 14:30:57 +00002586 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
2587#else
2588 p = (unsigned char *) dhmin;
2589#endif
2590 end = p + dhminlen;
2591
Paul Bakker1b57b062011-01-06 15:48:19 +00002592 memset( dhm, 0, sizeof( dhm_context ) );
2593
Paul Bakker1b57b062011-01-06 15:48:19 +00002594 /*
2595 * DHParams ::= SEQUENCE {
2596 * prime INTEGER, -- P
2597 * generator INTEGER, -- g
2598 * }
2599 */
2600 if( ( ret = asn1_get_tag( &p, end, &len,
2601 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2602 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002603#if defined(POLARSSL_PEM_C)
2604 pem_free( &pem );
2605#endif
Paul Bakker9d781402011-05-09 16:17:09 +00002606 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002607 }
2608
2609 end = p + len;
2610
2611 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
2612 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
2613 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002614#if defined(POLARSSL_PEM_C)
2615 pem_free( &pem );
2616#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002617 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002618 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002619 }
2620
2621 if( p != end )
2622 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002623#if defined(POLARSSL_PEM_C)
2624 pem_free( &pem );
2625#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002626 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002627 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker1b57b062011-01-06 15:48:19 +00002628 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
2629 }
2630
Paul Bakker96743fc2011-02-12 14:30:57 +00002631#if defined(POLARSSL_PEM_C)
2632 pem_free( &pem );
2633#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002634
2635 return( 0 );
2636}
2637
Paul Bakker335db3f2011-04-25 15:28:35 +00002638#if defined(POLARSSL_FS_IO)
Paul Bakker1b57b062011-01-06 15:48:19 +00002639/*
2640 * Load and parse a private RSA key
2641 */
2642int x509parse_dhmfile( dhm_context *dhm, const char *path )
2643{
2644 int ret;
2645 size_t n;
2646 unsigned char *buf;
2647
Paul Bakker69e095c2011-12-10 21:55:01 +00002648 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
2649 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002650
Paul Bakker27fdf462011-06-09 13:55:13 +00002651 ret = x509parse_dhm( dhm, buf, n );
Paul Bakker1b57b062011-01-06 15:48:19 +00002652
2653 memset( buf, 0, n + 1 );
2654 free( buf );
2655
2656 return( ret );
2657}
Paul Bakker335db3f2011-04-25 15:28:35 +00002658#endif /* POLARSSL_FS_IO */
Paul Bakkereaa89f82011-04-04 21:36:15 +00002659#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00002660
Paul Bakker5121ce52009-01-03 21:22:43 +00002661#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002662#include <stdarg.h>
2663
2664#if !defined vsnprintf
2665#define vsnprintf _vsnprintf
2666#endif // vsnprintf
2667
2668/*
2669 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2670 * Result value is not size of buffer needed, but -1 if no fit is possible.
2671 *
2672 * This fuction tries to 'fix' this by at least suggesting enlarging the
2673 * size by 20.
2674 */
2675int compat_snprintf(char *str, size_t size, const char *format, ...)
2676{
2677 va_list ap;
2678 int res = -1;
2679
2680 va_start( ap, format );
2681
2682 res = vsnprintf( str, size, format, ap );
2683
2684 va_end( ap );
2685
2686 // No quick fix possible
2687 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00002688 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002689
2690 return res;
2691}
2692
2693#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002694#endif
2695
Paul Bakkerd98030e2009-05-02 15:13:40 +00002696#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2697
2698#define SAFE_SNPRINTF() \
2699{ \
2700 if( ret == -1 ) \
2701 return( -1 ); \
2702 \
Paul Bakker23986e52011-04-24 08:57:21 +00002703 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002704 p[n - 1] = '\0'; \
2705 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2706 } \
2707 \
Paul Bakker23986e52011-04-24 08:57:21 +00002708 n -= (unsigned int) ret; \
2709 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002710}
2711
Paul Bakker5121ce52009-01-03 21:22:43 +00002712/*
2713 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002714 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002715 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002716int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002717{
Paul Bakker23986e52011-04-24 08:57:21 +00002718 int ret;
2719 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002720 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002721 const x509_name *name;
Paul Bakker5121ce52009-01-03 21:22:43 +00002722 char s[128], *p;
2723
2724 memset( s, 0, sizeof( s ) );
2725
2726 name = dn;
2727 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002728 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002729
2730 while( name != NULL )
2731 {
Paul Bakkercefb3962012-06-27 11:51:09 +00002732 if( !name->oid.p )
2733 {
2734 name = name->next;
2735 continue;
2736 }
2737
Paul Bakker74111d32011-01-15 16:57:55 +00002738 if( name != dn )
2739 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002740 ret = snprintf( p, n, ", " );
2741 SAFE_SNPRINTF();
2742 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002743
Paul Bakker535e97d2012-08-23 10:49:55 +00002744 if( name->oid.len == 3 &&
2745 memcmp( name->oid.p, OID_X520, 2 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002746 {
2747 switch( name->oid.p[2] )
2748 {
2749 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002750 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002751
2752 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002753 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002754
2755 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002756 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002757
2758 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002759 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002760
2761 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002762 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002763
2764 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002765 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002766
2767 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002768 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002769 name->oid.p[2] );
2770 break;
2771 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002772 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002773 }
Paul Bakker535e97d2012-08-23 10:49:55 +00002774 else if( name->oid.len == 9 &&
2775 memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002776 {
2777 switch( name->oid.p[8] )
2778 {
2779 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002780 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002781
2782 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002783 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002784 name->oid.p[8] );
2785 break;
2786 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002787 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002788 }
2789 else
Paul Bakker74111d32011-01-15 16:57:55 +00002790 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002791 ret = snprintf( p, n, "\?\?=" );
Paul Bakker74111d32011-01-15 16:57:55 +00002792 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002793 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002794
2795 for( i = 0; i < name->val.len; i++ )
2796 {
Paul Bakker27fdf462011-06-09 13:55:13 +00002797 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002798 break;
2799
2800 c = name->val.p[i];
2801 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2802 s[i] = '?';
2803 else s[i] = c;
2804 }
2805 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002806 ret = snprintf( p, n, "%s", s );
2807 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002808 name = name->next;
2809 }
2810
Paul Bakker23986e52011-04-24 08:57:21 +00002811 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002812}
2813
2814/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002815 * Store the serial in printable form into buf; no more
2816 * than size characters will be written
2817 */
2818int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2819{
Paul Bakker23986e52011-04-24 08:57:21 +00002820 int ret;
2821 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00002822 char *p;
2823
2824 p = buf;
2825 n = size;
2826
2827 nr = ( serial->len <= 32 )
Paul Bakker03c7c252011-11-25 12:37:37 +00002828 ? serial->len : 28;
Paul Bakkerdd476992011-01-16 21:34:59 +00002829
2830 for( i = 0; i < nr; i++ )
2831 {
Paul Bakker93048802011-12-05 14:38:06 +00002832 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002833 continue;
2834
Paul Bakkerdd476992011-01-16 21:34:59 +00002835 ret = snprintf( p, n, "%02X%s",
2836 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2837 SAFE_SNPRINTF();
2838 }
2839
Paul Bakker03c7c252011-11-25 12:37:37 +00002840 if( nr != serial->len )
2841 {
2842 ret = snprintf( p, n, "...." );
2843 SAFE_SNPRINTF();
2844 }
2845
Paul Bakker23986e52011-04-24 08:57:21 +00002846 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00002847}
2848
2849/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002850 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002851 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002852int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2853 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002854{
Paul Bakker23986e52011-04-24 08:57:21 +00002855 int ret;
2856 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002857 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00002858
2859 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002860 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002861
Paul Bakkerd98030e2009-05-02 15:13:40 +00002862 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002863 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002864 SAFE_SNPRINTF();
2865 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002866 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002867 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002868
Paul Bakkerdd476992011-01-16 21:34:59 +00002869 ret = x509parse_serial_gets( p, n, &crt->serial);
2870 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002871
Paul Bakkerd98030e2009-05-02 15:13:40 +00002872 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2873 SAFE_SNPRINTF();
2874 ret = x509parse_dn_gets( p, n, &crt->issuer );
2875 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002876
Paul Bakkerd98030e2009-05-02 15:13:40 +00002877 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2878 SAFE_SNPRINTF();
2879 ret = x509parse_dn_gets( p, n, &crt->subject );
2880 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002881
Paul Bakkerd98030e2009-05-02 15:13:40 +00002882 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002883 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2884 crt->valid_from.year, crt->valid_from.mon,
2885 crt->valid_from.day, crt->valid_from.hour,
2886 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002887 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002888
Paul Bakkerd98030e2009-05-02 15:13:40 +00002889 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002890 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2891 crt->valid_to.year, crt->valid_to.mon,
2892 crt->valid_to.day, crt->valid_to.hour,
2893 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002894 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002895
Paul Bakkerd98030e2009-05-02 15:13:40 +00002896 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2897 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002898
Paul Bakker27d66162010-03-17 06:56:01 +00002899 switch( crt->sig_alg )
Paul Bakker5121ce52009-01-03 21:22:43 +00002900 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002901 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2902 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2903 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2904 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2905 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2906 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2907 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2908 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2909 default: ret = snprintf( p, n, "???" ); break;
2910 }
2911 SAFE_SNPRINTF();
2912
2913 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
Paul Bakker5c2364c2012-10-01 14:41:15 +00002914 (int) crt->rsa.N.n * (int) sizeof( t_uint ) * 8 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002915 SAFE_SNPRINTF();
2916
Paul Bakker23986e52011-04-24 08:57:21 +00002917 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002918}
2919
Paul Bakker74111d32011-01-15 16:57:55 +00002920/*
2921 * Return an informational string describing the given OID
2922 */
2923const char *x509_oid_get_description( x509_buf *oid )
2924{
2925 if ( oid == NULL )
2926 return ( NULL );
2927
2928 else if( OID_CMP( OID_SERVER_AUTH, oid ) )
2929 return( STRING_SERVER_AUTH );
2930
2931 else if( OID_CMP( OID_CLIENT_AUTH, oid ) )
2932 return( STRING_CLIENT_AUTH );
2933
2934 else if( OID_CMP( OID_CODE_SIGNING, oid ) )
2935 return( STRING_CODE_SIGNING );
2936
2937 else if( OID_CMP( OID_EMAIL_PROTECTION, oid ) )
2938 return( STRING_EMAIL_PROTECTION );
2939
2940 else if( OID_CMP( OID_TIME_STAMPING, oid ) )
2941 return( STRING_TIME_STAMPING );
2942
2943 else if( OID_CMP( OID_OCSP_SIGNING, oid ) )
2944 return( STRING_OCSP_SIGNING );
2945
2946 return( NULL );
2947}
2948
2949/* Return the x.y.z.... style numeric string for the given OID */
2950int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2951{
Paul Bakker23986e52011-04-24 08:57:21 +00002952 int ret;
2953 size_t i, n;
Paul Bakker74111d32011-01-15 16:57:55 +00002954 unsigned int value;
2955 char *p;
2956
2957 p = buf;
2958 n = size;
2959
2960 /* First byte contains first two dots */
2961 if( oid->len > 0 )
2962 {
2963 ret = snprintf( p, n, "%d.%d", oid->p[0]/40, oid->p[0]%40 );
2964 SAFE_SNPRINTF();
2965 }
2966
2967 /* TODO: value can overflow in value. */
2968 value = 0;
Paul Bakker23986e52011-04-24 08:57:21 +00002969 for( i = 1; i < oid->len; i++ )
Paul Bakker74111d32011-01-15 16:57:55 +00002970 {
2971 value <<= 7;
2972 value += oid->p[i] & 0x7F;
2973
2974 if( !( oid->p[i] & 0x80 ) )
2975 {
2976 /* Last byte */
2977 ret = snprintf( p, n, ".%d", value );
2978 SAFE_SNPRINTF();
2979 value = 0;
2980 }
2981 }
2982
Paul Bakker23986e52011-04-24 08:57:21 +00002983 return( (int) ( size - n ) );
Paul Bakker74111d32011-01-15 16:57:55 +00002984}
2985
Paul Bakkerd98030e2009-05-02 15:13:40 +00002986/*
2987 * Return an informational string about the CRL.
2988 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002989int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2990 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002991{
Paul Bakker23986e52011-04-24 08:57:21 +00002992 int ret;
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002993 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002994 char *p;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002995 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002996
2997 p = buf;
2998 n = size;
2999
3000 ret = snprintf( p, n, "%sCRL version : %d",
3001 prefix, crl->version );
3002 SAFE_SNPRINTF();
3003
3004 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
3005 SAFE_SNPRINTF();
3006 ret = x509parse_dn_gets( p, n, &crl->issuer );
3007 SAFE_SNPRINTF();
3008
3009 ret = snprintf( p, n, "\n%sthis update : " \
3010 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3011 crl->this_update.year, crl->this_update.mon,
3012 crl->this_update.day, crl->this_update.hour,
3013 crl->this_update.min, crl->this_update.sec );
3014 SAFE_SNPRINTF();
3015
3016 ret = snprintf( p, n, "\n%snext update : " \
3017 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3018 crl->next_update.year, crl->next_update.mon,
3019 crl->next_update.day, crl->next_update.hour,
3020 crl->next_update.min, crl->next_update.sec );
3021 SAFE_SNPRINTF();
3022
3023 entry = &crl->entry;
3024
3025 ret = snprintf( p, n, "\n%sRevoked certificates:",
3026 prefix );
3027 SAFE_SNPRINTF();
3028
Paul Bakker9be19372009-07-27 20:21:53 +00003029 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003030 {
3031 ret = snprintf( p, n, "\n%sserial number: ",
3032 prefix );
3033 SAFE_SNPRINTF();
3034
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003035 ret = x509parse_serial_gets( p, n, &entry->serial);
3036 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003037
Paul Bakkerd98030e2009-05-02 15:13:40 +00003038 ret = snprintf( p, n, " revocation date: " \
3039 "%04d-%02d-%02d %02d:%02d:%02d",
3040 entry->revocation_date.year, entry->revocation_date.mon,
3041 entry->revocation_date.day, entry->revocation_date.hour,
3042 entry->revocation_date.min, entry->revocation_date.sec );
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003043 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003044
3045 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003046 }
3047
Paul Bakkerd98030e2009-05-02 15:13:40 +00003048 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
3049 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003050
Paul Bakker27d66162010-03-17 06:56:01 +00003051 switch( crl->sig_alg )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003052 {
3053 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
3054 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
3055 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
3056 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
3057 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
3058 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
3059 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
3060 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
3061 default: ret = snprintf( p, n, "???" ); break;
3062 }
3063 SAFE_SNPRINTF();
3064
Paul Bakker1e27bb22009-07-19 20:25:25 +00003065 ret = snprintf( p, n, "\n" );
3066 SAFE_SNPRINTF();
3067
Paul Bakker23986e52011-04-24 08:57:21 +00003068 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003069}
3070
3071/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00003072 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00003073 */
Paul Bakker0d844dd2014-07-07 17:44:14 +02003074static void x509_get_current_time( x509_time *now )
Paul Bakker5121ce52009-01-03 21:22:43 +00003075{
Paul Bakkercce9d772011-11-18 14:26:47 +00003076#if defined(_WIN32)
3077 SYSTEMTIME st;
3078
Paul Bakkerf48de952014-07-08 14:39:41 +02003079 GetSystemTime(&st);
Paul Bakkercce9d772011-11-18 14:26:47 +00003080
Paul Bakker0d844dd2014-07-07 17:44:14 +02003081 now->year = st.wYear;
3082 now->mon = st.wMonth;
3083 now->day = st.wDay;
3084 now->hour = st.wHour;
3085 now->min = st.wMinute;
3086 now->sec = st.wSecond;
Paul Bakkercce9d772011-11-18 14:26:47 +00003087#else
Paul Bakker358a8412014-07-08 12:14:37 +02003088 struct tm lt;
Paul Bakker5121ce52009-01-03 21:22:43 +00003089 time_t tt;
3090
3091 tt = time( NULL );
Paul Bakkerf48de952014-07-08 14:39:41 +02003092 gmtime_r( &tt, &lt );
Paul Bakker5121ce52009-01-03 21:22:43 +00003093
Paul Bakker358a8412014-07-08 12:14:37 +02003094 now->year = lt.tm_year + 1900;
3095 now->mon = lt.tm_mon + 1;
3096 now->day = lt.tm_mday;
3097 now->hour = lt.tm_hour;
3098 now->min = lt.tm_min;
3099 now->sec = lt.tm_sec;
Paul Bakkercce9d772011-11-18 14:26:47 +00003100#endif
Paul Bakker0d844dd2014-07-07 17:44:14 +02003101}
Paul Bakkercce9d772011-11-18 14:26:47 +00003102
Paul Bakker0d844dd2014-07-07 17:44:14 +02003103/*
3104 * Return 0 if before <= after, 1 otherwise
3105 */
3106static int x509_check_time( const x509_time *before, const x509_time *after )
3107{
3108 if( before->year > after->year )
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 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003113 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003114
Paul Bakker0d844dd2014-07-07 17:44:14 +02003115 if( before->year == after->year &&
3116 before->mon == after->mon &&
3117 before->day > after->day )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003118 return( 1 );
3119
Paul Bakker0d844dd2014-07-07 17:44:14 +02003120 if( before->year == after->year &&
3121 before->mon == after->mon &&
3122 before->day == after->day &&
3123 before->hour > after->hour )
Paul Bakkerb6194992011-01-16 21:40:22 +00003124 return( 1 );
3125
Paul Bakker0d844dd2014-07-07 17:44:14 +02003126 if( before->year == after->year &&
3127 before->mon == after->mon &&
3128 before->day == after->day &&
3129 before->hour == after->hour &&
3130 before->min > after->min )
Paul Bakkerb6194992011-01-16 21:40:22 +00003131 return( 1 );
3132
Paul Bakker0d844dd2014-07-07 17:44:14 +02003133 if( before->year == after->year &&
3134 before->mon == after->mon &&
3135 before->day == after->day &&
3136 before->hour == after->hour &&
3137 before->min == after->min &&
3138 before->sec > after->sec )
Paul Bakkerb6194992011-01-16 21:40:22 +00003139 return( 1 );
3140
Paul Bakker40ea7de2009-05-03 10:18:48 +00003141 return( 0 );
3142}
3143
Paul Bakker0d844dd2014-07-07 17:44:14 +02003144int x509parse_time_expired( const x509_time *to )
3145{
3146 x509_time now;
3147
3148 x509_get_current_time( &now );
3149
3150 return( x509_check_time( &now, to ) );
3151}
3152
3153int x509parse_time_future( const x509_time *from )
3154{
3155 x509_time now;
3156
3157 x509_get_current_time( &now );
3158
3159 return( x509_check_time( from, &now ) );
3160}
3161
Paul Bakker40ea7de2009-05-03 10:18:48 +00003162/*
3163 * Return 1 if the certificate is revoked, or 0 otherwise.
3164 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003165int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003166{
Paul Bakkerff60ee62010-03-16 21:09:09 +00003167 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00003168
3169 while( cur != NULL && cur->serial.len != 0 )
3170 {
Paul Bakkera056efc2011-01-16 21:38:35 +00003171 if( crt->serial.len == cur->serial.len &&
3172 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003173 {
3174 if( x509parse_time_expired( &cur->revocation_date ) )
3175 return( 1 );
3176 }
3177
3178 cur = cur->next;
3179 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003180
3181 return( 0 );
3182}
3183
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003184/*
3185 * Wrapper for x509 hashes.
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003186 */
Paul Bakker23986e52011-04-24 08:57:21 +00003187static void x509_hash( const unsigned char *in, size_t len, int alg,
Paul Bakker5121ce52009-01-03 21:22:43 +00003188 unsigned char *out )
3189{
3190 switch( alg )
3191 {
Paul Bakker40e46942009-01-03 21:51:57 +00003192#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003193 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003194#endif
Paul Bakker40e46942009-01-03 21:51:57 +00003195#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003196 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003197#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003198#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003199 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003200#endif
3201#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003202 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003203#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00003204#if defined(POLARSSL_SHA2_C)
3205 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
3206 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
3207#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00003208#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003209 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
3210 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
3211#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003212 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003213 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003214 break;
3215 }
3216}
3217
3218/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00003219 * Check that the given certificate is valid accoring to the CRL.
3220 */
3221static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
3222 x509_crl *crl_list)
3223{
3224 int flags = 0;
3225 int hash_id;
3226 unsigned char hash[64];
3227
Paul Bakker915275b2012-09-28 07:10:55 +00003228 if( ca == NULL )
3229 return( flags );
3230
Paul Bakker76fd75a2011-01-16 21:12:10 +00003231 /*
3232 * TODO: What happens if no CRL is present?
3233 * Suggestion: Revocation state should be unknown if no CRL is present.
3234 * For backwards compatibility this is not yet implemented.
3235 */
3236
Paul Bakker915275b2012-09-28 07:10:55 +00003237 while( crl_list != NULL )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003238 {
Paul Bakker915275b2012-09-28 07:10:55 +00003239 if( crl_list->version == 0 ||
3240 crl_list->issuer_raw.len != ca->subject_raw.len ||
Paul Bakker76fd75a2011-01-16 21:12:10 +00003241 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
3242 crl_list->issuer_raw.len ) != 0 )
3243 {
3244 crl_list = crl_list->next;
3245 continue;
3246 }
3247
3248 /*
3249 * Check if CRL is correctly signed by the trusted CA
3250 */
3251 hash_id = crl_list->sig_alg;
3252
3253 x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
3254
Paul Bakker43f97992013-09-23 11:23:31 +02003255 if( !rsa_pkcs1_verify( &ca->rsa, NULL, NULL, RSA_PUBLIC, hash_id,
Paul Bakker76fd75a2011-01-16 21:12:10 +00003256 0, hash, crl_list->sig.p ) == 0 )
3257 {
3258 /*
3259 * CRL is not trusted
3260 */
3261 flags |= BADCRL_NOT_TRUSTED;
3262 break;
3263 }
3264
3265 /*
3266 * Check for validity of CRL (Do not drop out)
3267 */
3268 if( x509parse_time_expired( &crl_list->next_update ) )
3269 flags |= BADCRL_EXPIRED;
3270
Paul Bakker50a5c532014-07-08 10:59:10 +02003271 if( x509parse_time_future( &crl_list->this_update ) )
3272 flags |= BADCRL_FUTURE;
3273
Paul Bakker76fd75a2011-01-16 21:12:10 +00003274 /*
3275 * Check if certificate is revoked
3276 */
3277 if( x509parse_revoked(crt, crl_list) )
3278 {
3279 flags |= BADCERT_REVOKED;
3280 break;
3281 }
3282
3283 crl_list = crl_list->next;
3284 }
3285 return flags;
3286}
3287
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003288// Equal == 0, inequal == 1
3289static int x509_name_cmp( const void *s1, const void *s2, size_t len )
3290{
3291 size_t i;
3292 unsigned char diff;
3293 const unsigned char *n1 = s1, *n2 = s2;
3294
3295 for( i = 0; i < len; i++ )
3296 {
3297 diff = n1[i] ^ n2[i];
3298
Paul Bakkerc941adb2014-07-07 14:17:24 +02003299 if( diff == 0 )
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003300 continue;
3301
Paul Bakkerc941adb2014-07-07 14:17:24 +02003302 if( diff == 32 &&
3303 ( ( n1[i] >= 'a' && n1[i] <= 'z' ) ||
3304 ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) )
3305 {
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003306 continue;
Paul Bakkerc941adb2014-07-07 14:17:24 +02003307 }
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003308
3309 return( 1 );
3310 }
3311
3312 return( 0 );
3313}
3314
Paul Bakker1d073c52014-07-08 20:15:51 +02003315static int x509_wildcard_verify( const char *cn, x509_buf *name )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003316{
3317 size_t i;
3318 size_t cn_idx = 0;
3319
Paul Bakker57b12982012-02-11 17:38:38 +00003320 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003321 return( 0 );
3322
3323 for( i = 0; i < strlen( cn ); ++i )
3324 {
3325 if( cn[i] == '.' )
3326 {
3327 cn_idx = i;
3328 break;
3329 }
3330 }
3331
3332 if( cn_idx == 0 )
3333 return( 0 );
3334
Paul Bakker535e97d2012-08-23 10:49:55 +00003335 if( strlen( cn ) - cn_idx == name->len - 1 &&
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003336 x509_name_cmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003337 {
3338 return( 1 );
3339 }
3340
3341 return( 0 );
3342}
3343
Paul Bakker915275b2012-09-28 07:10:55 +00003344static int x509parse_verify_top(
3345 x509_cert *child, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003346 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003347 int (*f_vrfy)(void *, x509_cert *, int, int *),
3348 void *p_vrfy )
3349{
3350 int hash_id, ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003351 int ca_flags = 0, check_path_cnt = path_cnt + 1;
Paul Bakker915275b2012-09-28 07:10:55 +00003352 unsigned char hash[64];
3353
3354 if( x509parse_time_expired( &child->valid_to ) )
3355 *flags |= BADCERT_EXPIRED;
3356
Paul Bakker50a5c532014-07-08 10:59:10 +02003357 if( x509parse_time_future( &child->valid_from ) )
3358 *flags |= BADCERT_FUTURE;
3359
Paul Bakker915275b2012-09-28 07:10:55 +00003360 /*
3361 * Child is the top of the chain. Check against the trust_ca list.
3362 */
3363 *flags |= BADCERT_NOT_TRUSTED;
3364
3365 while( trust_ca != NULL )
3366 {
3367 if( trust_ca->version == 0 ||
3368 child->issuer_raw.len != trust_ca->subject_raw.len ||
3369 memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
3370 child->issuer_raw.len ) != 0 )
3371 {
3372 trust_ca = trust_ca->next;
3373 continue;
3374 }
3375
Paul Bakker9a736322012-11-14 12:39:52 +00003376 /*
3377 * Reduce path_len to check against if top of the chain is
3378 * the same as the trusted CA
3379 */
3380 if( child->subject_raw.len == trust_ca->subject_raw.len &&
3381 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3382 child->issuer_raw.len ) == 0 )
3383 {
3384 check_path_cnt--;
3385 }
3386
Paul Bakker915275b2012-09-28 07:10:55 +00003387 if( trust_ca->max_pathlen > 0 &&
Paul Bakker9a736322012-11-14 12:39:52 +00003388 trust_ca->max_pathlen < check_path_cnt )
Paul Bakker915275b2012-09-28 07:10:55 +00003389 {
3390 trust_ca = trust_ca->next;
3391 continue;
3392 }
3393
3394 hash_id = child->sig_alg;
3395
3396 x509_hash( child->tbs.p, child->tbs.len, hash_id, hash );
3397
Paul Bakker43f97992013-09-23 11:23:31 +02003398 if( rsa_pkcs1_verify( &trust_ca->rsa, NULL, NULL, RSA_PUBLIC, hash_id,
Paul Bakker915275b2012-09-28 07:10:55 +00003399 0, hash, child->sig.p ) != 0 )
3400 {
3401 trust_ca = trust_ca->next;
3402 continue;
3403 }
3404
3405 /*
3406 * Top of chain is signed by a trusted CA
3407 */
3408 *flags &= ~BADCERT_NOT_TRUSTED;
3409 break;
3410 }
3411
Paul Bakker9a736322012-11-14 12:39:52 +00003412 /*
Paul Bakker3497d8c2012-11-24 11:53:17 +01003413 * If top of chain is not the same as the trusted CA send a verify request
3414 * to the callback for any issues with validity and CRL presence for the
3415 * trusted CA certificate.
Paul Bakker9a736322012-11-14 12:39:52 +00003416 */
3417 if( trust_ca != NULL &&
3418 ( child->subject_raw.len != trust_ca->subject_raw.len ||
3419 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3420 child->issuer_raw.len ) != 0 ) )
Paul Bakker915275b2012-09-28 07:10:55 +00003421 {
3422 /* Check trusted CA's CRL for then chain's top crt */
3423 *flags |= x509parse_verifycrl( child, trust_ca, ca_crl );
3424
3425 if( x509parse_time_expired( &trust_ca->valid_to ) )
3426 ca_flags |= BADCERT_EXPIRED;
3427
Paul Bakker50a5c532014-07-08 10:59:10 +02003428 if( x509parse_time_future( &trust_ca->valid_from ) )
3429 ca_flags |= BADCERT_FUTURE;
3430
Paul Bakker915275b2012-09-28 07:10:55 +00003431 if( NULL != f_vrfy )
3432 {
Paul Bakker9a736322012-11-14 12:39:52 +00003433 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003434 return( ret );
3435 }
3436 }
3437
3438 /* Call callback on top cert */
3439 if( NULL != f_vrfy )
3440 {
Paul Bakker9a736322012-11-14 12:39:52 +00003441 if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003442 return( ret );
3443 }
3444
Paul Bakker915275b2012-09-28 07:10:55 +00003445 *flags |= ca_flags;
3446
3447 return( 0 );
3448}
3449
3450static int x509parse_verify_child(
3451 x509_cert *child, x509_cert *parent, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003452 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003453 int (*f_vrfy)(void *, x509_cert *, int, int *),
3454 void *p_vrfy )
3455{
3456 int hash_id, ret;
3457 int parent_flags = 0;
3458 unsigned char hash[64];
3459 x509_cert *grandparent;
3460
3461 if( x509parse_time_expired( &child->valid_to ) )
3462 *flags |= BADCERT_EXPIRED;
3463
Paul Bakker50a5c532014-07-08 10:59:10 +02003464 if( x509parse_time_future( &child->valid_from ) )
3465 *flags |= BADCERT_FUTURE;
3466
Paul Bakker915275b2012-09-28 07:10:55 +00003467 hash_id = child->sig_alg;
3468
3469 x509_hash( child->tbs.p, child->tbs.len, hash_id, hash );
3470
Paul Bakker43f97992013-09-23 11:23:31 +02003471 if( rsa_pkcs1_verify( &parent->rsa, NULL, NULL, RSA_PUBLIC, hash_id, 0,
3472 hash, child->sig.p ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003473 *flags |= BADCERT_NOT_TRUSTED;
3474
3475 /* Check trusted CA's CRL for the given crt */
3476 *flags |= x509parse_verifycrl(child, parent, ca_crl);
3477
3478 grandparent = parent->next;
3479
3480 while( grandparent != NULL )
3481 {
3482 if( grandparent->version == 0 ||
3483 grandparent->ca_istrue == 0 ||
3484 parent->issuer_raw.len != grandparent->subject_raw.len ||
3485 memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
3486 parent->issuer_raw.len ) != 0 )
3487 {
3488 grandparent = grandparent->next;
3489 continue;
3490 }
3491 break;
3492 }
3493
Paul Bakker915275b2012-09-28 07:10:55 +00003494 if( grandparent != NULL )
3495 {
3496 /*
3497 * Part of the chain
3498 */
Paul Bakker9a736322012-11-14 12:39:52 +00003499 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 +00003500 if( ret != 0 )
3501 return( ret );
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003502 }
Paul Bakker915275b2012-09-28 07:10:55 +00003503 else
3504 {
Paul Bakker9a736322012-11-14 12:39:52 +00003505 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 +00003506 if( ret != 0 )
3507 return( ret );
3508 }
3509
3510 /* child is verified to be a child of the parent, call verify callback */
3511 if( NULL != f_vrfy )
Paul Bakker9a736322012-11-14 12:39:52 +00003512 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003513 return( ret );
Paul Bakker915275b2012-09-28 07:10:55 +00003514
3515 *flags |= parent_flags;
3516
3517 return( 0 );
3518}
3519
Paul Bakker76fd75a2011-01-16 21:12:10 +00003520/*
Paul Bakker5121ce52009-01-03 21:22:43 +00003521 * Verify the certificate validity
3522 */
3523int x509parse_verify( x509_cert *crt,
3524 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00003525 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003526 const char *cn, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003527 int (*f_vrfy)(void *, x509_cert *, int, int *),
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003528 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00003529{
Paul Bakker23986e52011-04-24 08:57:21 +00003530 size_t cn_len;
Paul Bakker915275b2012-09-28 07:10:55 +00003531 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003532 int pathlen = 0;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003533 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00003534 x509_name *name;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003535 x509_sequence *cur = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003536
Paul Bakker40ea7de2009-05-03 10:18:48 +00003537 *flags = 0;
3538
Paul Bakker5121ce52009-01-03 21:22:43 +00003539 if( cn != NULL )
3540 {
3541 name = &crt->subject;
3542 cn_len = strlen( cn );
3543
Paul Bakker4d2c1242012-05-10 14:12:46 +00003544 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
Paul Bakker5121ce52009-01-03 21:22:43 +00003545 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00003546 cur = &crt->subject_alt_names;
3547
3548 while( cur != NULL )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003549 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003550 if( cur->buf.len == cn_len &&
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003551 x509_name_cmp( cn, cur->buf.p, cn_len ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003552 break;
3553
Paul Bakker535e97d2012-08-23 10:49:55 +00003554 if( cur->buf.len > 2 &&
3555 memcmp( cur->buf.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003556 x509_wildcard_verify( cn, &cur->buf ) )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003557 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003558
Paul Bakker4d2c1242012-05-10 14:12:46 +00003559 cur = cur->next;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003560 }
3561
3562 if( cur == NULL )
3563 *flags |= BADCERT_CN_MISMATCH;
3564 }
Paul Bakker4d2c1242012-05-10 14:12:46 +00003565 else
3566 {
3567 while( name != NULL )
3568 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003569 if( name->oid.len == 3 &&
3570 memcmp( name->oid.p, OID_CN, 3 ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003571 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003572 if( name->val.len == cn_len &&
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003573 x509_name_cmp( name->val.p, cn, cn_len ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003574 break;
3575
Paul Bakker535e97d2012-08-23 10:49:55 +00003576 if( name->val.len > 2 &&
3577 memcmp( name->val.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003578 x509_wildcard_verify( cn, &name->val ) )
3579 break;
3580 }
3581
3582 name = name->next;
3583 }
3584
3585 if( name == NULL )
3586 *flags |= BADCERT_CN_MISMATCH;
3587 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003588 }
3589
Paul Bakker5121ce52009-01-03 21:22:43 +00003590 /*
Paul Bakker915275b2012-09-28 07:10:55 +00003591 * Iterate upwards in the given cert chain, to find our crt parent.
3592 * Ignore any upper cert with CA != TRUE.
Paul Bakker5121ce52009-01-03 21:22:43 +00003593 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003594 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003595
Paul Bakker76fd75a2011-01-16 21:12:10 +00003596 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003597 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003598 if( parent->ca_istrue == 0 ||
3599 crt->issuer_raw.len != parent->subject_raw.len ||
3600 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00003601 crt->issuer_raw.len ) != 0 )
3602 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003603 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003604 continue;
3605 }
Paul Bakker915275b2012-09-28 07:10:55 +00003606 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003607 }
3608
Paul Bakker915275b2012-09-28 07:10:55 +00003609 if( parent != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003610 {
Paul Bakker915275b2012-09-28 07:10:55 +00003611 /*
3612 * Part of the chain
3613 */
Paul Bakker9a736322012-11-14 12:39:52 +00003614 ret = x509parse_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003615 if( ret != 0 )
3616 return( ret );
3617 }
3618 else
Paul Bakker74111d32011-01-15 16:57:55 +00003619 {
Paul Bakker9a736322012-11-14 12:39:52 +00003620 ret = x509parse_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003621 if( ret != 0 )
3622 return( ret );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003623 }
Paul Bakker915275b2012-09-28 07:10:55 +00003624
3625 if( *flags != 0 )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003626 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003627
Paul Bakker5121ce52009-01-03 21:22:43 +00003628 return( 0 );
3629}
3630
3631/*
3632 * Unallocate all certificate data
3633 */
3634void x509_free( x509_cert *crt )
3635{
3636 x509_cert *cert_cur = crt;
3637 x509_cert *cert_prv;
3638 x509_name *name_cur;
3639 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00003640 x509_sequence *seq_cur;
3641 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00003642
3643 if( crt == NULL )
3644 return;
3645
3646 do
3647 {
3648 rsa_free( &cert_cur->rsa );
3649
3650 name_cur = cert_cur->issuer.next;
3651 while( name_cur != NULL )
3652 {
3653 name_prv = name_cur;
3654 name_cur = name_cur->next;
3655 memset( name_prv, 0, sizeof( x509_name ) );
3656 free( name_prv );
3657 }
3658
3659 name_cur = cert_cur->subject.next;
3660 while( name_cur != NULL )
3661 {
3662 name_prv = name_cur;
3663 name_cur = name_cur->next;
3664 memset( name_prv, 0, sizeof( x509_name ) );
3665 free( name_prv );
3666 }
3667
Paul Bakker74111d32011-01-15 16:57:55 +00003668 seq_cur = cert_cur->ext_key_usage.next;
3669 while( seq_cur != NULL )
3670 {
3671 seq_prv = seq_cur;
3672 seq_cur = seq_cur->next;
3673 memset( seq_prv, 0, sizeof( x509_sequence ) );
3674 free( seq_prv );
3675 }
3676
Paul Bakker8afa70d2012-02-11 18:42:45 +00003677 seq_cur = cert_cur->subject_alt_names.next;
3678 while( seq_cur != NULL )
3679 {
3680 seq_prv = seq_cur;
3681 seq_cur = seq_cur->next;
3682 memset( seq_prv, 0, sizeof( x509_sequence ) );
3683 free( seq_prv );
3684 }
3685
Paul Bakker5121ce52009-01-03 21:22:43 +00003686 if( cert_cur->raw.p != NULL )
3687 {
3688 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
3689 free( cert_cur->raw.p );
3690 }
3691
3692 cert_cur = cert_cur->next;
3693 }
3694 while( cert_cur != NULL );
3695
3696 cert_cur = crt;
3697 do
3698 {
3699 cert_prv = cert_cur;
3700 cert_cur = cert_cur->next;
3701
3702 memset( cert_prv, 0, sizeof( x509_cert ) );
3703 if( cert_prv != crt )
3704 free( cert_prv );
3705 }
3706 while( cert_cur != NULL );
3707}
3708
Paul Bakkerd98030e2009-05-02 15:13:40 +00003709/*
3710 * Unallocate all CRL data
3711 */
3712void x509_crl_free( x509_crl *crl )
3713{
3714 x509_crl *crl_cur = crl;
3715 x509_crl *crl_prv;
3716 x509_name *name_cur;
3717 x509_name *name_prv;
3718 x509_crl_entry *entry_cur;
3719 x509_crl_entry *entry_prv;
3720
3721 if( crl == NULL )
3722 return;
3723
3724 do
3725 {
3726 name_cur = crl_cur->issuer.next;
3727 while( name_cur != NULL )
3728 {
3729 name_prv = name_cur;
3730 name_cur = name_cur->next;
3731 memset( name_prv, 0, sizeof( x509_name ) );
3732 free( name_prv );
3733 }
3734
3735 entry_cur = crl_cur->entry.next;
3736 while( entry_cur != NULL )
3737 {
3738 entry_prv = entry_cur;
3739 entry_cur = entry_cur->next;
3740 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
3741 free( entry_prv );
3742 }
3743
3744 if( crl_cur->raw.p != NULL )
3745 {
3746 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
3747 free( crl_cur->raw.p );
3748 }
3749
3750 crl_cur = crl_cur->next;
3751 }
3752 while( crl_cur != NULL );
3753
3754 crl_cur = crl;
3755 do
3756 {
3757 crl_prv = crl_cur;
3758 crl_cur = crl_cur->next;
3759
3760 memset( crl_prv, 0, sizeof( x509_crl ) );
3761 if( crl_prv != crl )
3762 free( crl_prv );
3763 }
3764 while( crl_cur != NULL );
3765}
3766
Paul Bakker40e46942009-01-03 21:51:57 +00003767#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00003768
Paul Bakker40e46942009-01-03 21:51:57 +00003769#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00003770
3771/*
3772 * Checkup routine
3773 */
3774int x509_self_test( int verbose )
3775{
Paul Bakker5690efc2011-05-26 13:16:06 +00003776#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00003777 int ret;
3778 int flags;
3779 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00003780 x509_cert cacert;
3781 x509_cert clicert;
3782 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00003783#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003784 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00003785#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003786
3787 if( verbose != 0 )
3788 printf( " X.509 certificate load: " );
3789
3790 memset( &clicert, 0, sizeof( x509_cert ) );
3791
Paul Bakkereae09db2013-06-06 12:35:54 +02003792 ret = x509parse_crt( &clicert, (const unsigned char *) test_cli_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003793 strlen( test_cli_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003794 if( ret != 0 )
3795 {
3796 if( verbose != 0 )
3797 printf( "failed\n" );
3798
3799 return( ret );
3800 }
3801
3802 memset( &cacert, 0, sizeof( x509_cert ) );
3803
Paul Bakkereae09db2013-06-06 12:35:54 +02003804 ret = x509parse_crt( &cacert, (const unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003805 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003806 if( ret != 0 )
3807 {
3808 if( verbose != 0 )
3809 printf( "failed\n" );
3810
3811 return( ret );
3812 }
3813
3814 if( verbose != 0 )
3815 printf( "passed\n X.509 private key load: " );
3816
3817 i = strlen( test_ca_key );
3818 j = strlen( test_ca_pwd );
3819
Paul Bakker66b78b22011-03-25 14:22:50 +00003820 rsa_init( &rsa, RSA_PKCS_V15, 0 );
3821
Paul Bakker5121ce52009-01-03 21:22:43 +00003822 if( ( ret = x509parse_key( &rsa,
Paul Bakkereae09db2013-06-06 12:35:54 +02003823 (const unsigned char *) test_ca_key, i,
3824 (const unsigned char *) test_ca_pwd, j ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003825 {
3826 if( verbose != 0 )
3827 printf( "failed\n" );
3828
3829 return( ret );
3830 }
3831
3832 if( verbose != 0 )
3833 printf( "passed\n X.509 signature verify: ");
3834
Paul Bakker23986e52011-04-24 08:57:21 +00003835 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003836 if( ret != 0 )
3837 {
3838 if( verbose != 0 )
3839 printf( "failed\n" );
3840
3841 return( ret );
3842 }
3843
Paul Bakker5690efc2011-05-26 13:16:06 +00003844#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003845 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003846 printf( "passed\n X.509 DHM parameter load: " );
3847
3848 i = strlen( test_dhm_params );
3849 j = strlen( test_ca_pwd );
3850
Paul Bakkereae09db2013-06-06 12:35:54 +02003851 if( ( ret = x509parse_dhm( &dhm, (const unsigned char *) test_dhm_params, i ) ) != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003852 {
3853 if( verbose != 0 )
3854 printf( "failed\n" );
3855
3856 return( ret );
3857 }
3858
3859 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003860 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00003861#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003862
3863 x509_free( &cacert );
3864 x509_free( &clicert );
3865 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00003866#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003867 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00003868#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003869
3870 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003871#else
3872 ((void) verbose);
3873 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3874#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003875}
3876
3877#endif
3878
3879#endif