blob: fe13b16b2aeb7e187f6f387041cfc66ddc3840d4 [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
286 */
287static int x509_get_name( unsigned char **p,
288 const unsigned char *end,
289 x509_name *cur )
290{
Paul Bakker23986e52011-04-24 08:57:21 +0000291 int ret;
292 size_t len;
Paul Bakker400ff6f2011-02-20 10:40:16 +0000293 const unsigned char *end2;
294 x509_name *use;
295
296 if( ( ret = asn1_get_tag( p, end, &len,
297 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000298 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000299
300 end2 = end;
301 end = *p + len;
302 use = cur;
303
304 do
305 {
306 if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
307 return( ret );
308
309 if( *p != end )
310 {
311 use->next = (x509_name *) malloc(
312 sizeof( x509_name ) );
313
314 if( use->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000315 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000316
317 memset( use->next, 0, sizeof( x509_name ) );
318
319 use = use->next;
320 }
321 }
322 while( *p != end );
Paul Bakker5121ce52009-01-03 21:22:43 +0000323
324 /*
325 * recurse until end of SEQUENCE is reached
326 */
327 if( *p == end2 )
328 return( 0 );
329
330 cur->next = (x509_name *) malloc(
331 sizeof( x509_name ) );
332
333 if( cur->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000334 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000335
Paul Bakker430ffbe2012-05-01 08:14:20 +0000336 memset( cur->next, 0, sizeof( x509_name ) );
337
Paul Bakker5121ce52009-01-03 21:22:43 +0000338 return( x509_get_name( p, end2, cur->next ) );
339}
340
341/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000342 * Time ::= CHOICE {
343 * utcTime UTCTime,
344 * generalTime GeneralizedTime }
345 */
Paul Bakker91200182010-02-18 21:26:15 +0000346static int x509_get_time( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000347 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000348 x509_time *time )
349{
Paul Bakker23986e52011-04-24 08:57:21 +0000350 int ret;
351 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000352 char date[64];
Paul Bakker91200182010-02-18 21:26:15 +0000353 unsigned char tag;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000354
Paul Bakker91200182010-02-18 21:26:15 +0000355 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000356 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
357 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000358
Paul Bakker91200182010-02-18 21:26:15 +0000359 tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000360
Paul Bakker91200182010-02-18 21:26:15 +0000361 if ( tag == ASN1_UTC_TIME )
362 {
363 (*p)++;
364 ret = asn1_get_len( p, end, &len );
365
366 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000367 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000368
Paul Bakker91200182010-02-18 21:26:15 +0000369 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000370 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
371 len : sizeof( date ) - 1 );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000372
Paul Bakker243d6182014-07-08 14:40:58 +0200373 if( sscanf( date, "%2d%2d%2d%2d%2d%2dZ",
Paul Bakker91200182010-02-18 21:26:15 +0000374 &time->year, &time->mon, &time->day,
375 &time->hour, &time->min, &time->sec ) < 5 )
376 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000377
Paul Bakker400ff6f2011-02-20 10:40:16 +0000378 time->year += 100 * ( time->year < 50 );
Paul Bakker91200182010-02-18 21:26:15 +0000379 time->year += 1900;
380
381 *p += len;
382
383 return( 0 );
384 }
385 else if ( tag == ASN1_GENERALIZED_TIME )
386 {
387 (*p)++;
388 ret = asn1_get_len( p, end, &len );
389
390 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000391 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker91200182010-02-18 21:26:15 +0000392
393 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000394 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
395 len : sizeof( date ) - 1 );
Paul Bakker91200182010-02-18 21:26:15 +0000396
Paul Bakker243d6182014-07-08 14:40:58 +0200397 if( sscanf( date, "%4d%2d%2d%2d%2d%2dZ",
Paul Bakker91200182010-02-18 21:26:15 +0000398 &time->year, &time->mon, &time->day,
399 &time->hour, &time->min, &time->sec ) < 5 )
400 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
401
402 *p += len;
403
404 return( 0 );
405 }
406 else
Paul Bakker9d781402011-05-09 16:17:09 +0000407 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000408}
409
410
411/*
412 * Validity ::= SEQUENCE {
413 * notBefore Time,
414 * notAfter Time }
415 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000416static int x509_get_dates( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000417 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000418 x509_time *from,
419 x509_time *to )
420{
Paul Bakker23986e52011-04-24 08:57:21 +0000421 int ret;
422 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000423
424 if( ( ret = asn1_get_tag( p, end, &len,
425 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000426 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000427
428 end = *p + len;
429
Paul Bakker91200182010-02-18 21:26:15 +0000430 if( ( ret = x509_get_time( p, end, from ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000431 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000432
Paul Bakker91200182010-02-18 21:26:15 +0000433 if( ( ret = x509_get_time( p, end, to ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000434 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000435
436 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000437 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker40e46942009-01-03 21:51:57 +0000438 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000439
440 return( 0 );
441}
442
443/*
444 * SubjectPublicKeyInfo ::= SEQUENCE {
445 * algorithm AlgorithmIdentifier,
446 * subjectPublicKey BIT STRING }
447 */
448static int x509_get_pubkey( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000449 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000450 x509_buf *pk_alg_oid,
451 mpi *N, mpi *E )
452{
Paul Bakker65a19092013-06-06 21:14:58 +0200453 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000454 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000455 unsigned char *end2;
456
457 if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 )
458 return( ret );
459
460 /*
461 * only RSA public keys handled at this time
462 */
Paul Bakker65a19092013-06-06 21:14:58 +0200463 if( pk_alg_oid->len != 9 ||
464 memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) != 0 )
Paul Bakker400ff6f2011-02-20 10:40:16 +0000465 {
Paul Bakkered56b222011-07-13 11:26:43 +0000466 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
Paul Bakker65a19092013-06-06 21:14:58 +0200467 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000468
469 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000470 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000471
472 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000473 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000474 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000475
476 end2 = *p + len;
477
478 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000479 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000480
481 /*
482 * RSAPublicKey ::= SEQUENCE {
483 * modulus INTEGER, -- n
484 * publicExponent INTEGER -- e
485 * }
486 */
487 if( ( ret = asn1_get_tag( p, end2, &len,
488 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000489 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000490
491 if( *p + len != end2 )
Paul Bakker9d781402011-05-09 16:17:09 +0000492 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000493 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000494
495 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
496 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000497 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000498
499 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000500 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000501 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000502
503 return( 0 );
504}
505
506static int x509_get_sig( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000507 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000508 x509_buf *sig )
509{
Paul Bakker23986e52011-04-24 08:57:21 +0000510 int ret;
511 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000512
Paul Bakker8afa70d2012-02-11 18:42:45 +0000513 if( ( end - *p ) < 1 )
514 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE +
515 POLARSSL_ERR_ASN1_OUT_OF_DATA );
516
Paul Bakker5121ce52009-01-03 21:22:43 +0000517 sig->tag = **p;
518
519 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000520 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000521
Paul Bakker74111d32011-01-15 16:57:55 +0000522
Paul Bakker5121ce52009-01-03 21:22:43 +0000523 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000524 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000525
526 sig->len = len;
527 sig->p = *p;
528
529 *p += len;
530
531 return( 0 );
532}
533
534/*
535 * X.509 v2/v3 unique identifier (not parsed)
536 */
537static int x509_get_uid( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000538 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000539 x509_buf *uid, int n )
540{
541 int ret;
542
543 if( *p == end )
544 return( 0 );
545
546 uid->tag = **p;
547
548 if( ( ret = asn1_get_tag( p, end, &uid->len,
549 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
550 {
Paul Bakker40e46942009-01-03 21:51:57 +0000551 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000552 return( 0 );
553
554 return( ret );
555 }
556
557 uid->p = *p;
558 *p += uid->len;
559
560 return( 0 );
561}
562
563/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000564 * X.509 Extensions (No parsing of extensions, pointer should
565 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000566 */
567static int x509_get_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000568 const unsigned char *end,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000569 x509_buf *ext, int tag )
Paul Bakker5121ce52009-01-03 21:22:43 +0000570{
Paul Bakker23986e52011-04-24 08:57:21 +0000571 int ret;
572 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000573
574 if( *p == end )
575 return( 0 );
576
577 ext->tag = **p;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000578
Paul Bakker5121ce52009-01-03 21:22:43 +0000579 if( ( ret = asn1_get_tag( p, end, &ext->len,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000580 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000581 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000582
583 ext->p = *p;
584 end = *p + ext->len;
585
586 /*
587 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
588 *
589 * Extension ::= SEQUENCE {
590 * extnID OBJECT IDENTIFIER,
591 * critical BOOLEAN DEFAULT FALSE,
592 * extnValue OCTET STRING }
593 */
594 if( ( ret = asn1_get_tag( p, end, &len,
595 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000596 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000597
598 if( end != *p + len )
Paul Bakker9d781402011-05-09 16:17:09 +0000599 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +0000600 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000601
Paul Bakkerd98030e2009-05-02 15:13:40 +0000602 return( 0 );
603}
604
605/*
606 * X.509 CRL v2 extensions (no extensions parsed yet.)
607 */
608static int x509_get_crl_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000609 const unsigned char *end,
610 x509_buf *ext )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000611{
Paul Bakker23986e52011-04-24 08:57:21 +0000612 int ret;
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000613 size_t len = 0;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000614
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000615 /* Get explicit tag */
616 if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000617 {
618 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
619 return( 0 );
620
621 return( ret );
622 }
623
624 while( *p < end )
625 {
626 if( ( ret = asn1_get_tag( p, end, &len,
627 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000628 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000629
630 *p += len;
631 }
632
633 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000634 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerd98030e2009-05-02 15:13:40 +0000635 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
636
637 return( 0 );
638}
639
Paul Bakkerb5a11ab2011-10-12 09:58:41 +0000640/*
641 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
642 */
643static int x509_get_crl_entry_ext( unsigned char **p,
644 const unsigned char *end,
645 x509_buf *ext )
646{
647 int ret;
648 size_t len = 0;
649
650 /* OPTIONAL */
651 if (end <= *p)
652 return( 0 );
653
654 ext->tag = **p;
655 ext->p = *p;
656
657 /*
658 * Get CRL-entry extension sequence header
659 * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
660 */
661 if( ( ret = asn1_get_tag( p, end, &ext->len,
662 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
663 {
664 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
665 {
666 ext->p = NULL;
667 return( 0 );
668 }
669 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
670 }
671
672 end = *p + ext->len;
673
674 if( end != *p + ext->len )
675 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
676 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
677
678 while( *p < end )
679 {
680 if( ( ret = asn1_get_tag( p, end, &len,
681 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
682 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
683
684 *p += len;
685 }
686
687 if( *p != end )
688 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
689 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
690
691 return( 0 );
692}
693
Paul Bakker74111d32011-01-15 16:57:55 +0000694static int x509_get_basic_constraints( unsigned char **p,
695 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000696 int *ca_istrue,
697 int *max_pathlen )
698{
Paul Bakker23986e52011-04-24 08:57:21 +0000699 int ret;
700 size_t len;
Paul Bakker74111d32011-01-15 16:57:55 +0000701
702 /*
703 * BasicConstraints ::= SEQUENCE {
704 * cA BOOLEAN DEFAULT FALSE,
705 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
706 */
Paul Bakker3cccddb2011-01-16 21:46:31 +0000707 *ca_istrue = 0; /* DEFAULT FALSE */
Paul Bakker74111d32011-01-15 16:57:55 +0000708 *max_pathlen = 0; /* endless */
709
710 if( ( ret = asn1_get_tag( p, end, &len,
711 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000712 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000713
714 if( *p == end )
715 return 0;
716
Paul Bakker3cccddb2011-01-16 21:46:31 +0000717 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000718 {
719 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker3cccddb2011-01-16 21:46:31 +0000720 ret = asn1_get_int( p, end, ca_istrue );
Paul Bakker74111d32011-01-15 16:57:55 +0000721
722 if( ret != 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
Paul Bakker3cccddb2011-01-16 21:46:31 +0000725 if( *ca_istrue != 0 )
726 *ca_istrue = 1;
Paul Bakker74111d32011-01-15 16:57:55 +0000727 }
728
729 if( *p == end )
730 return 0;
731
732 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000733 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000734
735 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000736 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000737 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
738
739 (*max_pathlen)++;
740
Paul Bakker74111d32011-01-15 16:57:55 +0000741 return 0;
742}
743
744static int x509_get_ns_cert_type( unsigned char **p,
745 const unsigned char *end,
746 unsigned char *ns_cert_type)
747{
748 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000749 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000750
751 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000752 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000753
754 if( bs.len != 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000755 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000756 POLARSSL_ERR_ASN1_INVALID_LENGTH );
757
758 /* Get actual bitstring */
759 *ns_cert_type = *bs.p;
760 return 0;
761}
762
763static int x509_get_key_usage( unsigned char **p,
764 const unsigned char *end,
765 unsigned char *key_usage)
766{
767 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000768 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000769
770 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000771 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000772
Paul Bakker94a67962012-08-23 13:03:52 +0000773 if( bs.len < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000774 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000775 POLARSSL_ERR_ASN1_INVALID_LENGTH );
776
777 /* Get actual bitstring */
778 *key_usage = *bs.p;
779 return 0;
780}
781
Paul Bakkerd98030e2009-05-02 15:13:40 +0000782/*
Paul Bakker74111d32011-01-15 16:57:55 +0000783 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
784 *
785 * KeyPurposeId ::= OBJECT IDENTIFIER
786 */
787static int x509_get_ext_key_usage( unsigned char **p,
788 const unsigned char *end,
789 x509_sequence *ext_key_usage)
790{
791 int ret;
792
793 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000794 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000795
796 /* Sequence length must be >= 1 */
797 if( ext_key_usage->buf.p == NULL )
Paul Bakker9d781402011-05-09 16:17:09 +0000798 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000799 POLARSSL_ERR_ASN1_INVALID_LENGTH );
800
801 return 0;
802}
803
804/*
Paul Bakkera8cd2392012-02-11 16:09:32 +0000805 * SubjectAltName ::= GeneralNames
806 *
807 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
808 *
809 * GeneralName ::= CHOICE {
810 * otherName [0] OtherName,
811 * rfc822Name [1] IA5String,
812 * dNSName [2] IA5String,
813 * x400Address [3] ORAddress,
814 * directoryName [4] Name,
815 * ediPartyName [5] EDIPartyName,
816 * uniformResourceIdentifier [6] IA5String,
817 * iPAddress [7] OCTET STRING,
818 * registeredID [8] OBJECT IDENTIFIER }
819 *
820 * OtherName ::= SEQUENCE {
821 * type-id OBJECT IDENTIFIER,
822 * value [0] EXPLICIT ANY DEFINED BY type-id }
823 *
824 * EDIPartyName ::= SEQUENCE {
825 * nameAssigner [0] DirectoryString OPTIONAL,
826 * partyName [1] DirectoryString }
827 *
828 * NOTE: PolarSSL only parses and uses dNSName at this point.
829 */
830static int x509_get_subject_alt_name( unsigned char **p,
831 const unsigned char *end,
832 x509_sequence *subject_alt_name )
833{
834 int ret;
835 size_t len, tag_len;
836 asn1_buf *buf;
837 unsigned char tag;
838 asn1_sequence *cur = subject_alt_name;
839
840 /* Get main sequence tag */
841 if( ( ret = asn1_get_tag( p, end, &len,
842 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
843 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
844
845 if( *p + len != end )
846 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
847 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
848
849 while( *p < end )
850 {
851 if( ( end - *p ) < 1 )
852 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
853 POLARSSL_ERR_ASN1_OUT_OF_DATA );
854
855 tag = **p;
856 (*p)++;
857 if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 )
858 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
859
860 if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC )
861 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
862 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
863
864 if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) )
865 {
866 *p += tag_len;
867 continue;
868 }
869
870 buf = &(cur->buf);
871 buf->tag = tag;
872 buf->p = *p;
873 buf->len = tag_len;
874 *p += buf->len;
875
876 /* Allocate and assign next pointer */
877 if (*p < end)
878 {
879 cur->next = (asn1_sequence *) malloc(
880 sizeof( asn1_sequence ) );
881
882 if( cur->next == NULL )
883 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
884 POLARSSL_ERR_ASN1_MALLOC_FAILED );
885
Paul Bakker535e97d2012-08-23 10:49:55 +0000886 memset( cur->next, 0, sizeof( asn1_sequence ) );
Paul Bakkera8cd2392012-02-11 16:09:32 +0000887 cur = cur->next;
888 }
889 }
890
891 /* Set final sequence entry's next pointer to NULL */
892 cur->next = NULL;
893
894 if( *p != end )
895 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
896 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
897
898 return( 0 );
899}
900
901/*
Paul Bakker74111d32011-01-15 16:57:55 +0000902 * X.509 v3 extensions
903 *
904 * TODO: Perform all of the basic constraints tests required by the RFC
905 * TODO: Set values for undetected extensions to a sane default?
906 *
Paul Bakkerd98030e2009-05-02 15:13:40 +0000907 */
908static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000909 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000910 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000911{
Paul Bakker23986e52011-04-24 08:57:21 +0000912 int ret;
913 size_t len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000914 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000915
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000916 if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000917 {
918 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
919 return( 0 );
920
921 return( ret );
922 }
923
Paul Bakker5121ce52009-01-03 21:22:43 +0000924 while( *p < end )
925 {
Paul Bakker74111d32011-01-15 16:57:55 +0000926 /*
927 * Extension ::= SEQUENCE {
928 * extnID OBJECT IDENTIFIER,
929 * critical BOOLEAN DEFAULT FALSE,
930 * extnValue OCTET STRING }
931 */
932 x509_buf extn_oid = {0, 0, NULL};
933 int is_critical = 0; /* DEFAULT FALSE */
934
Paul Bakker5121ce52009-01-03 21:22:43 +0000935 if( ( ret = asn1_get_tag( p, end, &len,
936 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000937 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000938
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000939 end_ext_data = *p + len;
940
Paul Bakker74111d32011-01-15 16:57:55 +0000941 /* Get extension ID */
942 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000943
Paul Bakker74111d32011-01-15 16:57:55 +0000944 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000945 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000946
Paul Bakker74111d32011-01-15 16:57:55 +0000947 extn_oid.p = *p;
948 *p += extn_oid.len;
949
950 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000951 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000952 POLARSSL_ERR_ASN1_OUT_OF_DATA );
953
954 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000955 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000956 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
Paul Bakker9d781402011-05-09 16:17:09 +0000957 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000958
Paul Bakker74111d32011-01-15 16:57:55 +0000959 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000960 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000961 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000962 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000963
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000964 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000965
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000966 if( end_ext_octet != end_ext_data )
Paul Bakker9d781402011-05-09 16:17:09 +0000967 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000968 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000969
Paul Bakker74111d32011-01-15 16:57:55 +0000970 /*
971 * Detect supported extensions
972 */
973 if( ( OID_SIZE( OID_BASIC_CONSTRAINTS ) == extn_oid.len ) &&
974 memcmp( extn_oid.p, OID_BASIC_CONSTRAINTS, extn_oid.len ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000975 {
Paul Bakker74111d32011-01-15 16:57:55 +0000976 /* Parse basic constraints */
977 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
Paul Bakker3cccddb2011-01-16 21:46:31 +0000978 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000979 return ( ret );
980 crt->ext_types |= EXT_BASIC_CONSTRAINTS;
Paul Bakker5121ce52009-01-03 21:22:43 +0000981 }
Paul Bakker74111d32011-01-15 16:57:55 +0000982 else if( ( OID_SIZE( OID_NS_CERT_TYPE ) == extn_oid.len ) &&
983 memcmp( extn_oid.p, OID_NS_CERT_TYPE, extn_oid.len ) == 0 )
984 {
985 /* Parse netscape certificate type */
986 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
987 &crt->ns_cert_type ) ) != 0 )
988 return ( ret );
989 crt->ext_types |= EXT_NS_CERT_TYPE;
990 }
991 else if( ( OID_SIZE( OID_KEY_USAGE ) == extn_oid.len ) &&
992 memcmp( extn_oid.p, OID_KEY_USAGE, extn_oid.len ) == 0 )
993 {
994 /* Parse key usage */
995 if( ( ret = x509_get_key_usage( p, end_ext_octet,
996 &crt->key_usage ) ) != 0 )
997 return ( ret );
998 crt->ext_types |= EXT_KEY_USAGE;
999 }
1000 else if( ( OID_SIZE( OID_EXTENDED_KEY_USAGE ) == extn_oid.len ) &&
1001 memcmp( extn_oid.p, OID_EXTENDED_KEY_USAGE, extn_oid.len ) == 0 )
1002 {
1003 /* Parse extended key usage */
1004 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
1005 &crt->ext_key_usage ) ) != 0 )
1006 return ( ret );
1007 crt->ext_types |= EXT_EXTENDED_KEY_USAGE;
1008 }
Paul Bakkera8cd2392012-02-11 16:09:32 +00001009 else if( ( OID_SIZE( OID_SUBJECT_ALT_NAME ) == extn_oid.len ) &&
1010 memcmp( extn_oid.p, OID_SUBJECT_ALT_NAME, extn_oid.len ) == 0 )
1011 {
1012 /* Parse extended key usage */
1013 if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
1014 &crt->subject_alt_names ) ) != 0 )
1015 return ( ret );
1016 crt->ext_types |= EXT_SUBJECT_ALT_NAME;
1017 }
Paul Bakker74111d32011-01-15 16:57:55 +00001018 else
1019 {
1020 /* No parser found, skip extension */
1021 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +00001022
Paul Bakker5c721f92011-07-27 16:51:09 +00001023#if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
Paul Bakker74111d32011-01-15 16:57:55 +00001024 if( is_critical )
1025 {
1026 /* Data is marked as critical: fail */
Paul Bakker9d781402011-05-09 16:17:09 +00001027 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +00001028 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
1029 }
Paul Bakker5c721f92011-07-27 16:51:09 +00001030#endif
Paul Bakker74111d32011-01-15 16:57:55 +00001031 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001032 }
1033
1034 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +00001035 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +00001036 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001037
Paul Bakker5121ce52009-01-03 21:22:43 +00001038 return( 0 );
1039}
1040
1041/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001042 * X.509 CRL Entries
1043 */
1044static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001045 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001046 x509_crl_entry *entry )
1047{
Paul Bakker23986e52011-04-24 08:57:21 +00001048 int ret;
1049 size_t entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001050 x509_crl_entry *cur_entry = entry;
1051
1052 if( *p == end )
1053 return( 0 );
1054
Paul Bakker9be19372009-07-27 20:21:53 +00001055 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001056 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1057 {
1058 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
1059 return( 0 );
1060
1061 return( ret );
1062 }
1063
Paul Bakker9be19372009-07-27 20:21:53 +00001064 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001065
1066 while( *p < end )
1067 {
Paul Bakker23986e52011-04-24 08:57:21 +00001068 size_t len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001069 const unsigned char *end2;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001070
1071 if( ( ret = asn1_get_tag( p, end, &len2,
1072 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1073 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001074 return( ret );
1075 }
1076
Paul Bakker9be19372009-07-27 20:21:53 +00001077 cur_entry->raw.tag = **p;
1078 cur_entry->raw.p = *p;
1079 cur_entry->raw.len = len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001080 end2 = *p + len2;
Paul Bakker9be19372009-07-27 20:21:53 +00001081
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001082 if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001083 return( ret );
1084
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001085 if( ( ret = x509_get_time( p, end2, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001086 return( ret );
1087
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001088 if( ( ret = x509_get_crl_entry_ext( p, end2, &cur_entry->entry_ext ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001089 return( ret );
1090
Paul Bakker74111d32011-01-15 16:57:55 +00001091 if ( *p < end )
1092 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001093 cur_entry->next = malloc( sizeof( x509_crl_entry ) );
Paul Bakkerb15b8512012-01-13 13:44:06 +00001094
1095 if( cur_entry->next == NULL )
1096 return( POLARSSL_ERR_X509_MALLOC_FAILED );
1097
Paul Bakkerd98030e2009-05-02 15:13:40 +00001098 cur_entry = cur_entry->next;
1099 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
1100 }
1101 }
1102
1103 return( 0 );
1104}
1105
Paul Bakker27d66162010-03-17 06:56:01 +00001106static int x509_get_sig_alg( const x509_buf *sig_oid, int *sig_alg )
1107{
1108 if( sig_oid->len == 9 &&
1109 memcmp( sig_oid->p, OID_PKCS1, 8 ) == 0 )
1110 {
1111 if( sig_oid->p[8] >= 2 && sig_oid->p[8] <= 5 )
1112 {
1113 *sig_alg = sig_oid->p[8];
1114 return( 0 );
1115 }
1116
1117 if ( sig_oid->p[8] >= 11 && sig_oid->p[8] <= 14 )
1118 {
1119 *sig_alg = sig_oid->p[8];
1120 return( 0 );
1121 }
1122
1123 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1124 }
Paul Bakker400ff6f2011-02-20 10:40:16 +00001125 if( sig_oid->len == 5 &&
1126 memcmp( sig_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
1127 {
1128 *sig_alg = SIG_RSA_SHA1;
1129 return( 0 );
1130 }
Paul Bakker27d66162010-03-17 06:56:01 +00001131
1132 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1133}
1134
Paul Bakkerd98030e2009-05-02 15:13:40 +00001135/*
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001136 * Parse and fill a single X.509 certificate in DER format
Paul Bakker5121ce52009-01-03 21:22:43 +00001137 */
Paul Bakker1d073c52014-07-08 20:15:51 +02001138static int x509parse_crt_der_core( x509_cert *crt, const unsigned char *buf,
1139 size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001140{
Paul Bakker23986e52011-04-24 08:57:21 +00001141 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001142 size_t len;
Paul Bakkerb00ca422012-09-25 12:10:00 +00001143 unsigned char *p, *end, *crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001144
Paul Bakker320a4b52009-03-28 18:52:39 +00001145 /*
1146 * Check for valid input
1147 */
1148 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001149 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker320a4b52009-03-28 18:52:39 +00001150
Paul Bakker96743fc2011-02-12 14:30:57 +00001151 p = (unsigned char *) malloc( len = buflen );
1152
1153 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001154 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001155
1156 memcpy( p, buf, buflen );
1157
Paul Bakker5121ce52009-01-03 21:22:43 +00001158 crt->raw.p = p;
1159 crt->raw.len = len;
1160 end = p + len;
1161
1162 /*
1163 * Certificate ::= SEQUENCE {
1164 * tbsCertificate TBSCertificate,
1165 * signatureAlgorithm AlgorithmIdentifier,
1166 * signatureValue BIT STRING }
1167 */
1168 if( ( ret = asn1_get_tag( &p, end, &len,
1169 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1170 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001171 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001172 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001173 }
1174
Paul Bakkerb00ca422012-09-25 12:10:00 +00001175 if( len > (size_t) ( end - p ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001176 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001177 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001178 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001179 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001180 }
Paul Bakkerb00ca422012-09-25 12:10:00 +00001181 crt_end = p + len;
Paul Bakkerd6d41092013-06-13 09:00:25 +02001182
Paul Bakker5121ce52009-01-03 21:22:43 +00001183 /*
1184 * TBSCertificate ::= SEQUENCE {
1185 */
1186 crt->tbs.p = p;
1187
1188 if( ( ret = asn1_get_tag( &p, end, &len,
1189 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1190 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001191 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001192 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001193 }
1194
1195 end = p + len;
1196 crt->tbs.len = end - crt->tbs.p;
1197
1198 /*
1199 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1200 *
1201 * CertificateSerialNumber ::= INTEGER
1202 *
1203 * signature AlgorithmIdentifier
1204 */
1205 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1206 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1207 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
1208 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001209 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001210 return( ret );
1211 }
1212
1213 crt->version++;
1214
1215 if( crt->version > 3 )
1216 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001217 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001218 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001219 }
1220
Paul Bakker27d66162010-03-17 06:56:01 +00001221 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_alg ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001222 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001223 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001224 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001225 }
1226
1227 /*
1228 * issuer Name
1229 */
1230 crt->issuer_raw.p = p;
1231
1232 if( ( ret = asn1_get_tag( &p, end, &len,
1233 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1234 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001235 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001236 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001237 }
1238
1239 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1240 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001241 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001242 return( ret );
1243 }
1244
1245 crt->issuer_raw.len = p - crt->issuer_raw.p;
1246
1247 /*
1248 * Validity ::= SEQUENCE {
1249 * notBefore Time,
1250 * notAfter Time }
1251 *
1252 */
1253 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1254 &crt->valid_to ) ) != 0 )
1255 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001256 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001257 return( ret );
1258 }
1259
1260 /*
1261 * subject Name
1262 */
1263 crt->subject_raw.p = p;
1264
1265 if( ( ret = asn1_get_tag( &p, end, &len,
1266 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1267 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001268 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001269 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001270 }
1271
Paul Bakkercefb3962012-06-27 11:51:09 +00001272 if( len && ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001273 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001274 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001275 return( ret );
1276 }
1277
1278 crt->subject_raw.len = p - crt->subject_raw.p;
1279
1280 /*
1281 * SubjectPublicKeyInfo ::= SEQUENCE
1282 * algorithm AlgorithmIdentifier,
1283 * subjectPublicKey BIT STRING }
1284 */
1285 if( ( ret = asn1_get_tag( &p, end, &len,
1286 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1287 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001288 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001289 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001290 }
1291
1292 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1293 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1294 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001295 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001296 return( ret );
1297 }
1298
1299 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1300 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001301 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001302 return( ret );
1303 }
1304
1305 crt->rsa.len = mpi_size( &crt->rsa.N );
1306
1307 /*
1308 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1309 * -- If present, version shall be v2 or v3
1310 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1311 * -- If present, version shall be v2 or v3
1312 * extensions [3] EXPLICIT Extensions OPTIONAL
1313 * -- If present, version shall be v3
1314 */
1315 if( crt->version == 2 || crt->version == 3 )
1316 {
1317 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1318 if( ret != 0 )
1319 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001320 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001321 return( ret );
1322 }
1323 }
1324
1325 if( crt->version == 2 || crt->version == 3 )
1326 {
1327 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1328 if( ret != 0 )
1329 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001330 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001331 return( ret );
1332 }
1333 }
1334
1335 if( crt->version == 3 )
1336 {
Paul Bakker74111d32011-01-15 16:57:55 +00001337 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001338 if( ret != 0 )
1339 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001340 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001341 return( ret );
1342 }
1343 }
1344
1345 if( p != end )
1346 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001347 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001348 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001349 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001350 }
1351
Paul Bakkerb00ca422012-09-25 12:10:00 +00001352 end = crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001353
1354 /*
1355 * signatureAlgorithm AlgorithmIdentifier,
1356 * signatureValue BIT STRING
1357 */
1358 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1359 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001360 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001361 return( ret );
1362 }
1363
Paul Bakker535e97d2012-08-23 10:49:55 +00001364 if( crt->sig_oid1.len != crt->sig_oid2.len ||
1365 memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001366 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001367 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001368 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001369 }
1370
1371 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1372 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001373 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001374 return( ret );
1375 }
1376
1377 if( p != end )
1378 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001379 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001380 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001381 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001382 }
1383
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001384 return( 0 );
1385}
1386
1387/*
Paul Bakkerd6d41092013-06-13 09:00:25 +02001388 * Parse one X.509 certificate in DER format from a buffer and add them to a
1389 * chained list
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001390 */
Paul Bakkerd6d41092013-06-13 09:00:25 +02001391int x509parse_crt_der( x509_cert *chain, const unsigned char *buf, size_t buflen )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001392{
Paul Bakkerd6d41092013-06-13 09:00:25 +02001393 int ret;
1394 x509_cert *crt = chain, *prev = NULL;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001395
1396 /*
1397 * Check for valid input
1398 */
1399 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001400 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001401
1402 while( crt->version != 0 && crt->next != NULL )
1403 {
1404 prev = crt;
1405 crt = crt->next;
1406 }
1407
1408 /*
1409 * Add new certificate on the end of the chain if needed.
1410 */
1411 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001412 {
1413 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1414
Paul Bakker7d06ad22009-05-02 15:53:56 +00001415 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001416 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker320a4b52009-03-28 18:52:39 +00001417
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001418 prev = crt;
Paul Bakker7d06ad22009-05-02 15:53:56 +00001419 crt = crt->next;
1420 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001421 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001422
Paul Bakkerd6d41092013-06-13 09:00:25 +02001423 if( ( ret = x509parse_crt_der_core( crt, buf, buflen ) ) != 0 )
1424 {
1425 if( prev )
1426 prev->next = NULL;
1427
1428 if( crt != chain )
1429 free( crt );
1430
1431 return( ret );
1432 }
1433
1434 return( 0 );
1435}
1436
1437/*
1438 * Parse one or more PEM certificates from a buffer and add them to the chained list
1439 */
1440int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
1441{
1442 int ret, success = 0, first_error = 0, total_failed = 0;
1443 int buf_format = X509_FORMAT_DER;
1444
1445 /*
1446 * Check for valid input
1447 */
1448 if( chain == NULL || buf == NULL )
1449 return( POLARSSL_ERR_X509_INVALID_INPUT );
1450
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001451 /*
1452 * Determine buffer content. Buffer contains either one DER certificate or
1453 * one or more PEM certificates.
1454 */
1455#if defined(POLARSSL_PEM_C)
Paul Bakkereae09db2013-06-06 12:35:54 +02001456 if( strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001457 buf_format = X509_FORMAT_PEM;
1458#endif
1459
1460 if( buf_format == X509_FORMAT_DER )
Paul Bakkerd6d41092013-06-13 09:00:25 +02001461 return x509parse_crt_der( chain, buf, buflen );
1462
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001463#if defined(POLARSSL_PEM_C)
1464 if( buf_format == X509_FORMAT_PEM )
1465 {
1466 pem_context pem;
1467
1468 while( buflen > 0 )
1469 {
1470 size_t use_len;
1471 pem_init( &pem );
1472
1473 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02001474 (char *) "-----BEGIN CERTIFICATE-----",
1475 (char *) "-----END CERTIFICATE-----",
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001476 buf, NULL, 0, &use_len );
1477
1478 if( ret == 0 )
1479 {
1480 /*
1481 * Was PEM encoded
1482 */
1483 buflen -= use_len;
1484 buf += use_len;
1485 }
Paul Bakker64171862013-06-06 15:01:18 +02001486 else if( ret == POLARSSL_ERR_PEM_BAD_INPUT_DATA )
1487 {
1488 return( ret );
1489 }
Paul Bakker9255e832013-06-06 14:58:28 +02001490 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001491 {
1492 pem_free( &pem );
1493
Paul Bakker64171862013-06-06 15:01:18 +02001494 /*
1495 * PEM header and footer were found
1496 */
1497 buflen -= use_len;
1498 buf += use_len;
1499
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001500 if( first_error == 0 )
1501 first_error = ret;
1502
1503 continue;
1504 }
1505 else
1506 break;
1507
Paul Bakkerd6d41092013-06-13 09:00:25 +02001508 ret = x509parse_crt_der( chain, pem.buf, pem.buflen );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001509
1510 pem_free( &pem );
1511
1512 if( ret != 0 )
1513 {
1514 /*
Paul Bakkerd6d41092013-06-13 09:00:25 +02001515 * Quit parsing on a memory error
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001516 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001517 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001518 return( ret );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001519
1520 if( first_error == 0 )
1521 first_error = ret;
1522
Paul Bakkerd6d41092013-06-13 09:00:25 +02001523 total_failed++;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001524 continue;
1525 }
1526
1527 success = 1;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001528 }
1529 }
1530#endif
1531
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001532 if( success )
Paul Bakker69e095c2011-12-10 21:55:01 +00001533 return( total_failed );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001534 else if( first_error )
1535 return( first_error );
1536 else
1537 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001538}
1539
1540/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001541 * Parse one or more CRLs and add them to the chained list
1542 */
Paul Bakker23986e52011-04-24 08:57:21 +00001543int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001544{
Paul Bakker23986e52011-04-24 08:57:21 +00001545 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001546 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001547 unsigned char *p, *end;
1548 x509_crl *crl;
Paul Bakker96743fc2011-02-12 14:30:57 +00001549#if defined(POLARSSL_PEM_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00001550 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001551 pem_context pem;
1552#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001553
1554 crl = chain;
1555
1556 /*
1557 * Check for valid input
1558 */
1559 if( crl == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001560 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001561
1562 while( crl->version != 0 && crl->next != NULL )
1563 crl = crl->next;
1564
1565 /*
1566 * Add new CRL on the end of the chain if needed.
1567 */
1568 if ( crl->version != 0 && crl->next == NULL)
1569 {
1570 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1571
Paul Bakker7d06ad22009-05-02 15:53:56 +00001572 if( crl->next == NULL )
1573 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001574 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001575 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001576 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001577
Paul Bakker7d06ad22009-05-02 15:53:56 +00001578 crl = crl->next;
1579 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001580 }
1581
Paul Bakker96743fc2011-02-12 14:30:57 +00001582#if defined(POLARSSL_PEM_C)
1583 pem_init( &pem );
1584 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02001585 (char *) "-----BEGIN X509 CRL-----",
1586 (char *) "-----END X509 CRL-----",
Paul Bakker96743fc2011-02-12 14:30:57 +00001587 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001588
Paul Bakker96743fc2011-02-12 14:30:57 +00001589 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001590 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001591 /*
1592 * Was PEM encoded
1593 */
1594 buflen -= use_len;
1595 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001596
1597 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001598 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001599 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001600 p = pem.buf;
1601 pem.buf = NULL;
1602 len = pem.buflen;
1603 pem_free( &pem );
1604 }
Paul Bakker9255e832013-06-06 14:58:28 +02001605 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker96743fc2011-02-12 14:30:57 +00001606 {
1607 pem_free( &pem );
1608 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001609 }
1610 else
1611 {
1612 /*
1613 * nope, copy the raw DER data
1614 */
1615 p = (unsigned char *) malloc( len = buflen );
1616
1617 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001618 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001619
1620 memcpy( p, buf, buflen );
1621
1622 buflen = 0;
1623 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001624#else
1625 p = (unsigned char *) malloc( len = buflen );
1626
1627 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001628 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001629
1630 memcpy( p, buf, buflen );
1631
1632 buflen = 0;
1633#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001634
1635 crl->raw.p = p;
1636 crl->raw.len = len;
1637 end = p + len;
1638
1639 /*
1640 * CertificateList ::= SEQUENCE {
1641 * tbsCertList TBSCertList,
1642 * signatureAlgorithm AlgorithmIdentifier,
1643 * signatureValue BIT STRING }
1644 */
1645 if( ( ret = asn1_get_tag( &p, end, &len,
1646 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1647 {
1648 x509_crl_free( crl );
1649 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1650 }
1651
Paul Bakker23986e52011-04-24 08:57:21 +00001652 if( len != (size_t) ( end - p ) )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001653 {
1654 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001655 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001656 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1657 }
1658
1659 /*
1660 * TBSCertList ::= SEQUENCE {
1661 */
1662 crl->tbs.p = p;
1663
1664 if( ( ret = asn1_get_tag( &p, end, &len,
1665 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1666 {
1667 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001668 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001669 }
1670
1671 end = p + len;
1672 crl->tbs.len = end - crl->tbs.p;
1673
1674 /*
1675 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1676 * -- if present, MUST be v2
1677 *
1678 * signature AlgorithmIdentifier
1679 */
Paul Bakker3329d1f2011-10-12 09:55:01 +00001680 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
Paul Bakkerd98030e2009-05-02 15:13:40 +00001681 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1682 {
1683 x509_crl_free( crl );
1684 return( ret );
1685 }
1686
1687 crl->version++;
1688
1689 if( crl->version > 2 )
1690 {
1691 x509_crl_free( crl );
1692 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1693 }
1694
Paul Bakker27d66162010-03-17 06:56:01 +00001695 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_alg ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001696 {
1697 x509_crl_free( crl );
1698 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1699 }
1700
1701 /*
1702 * issuer Name
1703 */
1704 crl->issuer_raw.p = p;
1705
1706 if( ( ret = asn1_get_tag( &p, end, &len,
1707 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1708 {
1709 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001710 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001711 }
1712
1713 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1714 {
1715 x509_crl_free( crl );
1716 return( ret );
1717 }
1718
1719 crl->issuer_raw.len = p - crl->issuer_raw.p;
1720
1721 /*
1722 * thisUpdate Time
1723 * nextUpdate Time OPTIONAL
1724 */
Paul Bakker91200182010-02-18 21:26:15 +00001725 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001726 {
1727 x509_crl_free( crl );
1728 return( ret );
1729 }
1730
Paul Bakker91200182010-02-18 21:26:15 +00001731 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001732 {
Paul Bakker9d781402011-05-09 16:17:09 +00001733 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001734 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker9d781402011-05-09 16:17:09 +00001735 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001736 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001737 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001738 x509_crl_free( crl );
1739 return( ret );
1740 }
1741 }
1742
1743 /*
1744 * revokedCertificates SEQUENCE OF SEQUENCE {
1745 * userCertificate CertificateSerialNumber,
1746 * revocationDate Time,
1747 * crlEntryExtensions Extensions OPTIONAL
1748 * -- if present, MUST be v2
1749 * } OPTIONAL
1750 */
1751 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1752 {
1753 x509_crl_free( crl );
1754 return( ret );
1755 }
1756
1757 /*
1758 * crlExtensions EXPLICIT Extensions OPTIONAL
1759 * -- if present, MUST be v2
1760 */
1761 if( crl->version == 2 )
1762 {
1763 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1764
1765 if( ret != 0 )
1766 {
1767 x509_crl_free( crl );
1768 return( ret );
1769 }
1770 }
1771
1772 if( p != end )
1773 {
1774 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001775 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001776 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1777 }
1778
1779 end = crl->raw.p + crl->raw.len;
1780
1781 /*
1782 * signatureAlgorithm AlgorithmIdentifier,
1783 * signatureValue BIT STRING
1784 */
1785 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1786 {
1787 x509_crl_free( crl );
1788 return( ret );
1789 }
1790
Paul Bakker535e97d2012-08-23 10:49:55 +00001791 if( crl->sig_oid1.len != crl->sig_oid2.len ||
1792 memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001793 {
1794 x509_crl_free( crl );
1795 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1796 }
1797
1798 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1799 {
1800 x509_crl_free( crl );
1801 return( ret );
1802 }
1803
1804 if( p != end )
1805 {
1806 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001807 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001808 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1809 }
1810
1811 if( buflen > 0 )
1812 {
1813 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1814
Paul Bakker7d06ad22009-05-02 15:53:56 +00001815 if( crl->next == NULL )
1816 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001817 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001818 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001819 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001820
Paul Bakker7d06ad22009-05-02 15:53:56 +00001821 crl = crl->next;
1822 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001823
1824 return( x509parse_crl( crl, buf, buflen ) );
1825 }
1826
1827 return( 0 );
1828}
1829
Paul Bakker335db3f2011-04-25 15:28:35 +00001830#if defined(POLARSSL_FS_IO)
Paul Bakkerd98030e2009-05-02 15:13:40 +00001831/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001832 * Load all data from a file into a given buffer.
1833 */
Paul Bakker1d073c52014-07-08 20:15:51 +02001834static int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001835{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001836 FILE *f;
Paul Bakkerfe7c24c2013-09-11 11:37:33 +02001837 long size;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001838
Paul Bakkerd98030e2009-05-02 15:13:40 +00001839 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001840 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001841
Paul Bakkerd98030e2009-05-02 15:13:40 +00001842 fseek( f, 0, SEEK_END );
Paul Bakkerfe7c24c2013-09-11 11:37:33 +02001843 if( ( size = ftell( f ) ) == -1 )
1844 {
1845 fclose( f );
1846 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1847 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001848 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001849
Paul Bakkerfe7c24c2013-09-11 11:37:33 +02001850 *n = (size_t) size;
1851
1852 if( *n + 1 == 0 ||
1853 ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
1854 {
1855 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +00001856 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerfe7c24c2013-09-11 11:37:33 +02001857 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001858
Paul Bakkerd98030e2009-05-02 15:13:40 +00001859 if( fread( *buf, 1, *n, f ) != *n )
1860 {
1861 fclose( f );
1862 free( *buf );
Paul Bakker69e095c2011-12-10 21:55:01 +00001863 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001864 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001865
Paul Bakkerd98030e2009-05-02 15:13:40 +00001866 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001867
Paul Bakkerd98030e2009-05-02 15:13:40 +00001868 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001869
Paul Bakkerd98030e2009-05-02 15:13:40 +00001870 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001871}
1872
1873/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001874 * Load one or more certificates and add them to the chained list
1875 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001876int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001877{
1878 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001879 size_t n;
1880 unsigned char *buf;
1881
Paul Bakker69e095c2011-12-10 21:55:01 +00001882 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1883 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001884
Paul Bakker69e095c2011-12-10 21:55:01 +00001885 ret = x509parse_crt( chain, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001886
1887 memset( buf, 0, n + 1 );
1888 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001889
1890 return( ret );
1891}
1892
Paul Bakker8d914582012-06-04 12:46:42 +00001893int x509parse_crtpath( x509_cert *chain, const char *path )
1894{
1895 int ret = 0;
1896#if defined(_WIN32)
Paul Bakker3338b792012-10-01 21:13:10 +00001897 int w_ret;
1898 WCHAR szDir[MAX_PATH];
1899 char filename[MAX_PATH];
1900 char *p;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001901 int len = strlen( path );
Paul Bakker3338b792012-10-01 21:13:10 +00001902
Paul Bakker97872ac2012-11-02 12:53:26 +00001903 WIN32_FIND_DATAW file_data;
Paul Bakker8d914582012-06-04 12:46:42 +00001904 HANDLE hFind;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001905
1906 if( len > MAX_PATH - 3 )
1907 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker8d914582012-06-04 12:46:42 +00001908
Paul Bakker3338b792012-10-01 21:13:10 +00001909 memset( szDir, 0, sizeof(szDir) );
1910 memset( filename, 0, MAX_PATH );
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001911 memcpy( filename, path, len );
1912 filename[len++] = '\\';
1913 p = filename + len;
1914 filename[len++] = '*';
Paul Bakker3338b792012-10-01 21:13:10 +00001915
Paul Bakker40cc9142014-07-07 15:16:47 +02001916 w_ret = MultiByteToWideChar( CP_ACP, 0, filename, len, szDir, MAX_PATH - 3 );
Paul Bakker8d914582012-06-04 12:46:42 +00001917
Paul Bakker97872ac2012-11-02 12:53:26 +00001918 hFind = FindFirstFileW( szDir, &file_data );
Paul Bakker8d914582012-06-04 12:46:42 +00001919 if (hFind == INVALID_HANDLE_VALUE)
1920 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1921
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001922 len = MAX_PATH - len;
Paul Bakker8d914582012-06-04 12:46:42 +00001923 do
1924 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001925 memset( p, 0, len );
Paul Bakker3338b792012-10-01 21:13:10 +00001926
Paul Bakkere4791f32012-06-04 21:29:15 +00001927 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
Paul Bakker8d914582012-06-04 12:46:42 +00001928 continue;
1929
Paul Bakker3338b792012-10-01 21:13:10 +00001930 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
1931 lstrlenW(file_data.cFileName),
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001932 p, len - 1,
1933 NULL, NULL );
Paul Bakker8d914582012-06-04 12:46:42 +00001934
Paul Bakker3338b792012-10-01 21:13:10 +00001935 w_ret = x509parse_crtfile( chain, filename );
1936 if( w_ret < 0 )
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001937 ret++;
1938 else
1939 ret += w_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001940 }
Paul Bakker97872ac2012-11-02 12:53:26 +00001941 while( FindNextFileW( hFind, &file_data ) != 0 );
Paul Bakker8d914582012-06-04 12:46:42 +00001942
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001943 if (GetLastError() != ERROR_NO_MORE_FILES)
1944 ret = POLARSSL_ERR_X509_FILE_IO_ERROR;
Paul Bakker8d914582012-06-04 12:46:42 +00001945
1946 FindClose( hFind );
1947#else
Paul Bakker9ccb2112014-07-07 13:43:31 +02001948#if defined(POLARSSL_HAVE_READDIR_R)
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001949 int t_ret, i;
1950 struct stat sb;
1951 struct dirent entry, *result = NULL;
Paul Bakker8d914582012-06-04 12:46:42 +00001952 char entry_name[255];
1953 DIR *dir = opendir( path );
1954
1955 if( dir == NULL)
1956 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1957
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001958 while( ( t_ret = readdir_r( dir, &entry, &result ) ) == 0 )
Paul Bakker8d914582012-06-04 12:46:42 +00001959 {
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001960 if( result == NULL )
1961 break;
1962
1963 snprintf( entry_name, sizeof(entry_name), "%s/%s", path, entry.d_name );
1964
1965 i = stat( entry_name, &sb );
1966
1967 if( i == -1 )
Paul Bakker88a22642013-09-11 12:14:16 +02001968 {
1969 closedir( dir );
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001970 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker88a22642013-09-11 12:14:16 +02001971 }
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001972
1973 if( !S_ISREG( sb.st_mode ) )
Paul Bakker8d914582012-06-04 12:46:42 +00001974 continue;
1975
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001976 // Ignore parse errors
1977 //
Paul Bakker8d914582012-06-04 12:46:42 +00001978 t_ret = x509parse_crtfile( chain, entry_name );
1979 if( t_ret < 0 )
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001980 ret++;
1981 else
1982 ret += t_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001983 }
1984 closedir( dir );
Paul Bakker9ccb2112014-07-07 13:43:31 +02001985#else /* POLARSSL_HAVE_READDIR_R */
1986 ((void) chain);
1987 ((void) path);
1988 ret = POLARSSL_ERR_X509_FEATURE_UNAVAILABLE;
1989#endif /* POLARSSL_HAVE_READDIR_R */
1990#endif /* _WIN32 */
Paul Bakker8d914582012-06-04 12:46:42 +00001991
1992 return( ret );
1993}
1994
Paul Bakkerd98030e2009-05-02 15:13:40 +00001995/*
1996 * Load one or more CRLs and add them to the chained list
1997 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001998int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001999{
2000 int ret;
2001 size_t n;
2002 unsigned char *buf;
2003
Paul Bakker69e095c2011-12-10 21:55:01 +00002004 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2005 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002006
Paul Bakker27fdf462011-06-09 13:55:13 +00002007 ret = x509parse_crl( chain, buf, n );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002008
2009 memset( buf, 0, n + 1 );
2010 free( buf );
2011
2012 return( ret );
2013}
2014
Paul Bakker5121ce52009-01-03 21:22:43 +00002015/*
Paul Bakker335db3f2011-04-25 15:28:35 +00002016 * Load and parse a private RSA key
2017 */
2018int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
2019{
2020 int ret;
2021 size_t n;
2022 unsigned char *buf;
2023
Paul Bakker69e095c2011-12-10 21:55:01 +00002024 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2025 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002026
2027 if( pwd == NULL )
Paul Bakker27fdf462011-06-09 13:55:13 +00002028 ret = x509parse_key( rsa, buf, n, NULL, 0 );
Paul Bakker335db3f2011-04-25 15:28:35 +00002029 else
Paul Bakker27fdf462011-06-09 13:55:13 +00002030 ret = x509parse_key( rsa, buf, n,
Paul Bakker335db3f2011-04-25 15:28:35 +00002031 (unsigned char *) pwd, strlen( pwd ) );
2032
2033 memset( buf, 0, n + 1 );
2034 free( buf );
2035
2036 return( ret );
2037}
2038
2039/*
2040 * Load and parse a public RSA key
2041 */
2042int x509parse_public_keyfile( rsa_context *rsa, const char *path )
2043{
2044 int ret;
2045 size_t n;
2046 unsigned char *buf;
2047
Paul Bakker69e095c2011-12-10 21:55:01 +00002048 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2049 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002050
Paul Bakker27fdf462011-06-09 13:55:13 +00002051 ret = x509parse_public_key( rsa, buf, n );
Paul Bakker335db3f2011-04-25 15:28:35 +00002052
2053 memset( buf, 0, n + 1 );
2054 free( buf );
2055
2056 return( ret );
2057}
2058#endif /* POLARSSL_FS_IO */
2059
2060/*
Paul Bakker65a19092013-06-06 21:14:58 +02002061 * Parse a PKCS#1 encoded private RSA key
Paul Bakker5121ce52009-01-03 21:22:43 +00002062 */
Paul Bakker65a19092013-06-06 21:14:58 +02002063static int x509parse_key_pkcs1_der( rsa_context *rsa,
2064 const unsigned char *key,
2065 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +00002066{
Paul Bakker23986e52011-04-24 08:57:21 +00002067 int ret;
2068 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00002069 unsigned char *p, *end;
Paul Bakkered56b222011-07-13 11:26:43 +00002070
Paul Bakker96743fc2011-02-12 14:30:57 +00002071 p = (unsigned char *) key;
Paul Bakker96743fc2011-02-12 14:30:57 +00002072 end = p + keylen;
2073
Paul Bakker5121ce52009-01-03 21:22:43 +00002074 /*
Paul Bakker65a19092013-06-06 21:14:58 +02002075 * This function parses the RSAPrivateKey (PKCS#1)
Paul Bakkered56b222011-07-13 11:26:43 +00002076 *
Paul Bakker5121ce52009-01-03 21:22:43 +00002077 * RSAPrivateKey ::= SEQUENCE {
2078 * version Version,
2079 * modulus INTEGER, -- n
2080 * publicExponent INTEGER, -- e
2081 * privateExponent INTEGER, -- d
2082 * prime1 INTEGER, -- p
2083 * prime2 INTEGER, -- q
2084 * exponent1 INTEGER, -- d mod (p-1)
2085 * exponent2 INTEGER, -- d mod (q-1)
2086 * coefficient INTEGER, -- (inverse of q) mod p
2087 * otherPrimeInfos OtherPrimeInfos OPTIONAL
2088 * }
2089 */
2090 if( ( ret = asn1_get_tag( &p, end, &len,
2091 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2092 {
Paul Bakker9d781402011-05-09 16:17:09 +00002093 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002094 }
2095
2096 end = p + len;
2097
2098 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2099 {
Paul Bakker9d781402011-05-09 16:17:09 +00002100 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002101 }
2102
2103 if( rsa->ver != 0 )
2104 {
Paul Bakker9d781402011-05-09 16:17:09 +00002105 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002106 }
2107
2108 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
2109 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
2110 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
2111 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
2112 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
2113 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
2114 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
2115 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
2116 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002117 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002118 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002119 }
2120
2121 rsa->len = mpi_size( &rsa->N );
2122
2123 if( p != end )
2124 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002125 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002126 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00002127 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002128 }
2129
2130 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2131 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002132 rsa_free( rsa );
2133 return( ret );
2134 }
2135
Paul Bakker65a19092013-06-06 21:14:58 +02002136 return( 0 );
2137}
2138
2139/*
2140 * Parse an unencrypted PKCS#8 encoded private RSA key
2141 */
2142static int x509parse_key_pkcs8_unencrypted_der(
2143 rsa_context *rsa,
2144 const unsigned char *key,
2145 size_t keylen )
2146{
2147 int ret;
2148 size_t len;
2149 unsigned char *p, *end;
2150 x509_buf pk_alg_oid;
2151
2152 p = (unsigned char *) key;
2153 end = p + keylen;
2154
2155 /*
2156 * This function parses the PrivatKeyInfo object (PKCS#8)
2157 *
2158 * PrivateKeyInfo ::= SEQUENCE {
2159 * version Version,
2160 * algorithm AlgorithmIdentifier,
2161 * PrivateKey BIT STRING
2162 * }
2163 *
2164 * AlgorithmIdentifier ::= SEQUENCE {
2165 * algorithm OBJECT IDENTIFIER,
2166 * parameters ANY DEFINED BY algorithm OPTIONAL
2167 * }
2168 *
2169 * The PrivateKey BIT STRING is a PKCS#1 RSAPrivateKey
2170 */
2171 if( ( ret = asn1_get_tag( &p, end, &len,
2172 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2173 {
2174 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2175 }
2176
2177 end = p + len;
2178
2179 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2180 {
2181 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2182 }
2183
2184 if( rsa->ver != 0 )
2185 {
2186 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2187 }
2188
2189 if( ( ret = x509_get_alg( &p, end, &pk_alg_oid ) ) != 0 )
2190 {
2191 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2192 }
2193
2194 /*
2195 * only RSA keys handled at this time
2196 */
2197 if( pk_alg_oid.len != 9 ||
2198 memcmp( pk_alg_oid.p, OID_PKCS1_RSA, 9 ) != 0 )
2199 {
2200 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
2201 }
2202
2203 /*
2204 * Get the OCTET STRING and parse the PKCS#1 format inside
2205 */
2206 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2207 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2208
2209 if( ( end - p ) < 1 )
2210 {
2211 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
2212 POLARSSL_ERR_ASN1_OUT_OF_DATA );
2213 }
2214
2215 end = p + len;
2216
2217 if( ( ret = x509parse_key_pkcs1_der( rsa, p, end - p ) ) != 0 )
2218 return( ret );
2219
2220 return( 0 );
2221}
2222
2223/*
Paul Bakkerda7fdbd2013-06-19 11:15:43 +02002224 * Parse an encrypted PKCS#8 encoded private RSA key
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002225 */
2226static int x509parse_key_pkcs8_encrypted_der(
2227 rsa_context *rsa,
2228 const unsigned char *key,
2229 size_t keylen,
2230 const unsigned char *pwd,
2231 size_t pwdlen )
2232{
2233 int ret;
2234 size_t len;
2235 unsigned char *p, *end, *end2;
2236 x509_buf pbe_alg_oid, pbe_params;
2237 unsigned char buf[2048];
2238
2239 memset(buf, 0, 2048);
2240
2241 p = (unsigned char *) key;
2242 end = p + keylen;
2243
Paul Bakker1fd43212013-06-17 15:14:42 +02002244 if( pwdlen == 0 )
2245 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
2246
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002247 /*
2248 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
2249 *
2250 * EncryptedPrivateKeyInfo ::= SEQUENCE {
2251 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
2252 * encryptedData EncryptedData
2253 * }
2254 *
2255 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
2256 *
2257 * EncryptedData ::= OCTET STRING
2258 *
2259 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
2260 */
2261 if( ( ret = asn1_get_tag( &p, end, &len,
2262 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2263 {
2264 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2265 }
2266
2267 end = p + len;
2268
2269 if( ( ret = asn1_get_tag( &p, end, &len,
2270 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2271 {
2272 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2273 }
2274
2275 end2 = p + len;
2276
2277 if( ( ret = asn1_get_tag( &p, end, &pbe_alg_oid.len, ASN1_OID ) ) != 0 )
2278 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2279
2280 pbe_alg_oid.p = p;
2281 p += pbe_alg_oid.len;
2282
2283 /*
2284 * Store the algorithm parameters
2285 */
2286 pbe_params.p = p;
2287 pbe_params.len = end2 - p;
2288 p += pbe_params.len;
2289
2290 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2291 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2292
2293 // buf has been sized to 2048 bytes
2294 if( len > 2048 )
2295 return( POLARSSL_ERR_X509_INVALID_INPUT );
2296
2297 /*
2298 * Decrypt EncryptedData with appropriate PDE
2299 */
Paul Bakker14a222c2013-06-18 16:35:48 +02002300#if defined(POLARSSL_PKCS12_C)
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002301 if( OID_CMP( OID_PKCS12_PBE_SHA1_DES3_EDE_CBC, &pbe_alg_oid ) )
2302 {
Paul Bakker14a222c2013-06-18 16:35:48 +02002303 if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
2304 POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1,
2305 pwd, pwdlen, p, len, buf ) ) != 0 )
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002306 {
Paul Bakker14a222c2013-06-18 16:35:48 +02002307 if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH )
2308 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2309
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002310 return( ret );
2311 }
2312 }
2313 else if( OID_CMP( OID_PKCS12_PBE_SHA1_DES2_EDE_CBC, &pbe_alg_oid ) )
2314 {
Paul Bakker14a222c2013-06-18 16:35:48 +02002315 if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
2316 POLARSSL_CIPHER_DES_EDE_CBC, POLARSSL_MD_SHA1,
2317 pwd, pwdlen, p, len, buf ) ) != 0 )
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002318 {
Paul Bakker14a222c2013-06-18 16:35:48 +02002319 if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH )
2320 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2321
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002322 return( ret );
2323 }
2324 }
2325 else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) )
2326 {
2327 if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params,
2328 PKCS12_PBE_DECRYPT,
2329 pwd, pwdlen,
2330 p, len, buf ) ) != 0 )
2331 {
2332 return( ret );
2333 }
Paul Bakker14a222c2013-06-18 16:35:48 +02002334
2335 // Best guess for password mismatch when using RC4. If first tag is
2336 // not ASN1_CONSTRUCTED | ASN1_SEQUENCE
2337 //
2338 if( *buf != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
2339 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002340 }
Paul Bakker14a222c2013-06-18 16:35:48 +02002341 else
2342#endif /* POLARSSL_PKCS12_C */
Paul Bakker1fd43212013-06-17 15:14:42 +02002343#if defined(POLARSSL_PKCS5_C)
Paul Bakker14a222c2013-06-18 16:35:48 +02002344 if( OID_CMP( OID_PKCS5_PBES2, &pbe_alg_oid ) )
Paul Bakker1fd43212013-06-17 15:14:42 +02002345 {
2346 if( ( ret = pkcs5_pbes2( &pbe_params, PKCS5_DECRYPT, pwd, pwdlen,
2347 p, len, buf ) ) != 0 )
2348 {
2349 if( ret == POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH )
2350 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2351
2352 return( ret );
2353 }
2354 }
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002355 else
Paul Bakker14a222c2013-06-18 16:35:48 +02002356#endif /* POLARSSL_PKCS5_C */
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002357 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
2358
2359 return x509parse_key_pkcs8_unencrypted_der( rsa, buf, len );
2360}
2361
2362/*
Paul Bakker65a19092013-06-06 21:14:58 +02002363 * Parse a private RSA key
2364 */
2365int x509parse_key( rsa_context *rsa, const unsigned char *key, size_t keylen,
2366 const unsigned char *pwd, size_t pwdlen )
2367{
2368 int ret;
2369
Paul Bakker96743fc2011-02-12 14:30:57 +00002370#if defined(POLARSSL_PEM_C)
Paul Bakker65a19092013-06-06 21:14:58 +02002371 size_t len;
2372 pem_context pem;
2373
2374 pem_init( &pem );
2375 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02002376 (char *) "-----BEGIN RSA PRIVATE KEY-----",
2377 (char *) "-----END RSA PRIVATE KEY-----",
Paul Bakker65a19092013-06-06 21:14:58 +02002378 key, pwd, pwdlen, &len );
2379 if( ret == 0 )
2380 {
2381 if( ( ret = x509parse_key_pkcs1_der( rsa, pem.buf, pem.buflen ) ) != 0 )
2382 {
2383 rsa_free( rsa );
2384 }
2385
2386 pem_free( &pem );
2387 return( ret );
2388 }
Paul Bakkerb495d3a2013-06-17 15:58:04 +02002389 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
2390 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2391 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
2392 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
Paul Bakker65a19092013-06-06 21:14:58 +02002393 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker65a19092013-06-06 21:14:58 +02002394 return( ret );
Paul Bakker65a19092013-06-06 21:14:58 +02002395
2396 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02002397 (char *) "-----BEGIN PRIVATE KEY-----",
2398 (char *) "-----END PRIVATE KEY-----",
Paul Bakker65a19092013-06-06 21:14:58 +02002399 key, NULL, 0, &len );
2400 if( ret == 0 )
2401 {
2402 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa,
2403 pem.buf, pem.buflen ) ) != 0 )
2404 {
2405 rsa_free( rsa );
2406 }
2407
2408 pem_free( &pem );
2409 return( ret );
2410 }
2411 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker65a19092013-06-06 21:14:58 +02002412 return( ret );
Paul Bakker65a19092013-06-06 21:14:58 +02002413
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002414 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02002415 (char *) "-----BEGIN ENCRYPTED PRIVATE KEY-----",
2416 (char *) "-----END ENCRYPTED PRIVATE KEY-----",
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002417 key, NULL, 0, &len );
2418 if( ret == 0 )
2419 {
2420 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa,
2421 pem.buf, pem.buflen,
2422 pwd, pwdlen ) ) != 0 )
2423 {
2424 rsa_free( rsa );
2425 }
2426
2427 pem_free( &pem );
2428 return( ret );
2429 }
2430 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002431 return( ret );
Paul Bakker65a19092013-06-06 21:14:58 +02002432#else
2433 ((void) pwd);
2434 ((void) pwdlen);
2435#endif /* POLARSSL_PEM_C */
2436
2437 // At this point we only know it's not a PEM formatted key. Could be any
2438 // of the known DER encoded private key formats
2439 //
2440 // We try the different DER format parsers to see if one passes without
2441 // error
2442 //
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002443 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa, key, keylen,
2444 pwd, pwdlen ) ) == 0 )
Paul Bakker65a19092013-06-06 21:14:58 +02002445 {
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002446 return( 0 );
Paul Bakker65a19092013-06-06 21:14:58 +02002447 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002448
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002449 rsa_free( rsa );
Paul Bakker1fd43212013-06-17 15:14:42 +02002450
2451 if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH )
2452 {
2453 return( ret );
2454 }
2455
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002456 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa, key, keylen ) ) == 0 )
2457 return( 0 );
2458
2459 rsa_free( rsa );
Paul Bakker1fd43212013-06-17 15:14:42 +02002460
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002461 if( ( ret = x509parse_key_pkcs1_der( rsa, key, keylen ) ) == 0 )
2462 return( 0 );
2463
2464 rsa_free( rsa );
Paul Bakker1fd43212013-06-17 15:14:42 +02002465
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002466 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00002467}
2468
2469/*
Paul Bakker53019ae2011-03-25 13:58:48 +00002470 * Parse a public RSA key
2471 */
Paul Bakker23986e52011-04-24 08:57:21 +00002472int x509parse_public_key( rsa_context *rsa, const unsigned char *key, size_t keylen )
Paul Bakker53019ae2011-03-25 13:58:48 +00002473{
Paul Bakker23986e52011-04-24 08:57:21 +00002474 int ret;
2475 size_t len;
Paul Bakker53019ae2011-03-25 13:58:48 +00002476 unsigned char *p, *end;
2477 x509_buf alg_oid;
2478#if defined(POLARSSL_PEM_C)
2479 pem_context pem;
2480
2481 pem_init( &pem );
2482 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02002483 (char *) "-----BEGIN PUBLIC KEY-----",
2484 (char *) "-----END PUBLIC KEY-----",
Paul Bakker53019ae2011-03-25 13:58:48 +00002485 key, NULL, 0, &len );
2486
2487 if( ret == 0 )
2488 {
2489 /*
2490 * Was PEM encoded
2491 */
2492 keylen = pem.buflen;
2493 }
Paul Bakker9255e832013-06-06 14:58:28 +02002494 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker53019ae2011-03-25 13:58:48 +00002495 {
2496 pem_free( &pem );
2497 return( ret );
2498 }
2499
2500 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2501#else
2502 p = (unsigned char *) key;
2503#endif
2504 end = p + keylen;
2505
2506 /*
2507 * PublicKeyInfo ::= SEQUENCE {
2508 * algorithm AlgorithmIdentifier,
2509 * PublicKey BIT STRING
2510 * }
2511 *
2512 * AlgorithmIdentifier ::= SEQUENCE {
2513 * algorithm OBJECT IDENTIFIER,
2514 * parameters ANY DEFINED BY algorithm OPTIONAL
2515 * }
2516 *
2517 * RSAPublicKey ::= SEQUENCE {
2518 * modulus INTEGER, -- n
2519 * publicExponent INTEGER -- e
2520 * }
2521 */
2522
2523 if( ( ret = asn1_get_tag( &p, end, &len,
2524 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2525 {
2526#if defined(POLARSSL_PEM_C)
2527 pem_free( &pem );
2528#endif
2529 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002530 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002531 }
2532
2533 if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
2534 {
2535#if defined(POLARSSL_PEM_C)
2536 pem_free( &pem );
2537#endif
2538 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002539 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002540 }
2541
2542 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
2543 {
2544#if defined(POLARSSL_PEM_C)
2545 pem_free( &pem );
2546#endif
2547 rsa_free( rsa );
2548 return( ret );
2549 }
2550
2551 rsa->len = mpi_size( &rsa->N );
2552
2553#if defined(POLARSSL_PEM_C)
2554 pem_free( &pem );
2555#endif
2556
2557 return( 0 );
2558}
2559
Paul Bakkereaa89f82011-04-04 21:36:15 +00002560#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00002561/*
Paul Bakker1b57b062011-01-06 15:48:19 +00002562 * Parse DHM parameters
2563 */
Paul Bakker23986e52011-04-24 08:57:21 +00002564int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
Paul Bakker1b57b062011-01-06 15:48:19 +00002565{
Paul Bakker23986e52011-04-24 08:57:21 +00002566 int ret;
2567 size_t len;
Paul Bakker1b57b062011-01-06 15:48:19 +00002568 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00002569#if defined(POLARSSL_PEM_C)
2570 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00002571
Paul Bakker96743fc2011-02-12 14:30:57 +00002572 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00002573
Paul Bakker96743fc2011-02-12 14:30:57 +00002574 ret = pem_read_buffer( &pem,
Paul Bakker1d073c52014-07-08 20:15:51 +02002575 (char *) "-----BEGIN DH PARAMETERS-----",
2576 (char *) "-----END DH PARAMETERS-----",
Paul Bakker96743fc2011-02-12 14:30:57 +00002577 dhmin, NULL, 0, &dhminlen );
2578
2579 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00002580 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002581 /*
2582 * Was PEM encoded
2583 */
2584 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00002585 }
Paul Bakker9255e832013-06-06 14:58:28 +02002586 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00002587 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002588 pem_free( &pem );
2589 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002590 }
2591
Paul Bakker96743fc2011-02-12 14:30:57 +00002592 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
2593#else
2594 p = (unsigned char *) dhmin;
2595#endif
2596 end = p + dhminlen;
2597
Paul Bakker1b57b062011-01-06 15:48:19 +00002598 memset( dhm, 0, sizeof( dhm_context ) );
2599
Paul Bakker1b57b062011-01-06 15:48:19 +00002600 /*
2601 * DHParams ::= SEQUENCE {
2602 * prime INTEGER, -- P
2603 * generator INTEGER, -- g
2604 * }
2605 */
2606 if( ( ret = asn1_get_tag( &p, end, &len,
2607 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2608 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002609#if defined(POLARSSL_PEM_C)
2610 pem_free( &pem );
2611#endif
Paul Bakker9d781402011-05-09 16:17:09 +00002612 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002613 }
2614
2615 end = p + len;
2616
2617 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
2618 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
2619 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002620#if defined(POLARSSL_PEM_C)
2621 pem_free( &pem );
2622#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002623 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002624 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002625 }
2626
2627 if( p != end )
2628 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002629#if defined(POLARSSL_PEM_C)
2630 pem_free( &pem );
2631#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002632 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002633 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker1b57b062011-01-06 15:48:19 +00002634 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
2635 }
2636
Paul Bakker96743fc2011-02-12 14:30:57 +00002637#if defined(POLARSSL_PEM_C)
2638 pem_free( &pem );
2639#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002640
2641 return( 0 );
2642}
2643
Paul Bakker335db3f2011-04-25 15:28:35 +00002644#if defined(POLARSSL_FS_IO)
Paul Bakker1b57b062011-01-06 15:48:19 +00002645/*
2646 * Load and parse a private RSA key
2647 */
2648int x509parse_dhmfile( dhm_context *dhm, const char *path )
2649{
2650 int ret;
2651 size_t n;
2652 unsigned char *buf;
2653
Paul Bakker69e095c2011-12-10 21:55:01 +00002654 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
2655 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002656
Paul Bakker27fdf462011-06-09 13:55:13 +00002657 ret = x509parse_dhm( dhm, buf, n );
Paul Bakker1b57b062011-01-06 15:48:19 +00002658
2659 memset( buf, 0, n + 1 );
2660 free( buf );
2661
2662 return( ret );
2663}
Paul Bakker335db3f2011-04-25 15:28:35 +00002664#endif /* POLARSSL_FS_IO */
Paul Bakkereaa89f82011-04-04 21:36:15 +00002665#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00002666
Paul Bakker5121ce52009-01-03 21:22:43 +00002667#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002668#include <stdarg.h>
2669
2670#if !defined vsnprintf
2671#define vsnprintf _vsnprintf
2672#endif // vsnprintf
2673
2674/*
2675 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2676 * Result value is not size of buffer needed, but -1 if no fit is possible.
2677 *
2678 * This fuction tries to 'fix' this by at least suggesting enlarging the
2679 * size by 20.
2680 */
2681int compat_snprintf(char *str, size_t size, const char *format, ...)
2682{
2683 va_list ap;
2684 int res = -1;
2685
2686 va_start( ap, format );
2687
2688 res = vsnprintf( str, size, format, ap );
2689
2690 va_end( ap );
2691
2692 // No quick fix possible
2693 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00002694 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002695
2696 return res;
2697}
2698
2699#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002700#endif
2701
Paul Bakkerd98030e2009-05-02 15:13:40 +00002702#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2703
2704#define SAFE_SNPRINTF() \
2705{ \
2706 if( ret == -1 ) \
2707 return( -1 ); \
2708 \
Paul Bakker23986e52011-04-24 08:57:21 +00002709 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002710 p[n - 1] = '\0'; \
2711 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2712 } \
2713 \
Paul Bakker23986e52011-04-24 08:57:21 +00002714 n -= (unsigned int) ret; \
2715 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002716}
2717
Paul Bakker5121ce52009-01-03 21:22:43 +00002718/*
2719 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002720 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002721 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002722int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002723{
Paul Bakker23986e52011-04-24 08:57:21 +00002724 int ret;
2725 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002726 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002727 const x509_name *name;
Paul Bakker5121ce52009-01-03 21:22:43 +00002728 char s[128], *p;
2729
2730 memset( s, 0, sizeof( s ) );
2731
2732 name = dn;
2733 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002734 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002735
2736 while( name != NULL )
2737 {
Paul Bakkercefb3962012-06-27 11:51:09 +00002738 if( !name->oid.p )
2739 {
2740 name = name->next;
2741 continue;
2742 }
2743
Paul Bakker74111d32011-01-15 16:57:55 +00002744 if( name != dn )
2745 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002746 ret = snprintf( p, n, ", " );
2747 SAFE_SNPRINTF();
2748 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002749
Paul Bakker535e97d2012-08-23 10:49:55 +00002750 if( name->oid.len == 3 &&
2751 memcmp( name->oid.p, OID_X520, 2 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002752 {
2753 switch( name->oid.p[2] )
2754 {
2755 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002756 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002757
2758 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002759 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002760
2761 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002762 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002763
2764 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002765 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002766
2767 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002768 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002769
2770 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002771 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002772
2773 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002774 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002775 name->oid.p[2] );
2776 break;
2777 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002778 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002779 }
Paul Bakker535e97d2012-08-23 10:49:55 +00002780 else if( name->oid.len == 9 &&
2781 memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002782 {
2783 switch( name->oid.p[8] )
2784 {
2785 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002786 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002787
2788 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002789 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002790 name->oid.p[8] );
2791 break;
2792 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002793 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002794 }
2795 else
Paul Bakker74111d32011-01-15 16:57:55 +00002796 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002797 ret = snprintf( p, n, "\?\?=" );
Paul Bakker74111d32011-01-15 16:57:55 +00002798 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002799 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002800
2801 for( i = 0; i < name->val.len; i++ )
2802 {
Paul Bakker27fdf462011-06-09 13:55:13 +00002803 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002804 break;
2805
2806 c = name->val.p[i];
2807 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2808 s[i] = '?';
2809 else s[i] = c;
2810 }
2811 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002812 ret = snprintf( p, n, "%s", s );
2813 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002814 name = name->next;
2815 }
2816
Paul Bakker23986e52011-04-24 08:57:21 +00002817 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002818}
2819
2820/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002821 * Store the serial in printable form into buf; no more
2822 * than size characters will be written
2823 */
2824int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2825{
Paul Bakker23986e52011-04-24 08:57:21 +00002826 int ret;
2827 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00002828 char *p;
2829
2830 p = buf;
2831 n = size;
2832
2833 nr = ( serial->len <= 32 )
Paul Bakker03c7c252011-11-25 12:37:37 +00002834 ? serial->len : 28;
Paul Bakkerdd476992011-01-16 21:34:59 +00002835
2836 for( i = 0; i < nr; i++ )
2837 {
Paul Bakker93048802011-12-05 14:38:06 +00002838 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002839 continue;
2840
Paul Bakkerdd476992011-01-16 21:34:59 +00002841 ret = snprintf( p, n, "%02X%s",
2842 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2843 SAFE_SNPRINTF();
2844 }
2845
Paul Bakker03c7c252011-11-25 12:37:37 +00002846 if( nr != serial->len )
2847 {
2848 ret = snprintf( p, n, "...." );
2849 SAFE_SNPRINTF();
2850 }
2851
Paul Bakker23986e52011-04-24 08:57:21 +00002852 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00002853}
2854
2855/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002856 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002857 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002858int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2859 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002860{
Paul Bakker23986e52011-04-24 08:57:21 +00002861 int ret;
2862 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002863 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00002864
2865 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002866 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002867
Paul Bakkerd98030e2009-05-02 15:13:40 +00002868 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002869 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002870 SAFE_SNPRINTF();
2871 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002872 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002873 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002874
Paul Bakkerdd476992011-01-16 21:34:59 +00002875 ret = x509parse_serial_gets( p, n, &crt->serial);
2876 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002877
Paul Bakkerd98030e2009-05-02 15:13:40 +00002878 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2879 SAFE_SNPRINTF();
2880 ret = x509parse_dn_gets( p, n, &crt->issuer );
2881 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002882
Paul Bakkerd98030e2009-05-02 15:13:40 +00002883 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2884 SAFE_SNPRINTF();
2885 ret = x509parse_dn_gets( p, n, &crt->subject );
2886 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002887
Paul Bakkerd98030e2009-05-02 15:13:40 +00002888 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002889 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2890 crt->valid_from.year, crt->valid_from.mon,
2891 crt->valid_from.day, crt->valid_from.hour,
2892 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002893 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002894
Paul Bakkerd98030e2009-05-02 15:13:40 +00002895 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002896 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2897 crt->valid_to.year, crt->valid_to.mon,
2898 crt->valid_to.day, crt->valid_to.hour,
2899 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002900 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002901
Paul Bakkerd98030e2009-05-02 15:13:40 +00002902 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2903 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002904
Paul Bakker27d66162010-03-17 06:56:01 +00002905 switch( crt->sig_alg )
Paul Bakker5121ce52009-01-03 21:22:43 +00002906 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002907 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2908 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2909 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2910 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2911 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2912 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2913 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2914 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2915 default: ret = snprintf( p, n, "???" ); break;
2916 }
2917 SAFE_SNPRINTF();
2918
2919 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
Paul Bakker5c2364c2012-10-01 14:41:15 +00002920 (int) crt->rsa.N.n * (int) sizeof( t_uint ) * 8 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002921 SAFE_SNPRINTF();
2922
Paul Bakker23986e52011-04-24 08:57:21 +00002923 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002924}
2925
Paul Bakker74111d32011-01-15 16:57:55 +00002926/*
2927 * Return an informational string describing the given OID
2928 */
2929const char *x509_oid_get_description( x509_buf *oid )
2930{
2931 if ( oid == NULL )
2932 return ( NULL );
2933
2934 else if( OID_CMP( OID_SERVER_AUTH, oid ) )
2935 return( STRING_SERVER_AUTH );
2936
2937 else if( OID_CMP( OID_CLIENT_AUTH, oid ) )
2938 return( STRING_CLIENT_AUTH );
2939
2940 else if( OID_CMP( OID_CODE_SIGNING, oid ) )
2941 return( STRING_CODE_SIGNING );
2942
2943 else if( OID_CMP( OID_EMAIL_PROTECTION, oid ) )
2944 return( STRING_EMAIL_PROTECTION );
2945
2946 else if( OID_CMP( OID_TIME_STAMPING, oid ) )
2947 return( STRING_TIME_STAMPING );
2948
2949 else if( OID_CMP( OID_OCSP_SIGNING, oid ) )
2950 return( STRING_OCSP_SIGNING );
2951
2952 return( NULL );
2953}
2954
2955/* Return the x.y.z.... style numeric string for the given OID */
2956int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2957{
Paul Bakker23986e52011-04-24 08:57:21 +00002958 int ret;
2959 size_t i, n;
Paul Bakker74111d32011-01-15 16:57:55 +00002960 unsigned int value;
2961 char *p;
2962
2963 p = buf;
2964 n = size;
2965
2966 /* First byte contains first two dots */
2967 if( oid->len > 0 )
2968 {
2969 ret = snprintf( p, n, "%d.%d", oid->p[0]/40, oid->p[0]%40 );
2970 SAFE_SNPRINTF();
2971 }
2972
2973 /* TODO: value can overflow in value. */
2974 value = 0;
Paul Bakker23986e52011-04-24 08:57:21 +00002975 for( i = 1; i < oid->len; i++ )
Paul Bakker74111d32011-01-15 16:57:55 +00002976 {
2977 value <<= 7;
2978 value += oid->p[i] & 0x7F;
2979
2980 if( !( oid->p[i] & 0x80 ) )
2981 {
2982 /* Last byte */
2983 ret = snprintf( p, n, ".%d", value );
2984 SAFE_SNPRINTF();
2985 value = 0;
2986 }
2987 }
2988
Paul Bakker23986e52011-04-24 08:57:21 +00002989 return( (int) ( size - n ) );
Paul Bakker74111d32011-01-15 16:57:55 +00002990}
2991
Paul Bakkerd98030e2009-05-02 15:13:40 +00002992/*
2993 * Return an informational string about the CRL.
2994 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002995int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2996 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002997{
Paul Bakker23986e52011-04-24 08:57:21 +00002998 int ret;
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002999 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003000 char *p;
Paul Bakkerff60ee62010-03-16 21:09:09 +00003001 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003002
3003 p = buf;
3004 n = size;
3005
3006 ret = snprintf( p, n, "%sCRL version : %d",
3007 prefix, crl->version );
3008 SAFE_SNPRINTF();
3009
3010 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
3011 SAFE_SNPRINTF();
3012 ret = x509parse_dn_gets( p, n, &crl->issuer );
3013 SAFE_SNPRINTF();
3014
3015 ret = snprintf( p, n, "\n%sthis update : " \
3016 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3017 crl->this_update.year, crl->this_update.mon,
3018 crl->this_update.day, crl->this_update.hour,
3019 crl->this_update.min, crl->this_update.sec );
3020 SAFE_SNPRINTF();
3021
3022 ret = snprintf( p, n, "\n%snext update : " \
3023 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3024 crl->next_update.year, crl->next_update.mon,
3025 crl->next_update.day, crl->next_update.hour,
3026 crl->next_update.min, crl->next_update.sec );
3027 SAFE_SNPRINTF();
3028
3029 entry = &crl->entry;
3030
3031 ret = snprintf( p, n, "\n%sRevoked certificates:",
3032 prefix );
3033 SAFE_SNPRINTF();
3034
Paul Bakker9be19372009-07-27 20:21:53 +00003035 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003036 {
3037 ret = snprintf( p, n, "\n%sserial number: ",
3038 prefix );
3039 SAFE_SNPRINTF();
3040
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003041 ret = x509parse_serial_gets( p, n, &entry->serial);
3042 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003043
Paul Bakkerd98030e2009-05-02 15:13:40 +00003044 ret = snprintf( p, n, " revocation date: " \
3045 "%04d-%02d-%02d %02d:%02d:%02d",
3046 entry->revocation_date.year, entry->revocation_date.mon,
3047 entry->revocation_date.day, entry->revocation_date.hour,
3048 entry->revocation_date.min, entry->revocation_date.sec );
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003049 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003050
3051 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003052 }
3053
Paul Bakkerd98030e2009-05-02 15:13:40 +00003054 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
3055 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003056
Paul Bakker27d66162010-03-17 06:56:01 +00003057 switch( crl->sig_alg )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003058 {
3059 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
3060 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
3061 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
3062 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
3063 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
3064 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
3065 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
3066 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
3067 default: ret = snprintf( p, n, "???" ); break;
3068 }
3069 SAFE_SNPRINTF();
3070
Paul Bakker1e27bb22009-07-19 20:25:25 +00003071 ret = snprintf( p, n, "\n" );
3072 SAFE_SNPRINTF();
3073
Paul Bakker23986e52011-04-24 08:57:21 +00003074 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003075}
3076
3077/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00003078 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00003079 */
Paul Bakker0d844dd2014-07-07 17:44:14 +02003080static void x509_get_current_time( x509_time *now )
Paul Bakker5121ce52009-01-03 21:22:43 +00003081{
Paul Bakkercce9d772011-11-18 14:26:47 +00003082#if defined(_WIN32)
3083 SYSTEMTIME st;
3084
Paul Bakkerf48de952014-07-08 14:39:41 +02003085 GetSystemTime(&st);
Paul Bakkercce9d772011-11-18 14:26:47 +00003086
Paul Bakker0d844dd2014-07-07 17:44:14 +02003087 now->year = st.wYear;
3088 now->mon = st.wMonth;
3089 now->day = st.wDay;
3090 now->hour = st.wHour;
3091 now->min = st.wMinute;
3092 now->sec = st.wSecond;
Paul Bakkercce9d772011-11-18 14:26:47 +00003093#else
Paul Bakker358a8412014-07-08 12:14:37 +02003094 struct tm lt;
Paul Bakker5121ce52009-01-03 21:22:43 +00003095 time_t tt;
3096
3097 tt = time( NULL );
Paul Bakkerf48de952014-07-08 14:39:41 +02003098 gmtime_r( &tt, &lt );
Paul Bakker5121ce52009-01-03 21:22:43 +00003099
Paul Bakker358a8412014-07-08 12:14:37 +02003100 now->year = lt.tm_year + 1900;
3101 now->mon = lt.tm_mon + 1;
3102 now->day = lt.tm_mday;
3103 now->hour = lt.tm_hour;
3104 now->min = lt.tm_min;
3105 now->sec = lt.tm_sec;
Paul Bakkercce9d772011-11-18 14:26:47 +00003106#endif
Paul Bakker0d844dd2014-07-07 17:44:14 +02003107}
Paul Bakkercce9d772011-11-18 14:26:47 +00003108
Paul Bakker0d844dd2014-07-07 17:44:14 +02003109/*
3110 * Return 0 if before <= after, 1 otherwise
3111 */
3112static int x509_check_time( const x509_time *before, const x509_time *after )
3113{
3114 if( before->year > after->year )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003115 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003116
Paul Bakker0d844dd2014-07-07 17:44:14 +02003117 if( before->year == after->year &&
3118 before->mon > after->mon )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003119 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003120
Paul Bakker0d844dd2014-07-07 17:44:14 +02003121 if( before->year == after->year &&
3122 before->mon == after->mon &&
3123 before->day > after->day )
Paul Bakker40ea7de2009-05-03 10:18:48 +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 )
Paul Bakkerb6194992011-01-16 21:40:22 +00003130 return( 1 );
3131
Paul Bakker0d844dd2014-07-07 17:44:14 +02003132 if( before->year == after->year &&
3133 before->mon == after->mon &&
3134 before->day == after->day &&
3135 before->hour == after->hour &&
3136 before->min > after->min )
Paul Bakkerb6194992011-01-16 21:40:22 +00003137 return( 1 );
3138
Paul Bakker0d844dd2014-07-07 17:44:14 +02003139 if( before->year == after->year &&
3140 before->mon == after->mon &&
3141 before->day == after->day &&
3142 before->hour == after->hour &&
3143 before->min == after->min &&
3144 before->sec > after->sec )
Paul Bakkerb6194992011-01-16 21:40:22 +00003145 return( 1 );
3146
Paul Bakker40ea7de2009-05-03 10:18:48 +00003147 return( 0 );
3148}
3149
Paul Bakker0d844dd2014-07-07 17:44:14 +02003150int x509parse_time_expired( const x509_time *to )
3151{
3152 x509_time now;
3153
3154 x509_get_current_time( &now );
3155
3156 return( x509_check_time( &now, to ) );
3157}
3158
3159int x509parse_time_future( const x509_time *from )
3160{
3161 x509_time now;
3162
3163 x509_get_current_time( &now );
3164
3165 return( x509_check_time( from, &now ) );
3166}
3167
Paul Bakker40ea7de2009-05-03 10:18:48 +00003168/*
3169 * Return 1 if the certificate is revoked, or 0 otherwise.
3170 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003171int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003172{
Paul Bakkerff60ee62010-03-16 21:09:09 +00003173 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00003174
3175 while( cur != NULL && cur->serial.len != 0 )
3176 {
Paul Bakkera056efc2011-01-16 21:38:35 +00003177 if( crt->serial.len == cur->serial.len &&
3178 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003179 {
3180 if( x509parse_time_expired( &cur->revocation_date ) )
3181 return( 1 );
3182 }
3183
3184 cur = cur->next;
3185 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003186
3187 return( 0 );
3188}
3189
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003190/*
3191 * Wrapper for x509 hashes.
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003192 */
Paul Bakker23986e52011-04-24 08:57:21 +00003193static void x509_hash( const unsigned char *in, size_t len, int alg,
Paul Bakker5121ce52009-01-03 21:22:43 +00003194 unsigned char *out )
3195{
3196 switch( alg )
3197 {
Paul Bakker40e46942009-01-03 21:51:57 +00003198#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003199 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003200#endif
Paul Bakker40e46942009-01-03 21:51:57 +00003201#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003202 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003203#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003204#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003205 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003206#endif
3207#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003208 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003209#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00003210#if defined(POLARSSL_SHA2_C)
3211 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
3212 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
3213#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00003214#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003215 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
3216 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
3217#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003218 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003219 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003220 break;
3221 }
3222}
3223
3224/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00003225 * Check that the given certificate is valid accoring to the CRL.
3226 */
3227static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
3228 x509_crl *crl_list)
3229{
3230 int flags = 0;
3231 int hash_id;
3232 unsigned char hash[64];
3233
Paul Bakker915275b2012-09-28 07:10:55 +00003234 if( ca == NULL )
3235 return( flags );
3236
Paul Bakker76fd75a2011-01-16 21:12:10 +00003237 /*
3238 * TODO: What happens if no CRL is present?
3239 * Suggestion: Revocation state should be unknown if no CRL is present.
3240 * For backwards compatibility this is not yet implemented.
3241 */
3242
Paul Bakker915275b2012-09-28 07:10:55 +00003243 while( crl_list != NULL )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003244 {
Paul Bakker915275b2012-09-28 07:10:55 +00003245 if( crl_list->version == 0 ||
3246 crl_list->issuer_raw.len != ca->subject_raw.len ||
Paul Bakker76fd75a2011-01-16 21:12:10 +00003247 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
3248 crl_list->issuer_raw.len ) != 0 )
3249 {
3250 crl_list = crl_list->next;
3251 continue;
3252 }
3253
3254 /*
3255 * Check if CRL is correctly signed by the trusted CA
3256 */
3257 hash_id = crl_list->sig_alg;
3258
3259 x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
3260
Paul Bakker43f97992013-09-23 11:23:31 +02003261 if( !rsa_pkcs1_verify( &ca->rsa, NULL, NULL, RSA_PUBLIC, hash_id,
Paul Bakker76fd75a2011-01-16 21:12:10 +00003262 0, hash, crl_list->sig.p ) == 0 )
3263 {
3264 /*
3265 * CRL is not trusted
3266 */
3267 flags |= BADCRL_NOT_TRUSTED;
3268 break;
3269 }
3270
3271 /*
3272 * Check for validity of CRL (Do not drop out)
3273 */
3274 if( x509parse_time_expired( &crl_list->next_update ) )
3275 flags |= BADCRL_EXPIRED;
3276
Paul Bakker50a5c532014-07-08 10:59:10 +02003277 if( x509parse_time_future( &crl_list->this_update ) )
3278 flags |= BADCRL_FUTURE;
3279
Paul Bakker76fd75a2011-01-16 21:12:10 +00003280 /*
3281 * Check if certificate is revoked
3282 */
3283 if( x509parse_revoked(crt, crl_list) )
3284 {
3285 flags |= BADCERT_REVOKED;
3286 break;
3287 }
3288
3289 crl_list = crl_list->next;
3290 }
3291 return flags;
3292}
3293
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003294// Equal == 0, inequal == 1
3295static int x509_name_cmp( const void *s1, const void *s2, size_t len )
3296{
3297 size_t i;
3298 unsigned char diff;
3299 const unsigned char *n1 = s1, *n2 = s2;
3300
3301 for( i = 0; i < len; i++ )
3302 {
3303 diff = n1[i] ^ n2[i];
3304
Paul Bakkerc941adb2014-07-07 14:17:24 +02003305 if( diff == 0 )
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003306 continue;
3307
Paul Bakkerc941adb2014-07-07 14:17:24 +02003308 if( diff == 32 &&
3309 ( ( n1[i] >= 'a' && n1[i] <= 'z' ) ||
3310 ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) )
3311 {
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003312 continue;
Paul Bakkerc941adb2014-07-07 14:17:24 +02003313 }
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003314
3315 return( 1 );
3316 }
3317
3318 return( 0 );
3319}
3320
Paul Bakker1d073c52014-07-08 20:15:51 +02003321static int x509_wildcard_verify( const char *cn, x509_buf *name )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003322{
3323 size_t i;
3324 size_t cn_idx = 0;
3325
Paul Bakker57b12982012-02-11 17:38:38 +00003326 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003327 return( 0 );
3328
3329 for( i = 0; i < strlen( cn ); ++i )
3330 {
3331 if( cn[i] == '.' )
3332 {
3333 cn_idx = i;
3334 break;
3335 }
3336 }
3337
3338 if( cn_idx == 0 )
3339 return( 0 );
3340
Paul Bakker535e97d2012-08-23 10:49:55 +00003341 if( strlen( cn ) - cn_idx == name->len - 1 &&
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003342 x509_name_cmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003343 {
3344 return( 1 );
3345 }
3346
3347 return( 0 );
3348}
3349
Paul Bakker915275b2012-09-28 07:10:55 +00003350static int x509parse_verify_top(
3351 x509_cert *child, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003352 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003353 int (*f_vrfy)(void *, x509_cert *, int, int *),
3354 void *p_vrfy )
3355{
3356 int hash_id, ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003357 int ca_flags = 0, check_path_cnt = path_cnt + 1;
Paul Bakker915275b2012-09-28 07:10:55 +00003358 unsigned char hash[64];
3359
3360 if( x509parse_time_expired( &child->valid_to ) )
3361 *flags |= BADCERT_EXPIRED;
3362
Paul Bakker50a5c532014-07-08 10:59:10 +02003363 if( x509parse_time_future( &child->valid_from ) )
3364 *flags |= BADCERT_FUTURE;
3365
Paul Bakker915275b2012-09-28 07:10:55 +00003366 /*
3367 * Child is the top of the chain. Check against the trust_ca list.
3368 */
3369 *flags |= BADCERT_NOT_TRUSTED;
3370
3371 while( trust_ca != NULL )
3372 {
3373 if( trust_ca->version == 0 ||
3374 child->issuer_raw.len != trust_ca->subject_raw.len ||
3375 memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
3376 child->issuer_raw.len ) != 0 )
3377 {
3378 trust_ca = trust_ca->next;
3379 continue;
3380 }
3381
Paul Bakker9a736322012-11-14 12:39:52 +00003382 /*
3383 * Reduce path_len to check against if top of the chain is
3384 * the same as the trusted CA
3385 */
3386 if( child->subject_raw.len == trust_ca->subject_raw.len &&
3387 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3388 child->issuer_raw.len ) == 0 )
3389 {
3390 check_path_cnt--;
3391 }
3392
Paul Bakker915275b2012-09-28 07:10:55 +00003393 if( trust_ca->max_pathlen > 0 &&
Paul Bakker9a736322012-11-14 12:39:52 +00003394 trust_ca->max_pathlen < check_path_cnt )
Paul Bakker915275b2012-09-28 07:10:55 +00003395 {
3396 trust_ca = trust_ca->next;
3397 continue;
3398 }
3399
3400 hash_id = child->sig_alg;
3401
3402 x509_hash( child->tbs.p, child->tbs.len, hash_id, hash );
3403
Paul Bakker43f97992013-09-23 11:23:31 +02003404 if( rsa_pkcs1_verify( &trust_ca->rsa, NULL, NULL, RSA_PUBLIC, hash_id,
Paul Bakker915275b2012-09-28 07:10:55 +00003405 0, hash, child->sig.p ) != 0 )
3406 {
3407 trust_ca = trust_ca->next;
3408 continue;
3409 }
3410
3411 /*
3412 * Top of chain is signed by a trusted CA
3413 */
3414 *flags &= ~BADCERT_NOT_TRUSTED;
3415 break;
3416 }
3417
Paul Bakker9a736322012-11-14 12:39:52 +00003418 /*
Paul Bakker3497d8c2012-11-24 11:53:17 +01003419 * If top of chain is not the same as the trusted CA send a verify request
3420 * to the callback for any issues with validity and CRL presence for the
3421 * trusted CA certificate.
Paul Bakker9a736322012-11-14 12:39:52 +00003422 */
3423 if( trust_ca != NULL &&
3424 ( child->subject_raw.len != trust_ca->subject_raw.len ||
3425 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3426 child->issuer_raw.len ) != 0 ) )
Paul Bakker915275b2012-09-28 07:10:55 +00003427 {
3428 /* Check trusted CA's CRL for then chain's top crt */
3429 *flags |= x509parse_verifycrl( child, trust_ca, ca_crl );
3430
3431 if( x509parse_time_expired( &trust_ca->valid_to ) )
3432 ca_flags |= BADCERT_EXPIRED;
3433
Paul Bakker50a5c532014-07-08 10:59:10 +02003434 if( x509parse_time_future( &trust_ca->valid_from ) )
3435 ca_flags |= BADCERT_FUTURE;
3436
Paul Bakker915275b2012-09-28 07:10:55 +00003437 if( NULL != f_vrfy )
3438 {
Paul Bakker9a736322012-11-14 12:39:52 +00003439 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003440 return( ret );
3441 }
3442 }
3443
3444 /* Call callback on top cert */
3445 if( NULL != f_vrfy )
3446 {
Paul Bakker9a736322012-11-14 12:39:52 +00003447 if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003448 return( ret );
3449 }
3450
Paul Bakker915275b2012-09-28 07:10:55 +00003451 *flags |= ca_flags;
3452
3453 return( 0 );
3454}
3455
3456static int x509parse_verify_child(
3457 x509_cert *child, x509_cert *parent, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003458 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003459 int (*f_vrfy)(void *, x509_cert *, int, int *),
3460 void *p_vrfy )
3461{
3462 int hash_id, ret;
3463 int parent_flags = 0;
3464 unsigned char hash[64];
3465 x509_cert *grandparent;
3466
3467 if( x509parse_time_expired( &child->valid_to ) )
3468 *flags |= BADCERT_EXPIRED;
3469
Paul Bakker50a5c532014-07-08 10:59:10 +02003470 if( x509parse_time_future( &child->valid_from ) )
3471 *flags |= BADCERT_FUTURE;
3472
Paul Bakker915275b2012-09-28 07:10:55 +00003473 hash_id = child->sig_alg;
3474
3475 x509_hash( child->tbs.p, child->tbs.len, hash_id, hash );
3476
Paul Bakker43f97992013-09-23 11:23:31 +02003477 if( rsa_pkcs1_verify( &parent->rsa, NULL, NULL, RSA_PUBLIC, hash_id, 0,
3478 hash, child->sig.p ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003479 *flags |= BADCERT_NOT_TRUSTED;
3480
3481 /* Check trusted CA's CRL for the given crt */
3482 *flags |= x509parse_verifycrl(child, parent, ca_crl);
3483
3484 grandparent = parent->next;
3485
3486 while( grandparent != NULL )
3487 {
3488 if( grandparent->version == 0 ||
3489 grandparent->ca_istrue == 0 ||
3490 parent->issuer_raw.len != grandparent->subject_raw.len ||
3491 memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
3492 parent->issuer_raw.len ) != 0 )
3493 {
3494 grandparent = grandparent->next;
3495 continue;
3496 }
3497 break;
3498 }
3499
Paul Bakker915275b2012-09-28 07:10:55 +00003500 if( grandparent != NULL )
3501 {
3502 /*
3503 * Part of the chain
3504 */
Paul Bakker9a736322012-11-14 12:39:52 +00003505 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 +00003506 if( ret != 0 )
3507 return( ret );
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003508 }
Paul Bakker915275b2012-09-28 07:10:55 +00003509 else
3510 {
Paul Bakker9a736322012-11-14 12:39:52 +00003511 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 +00003512 if( ret != 0 )
3513 return( ret );
3514 }
3515
3516 /* child is verified to be a child of the parent, call verify callback */
3517 if( NULL != f_vrfy )
Paul Bakker9a736322012-11-14 12:39:52 +00003518 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003519 return( ret );
Paul Bakker915275b2012-09-28 07:10:55 +00003520
3521 *flags |= parent_flags;
3522
3523 return( 0 );
3524}
3525
Paul Bakker76fd75a2011-01-16 21:12:10 +00003526/*
Paul Bakker5121ce52009-01-03 21:22:43 +00003527 * Verify the certificate validity
3528 */
3529int x509parse_verify( x509_cert *crt,
3530 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00003531 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003532 const char *cn, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003533 int (*f_vrfy)(void *, x509_cert *, int, int *),
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003534 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00003535{
Paul Bakker23986e52011-04-24 08:57:21 +00003536 size_t cn_len;
Paul Bakker915275b2012-09-28 07:10:55 +00003537 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003538 int pathlen = 0;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003539 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00003540 x509_name *name;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003541 x509_sequence *cur = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003542
Paul Bakker40ea7de2009-05-03 10:18:48 +00003543 *flags = 0;
3544
Paul Bakker5121ce52009-01-03 21:22:43 +00003545 if( cn != NULL )
3546 {
3547 name = &crt->subject;
3548 cn_len = strlen( cn );
3549
Paul Bakker4d2c1242012-05-10 14:12:46 +00003550 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
Paul Bakker5121ce52009-01-03 21:22:43 +00003551 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00003552 cur = &crt->subject_alt_names;
3553
3554 while( cur != NULL )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003555 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003556 if( cur->buf.len == cn_len &&
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003557 x509_name_cmp( cn, cur->buf.p, cn_len ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003558 break;
3559
Paul Bakker535e97d2012-08-23 10:49:55 +00003560 if( cur->buf.len > 2 &&
3561 memcmp( cur->buf.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003562 x509_wildcard_verify( cn, &cur->buf ) )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003563 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003564
Paul Bakker4d2c1242012-05-10 14:12:46 +00003565 cur = cur->next;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003566 }
3567
3568 if( cur == NULL )
3569 *flags |= BADCERT_CN_MISMATCH;
3570 }
Paul Bakker4d2c1242012-05-10 14:12:46 +00003571 else
3572 {
3573 while( name != NULL )
3574 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003575 if( name->oid.len == 3 &&
3576 memcmp( name->oid.p, OID_CN, 3 ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003577 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003578 if( name->val.len == cn_len &&
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003579 x509_name_cmp( name->val.p, cn, cn_len ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003580 break;
3581
Paul Bakker535e97d2012-08-23 10:49:55 +00003582 if( name->val.len > 2 &&
3583 memcmp( name->val.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003584 x509_wildcard_verify( cn, &name->val ) )
3585 break;
3586 }
3587
3588 name = name->next;
3589 }
3590
3591 if( name == NULL )
3592 *flags |= BADCERT_CN_MISMATCH;
3593 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003594 }
3595
Paul Bakker5121ce52009-01-03 21:22:43 +00003596 /*
Paul Bakker915275b2012-09-28 07:10:55 +00003597 * Iterate upwards in the given cert chain, to find our crt parent.
3598 * Ignore any upper cert with CA != TRUE.
Paul Bakker5121ce52009-01-03 21:22:43 +00003599 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003600 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003601
Paul Bakker76fd75a2011-01-16 21:12:10 +00003602 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003603 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003604 if( parent->ca_istrue == 0 ||
3605 crt->issuer_raw.len != parent->subject_raw.len ||
3606 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00003607 crt->issuer_raw.len ) != 0 )
3608 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003609 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003610 continue;
3611 }
Paul Bakker915275b2012-09-28 07:10:55 +00003612 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003613 }
3614
Paul Bakker915275b2012-09-28 07:10:55 +00003615 if( parent != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003616 {
Paul Bakker915275b2012-09-28 07:10:55 +00003617 /*
3618 * Part of the chain
3619 */
Paul Bakker9a736322012-11-14 12:39:52 +00003620 ret = x509parse_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003621 if( ret != 0 )
3622 return( ret );
3623 }
3624 else
Paul Bakker74111d32011-01-15 16:57:55 +00003625 {
Paul Bakker9a736322012-11-14 12:39:52 +00003626 ret = x509parse_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003627 if( ret != 0 )
3628 return( ret );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003629 }
Paul Bakker915275b2012-09-28 07:10:55 +00003630
3631 if( *flags != 0 )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003632 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003633
Paul Bakker5121ce52009-01-03 21:22:43 +00003634 return( 0 );
3635}
3636
3637/*
3638 * Unallocate all certificate data
3639 */
3640void x509_free( x509_cert *crt )
3641{
3642 x509_cert *cert_cur = crt;
3643 x509_cert *cert_prv;
3644 x509_name *name_cur;
3645 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00003646 x509_sequence *seq_cur;
3647 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00003648
3649 if( crt == NULL )
3650 return;
3651
3652 do
3653 {
3654 rsa_free( &cert_cur->rsa );
3655
3656 name_cur = cert_cur->issuer.next;
3657 while( name_cur != NULL )
3658 {
3659 name_prv = name_cur;
3660 name_cur = name_cur->next;
3661 memset( name_prv, 0, sizeof( x509_name ) );
3662 free( name_prv );
3663 }
3664
3665 name_cur = cert_cur->subject.next;
3666 while( name_cur != NULL )
3667 {
3668 name_prv = name_cur;
3669 name_cur = name_cur->next;
3670 memset( name_prv, 0, sizeof( x509_name ) );
3671 free( name_prv );
3672 }
3673
Paul Bakker74111d32011-01-15 16:57:55 +00003674 seq_cur = cert_cur->ext_key_usage.next;
3675 while( seq_cur != NULL )
3676 {
3677 seq_prv = seq_cur;
3678 seq_cur = seq_cur->next;
3679 memset( seq_prv, 0, sizeof( x509_sequence ) );
3680 free( seq_prv );
3681 }
3682
Paul Bakker8afa70d2012-02-11 18:42:45 +00003683 seq_cur = cert_cur->subject_alt_names.next;
3684 while( seq_cur != NULL )
3685 {
3686 seq_prv = seq_cur;
3687 seq_cur = seq_cur->next;
3688 memset( seq_prv, 0, sizeof( x509_sequence ) );
3689 free( seq_prv );
3690 }
3691
Paul Bakker5121ce52009-01-03 21:22:43 +00003692 if( cert_cur->raw.p != NULL )
3693 {
3694 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
3695 free( cert_cur->raw.p );
3696 }
3697
3698 cert_cur = cert_cur->next;
3699 }
3700 while( cert_cur != NULL );
3701
3702 cert_cur = crt;
3703 do
3704 {
3705 cert_prv = cert_cur;
3706 cert_cur = cert_cur->next;
3707
3708 memset( cert_prv, 0, sizeof( x509_cert ) );
3709 if( cert_prv != crt )
3710 free( cert_prv );
3711 }
3712 while( cert_cur != NULL );
3713}
3714
Paul Bakkerd98030e2009-05-02 15:13:40 +00003715/*
3716 * Unallocate all CRL data
3717 */
3718void x509_crl_free( x509_crl *crl )
3719{
3720 x509_crl *crl_cur = crl;
3721 x509_crl *crl_prv;
3722 x509_name *name_cur;
3723 x509_name *name_prv;
3724 x509_crl_entry *entry_cur;
3725 x509_crl_entry *entry_prv;
3726
3727 if( crl == NULL )
3728 return;
3729
3730 do
3731 {
3732 name_cur = crl_cur->issuer.next;
3733 while( name_cur != NULL )
3734 {
3735 name_prv = name_cur;
3736 name_cur = name_cur->next;
3737 memset( name_prv, 0, sizeof( x509_name ) );
3738 free( name_prv );
3739 }
3740
3741 entry_cur = crl_cur->entry.next;
3742 while( entry_cur != NULL )
3743 {
3744 entry_prv = entry_cur;
3745 entry_cur = entry_cur->next;
3746 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
3747 free( entry_prv );
3748 }
3749
3750 if( crl_cur->raw.p != NULL )
3751 {
3752 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
3753 free( crl_cur->raw.p );
3754 }
3755
3756 crl_cur = crl_cur->next;
3757 }
3758 while( crl_cur != NULL );
3759
3760 crl_cur = crl;
3761 do
3762 {
3763 crl_prv = crl_cur;
3764 crl_cur = crl_cur->next;
3765
3766 memset( crl_prv, 0, sizeof( x509_crl ) );
3767 if( crl_prv != crl )
3768 free( crl_prv );
3769 }
3770 while( crl_cur != NULL );
3771}
3772
Paul Bakker40e46942009-01-03 21:51:57 +00003773#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00003774
Paul Bakker40e46942009-01-03 21:51:57 +00003775#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00003776
3777/*
3778 * Checkup routine
3779 */
3780int x509_self_test( int verbose )
3781{
Paul Bakker5690efc2011-05-26 13:16:06 +00003782#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00003783 int ret;
3784 int flags;
3785 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00003786 x509_cert cacert;
3787 x509_cert clicert;
3788 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00003789#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003790 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00003791#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003792
3793 if( verbose != 0 )
3794 printf( " X.509 certificate load: " );
3795
3796 memset( &clicert, 0, sizeof( x509_cert ) );
3797
Paul Bakkereae09db2013-06-06 12:35:54 +02003798 ret = x509parse_crt( &clicert, (const unsigned char *) test_cli_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003799 strlen( test_cli_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003800 if( ret != 0 )
3801 {
3802 if( verbose != 0 )
3803 printf( "failed\n" );
3804
3805 return( ret );
3806 }
3807
3808 memset( &cacert, 0, sizeof( x509_cert ) );
3809
Paul Bakkereae09db2013-06-06 12:35:54 +02003810 ret = x509parse_crt( &cacert, (const unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003811 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003812 if( ret != 0 )
3813 {
3814 if( verbose != 0 )
3815 printf( "failed\n" );
3816
3817 return( ret );
3818 }
3819
3820 if( verbose != 0 )
3821 printf( "passed\n X.509 private key load: " );
3822
3823 i = strlen( test_ca_key );
3824 j = strlen( test_ca_pwd );
3825
Paul Bakker66b78b22011-03-25 14:22:50 +00003826 rsa_init( &rsa, RSA_PKCS_V15, 0 );
3827
Paul Bakker5121ce52009-01-03 21:22:43 +00003828 if( ( ret = x509parse_key( &rsa,
Paul Bakkereae09db2013-06-06 12:35:54 +02003829 (const unsigned char *) test_ca_key, i,
3830 (const unsigned char *) test_ca_pwd, j ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003831 {
3832 if( verbose != 0 )
3833 printf( "failed\n" );
3834
3835 return( ret );
3836 }
3837
3838 if( verbose != 0 )
3839 printf( "passed\n X.509 signature verify: ");
3840
Paul Bakker23986e52011-04-24 08:57:21 +00003841 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003842 if( ret != 0 )
3843 {
3844 if( verbose != 0 )
3845 printf( "failed\n" );
3846
3847 return( ret );
3848 }
3849
Paul Bakker5690efc2011-05-26 13:16:06 +00003850#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003851 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003852 printf( "passed\n X.509 DHM parameter load: " );
3853
3854 i = strlen( test_dhm_params );
3855 j = strlen( test_ca_pwd );
3856
Paul Bakkereae09db2013-06-06 12:35:54 +02003857 if( ( ret = x509parse_dhm( &dhm, (const unsigned char *) test_dhm_params, i ) ) != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003858 {
3859 if( verbose != 0 )
3860 printf( "failed\n" );
3861
3862 return( ret );
3863 }
3864
3865 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003866 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00003867#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003868
3869 x509_free( &cacert );
3870 x509_free( &clicert );
3871 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00003872#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003873 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00003874#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003875
3876 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003877#else
3878 ((void) verbose);
3879 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3880#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003881}
3882
3883#endif
3884
3885#endif