blob: f3e783152a33479c60e6a34fa6d7f861658cd76e [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 Bakker91200182010-02-18 21:26:15 +0000373 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
374 &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
397 if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
398 &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 Bakkerd6d41092013-06-13 09:00:25 +02001138int 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,
1474 "-----BEGIN CERTIFICATE-----",
1475 "-----END CERTIFICATE-----",
1476 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,
1585 "-----BEGIN X509 CRL-----",
1586 "-----END X509 CRL-----",
1587 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 Bakkerff60ee62010-03-16 21:09:09 +00001834int 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
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001946cleanup:
Paul Bakker8d914582012-06-04 12:46:42 +00001947 FindClose( hFind );
1948#else
Paul Bakker9ccb2112014-07-07 13:43:31 +02001949#if defined(POLARSSL_HAVE_READDIR_R)
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001950 int t_ret, i;
1951 struct stat sb;
1952 struct dirent entry, *result = NULL;
Paul Bakker8d914582012-06-04 12:46:42 +00001953 char entry_name[255];
1954 DIR *dir = opendir( path );
1955
1956 if( dir == NULL)
1957 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1958
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001959 while( ( t_ret = readdir_r( dir, &entry, &result ) ) == 0 )
Paul Bakker8d914582012-06-04 12:46:42 +00001960 {
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001961 if( result == NULL )
1962 break;
1963
1964 snprintf( entry_name, sizeof(entry_name), "%s/%s", path, entry.d_name );
1965
1966 i = stat( entry_name, &sb );
1967
1968 if( i == -1 )
Paul Bakker88a22642013-09-11 12:14:16 +02001969 {
1970 closedir( dir );
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001971 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker88a22642013-09-11 12:14:16 +02001972 }
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001973
1974 if( !S_ISREG( sb.st_mode ) )
Paul Bakker8d914582012-06-04 12:46:42 +00001975 continue;
1976
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001977 // Ignore parse errors
1978 //
Paul Bakker8d914582012-06-04 12:46:42 +00001979 t_ret = x509parse_crtfile( chain, entry_name );
1980 if( t_ret < 0 )
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001981 ret++;
1982 else
1983 ret += t_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001984 }
1985 closedir( dir );
Paul Bakker9ccb2112014-07-07 13:43:31 +02001986#else /* POLARSSL_HAVE_READDIR_R */
1987 ((void) chain);
1988 ((void) path);
1989 ret = POLARSSL_ERR_X509_FEATURE_UNAVAILABLE;
1990#endif /* POLARSSL_HAVE_READDIR_R */
1991#endif /* _WIN32 */
Paul Bakker8d914582012-06-04 12:46:42 +00001992
1993 return( ret );
1994}
1995
Paul Bakkerd98030e2009-05-02 15:13:40 +00001996/*
1997 * Load one or more CRLs and add them to the chained list
1998 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001999int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002000{
2001 int ret;
2002 size_t n;
2003 unsigned char *buf;
2004
Paul Bakker69e095c2011-12-10 21:55:01 +00002005 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2006 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002007
Paul Bakker27fdf462011-06-09 13:55:13 +00002008 ret = x509parse_crl( chain, buf, n );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002009
2010 memset( buf, 0, n + 1 );
2011 free( buf );
2012
2013 return( ret );
2014}
2015
Paul Bakker5121ce52009-01-03 21:22:43 +00002016/*
Paul Bakker335db3f2011-04-25 15:28:35 +00002017 * Load and parse a private RSA key
2018 */
2019int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
2020{
2021 int ret;
2022 size_t n;
2023 unsigned char *buf;
2024
Paul Bakker69e095c2011-12-10 21:55:01 +00002025 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2026 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002027
2028 if( pwd == NULL )
Paul Bakker27fdf462011-06-09 13:55:13 +00002029 ret = x509parse_key( rsa, buf, n, NULL, 0 );
Paul Bakker335db3f2011-04-25 15:28:35 +00002030 else
Paul Bakker27fdf462011-06-09 13:55:13 +00002031 ret = x509parse_key( rsa, buf, n,
Paul Bakker335db3f2011-04-25 15:28:35 +00002032 (unsigned char *) pwd, strlen( pwd ) );
2033
2034 memset( buf, 0, n + 1 );
2035 free( buf );
2036
2037 return( ret );
2038}
2039
2040/*
2041 * Load and parse a public RSA key
2042 */
2043int x509parse_public_keyfile( rsa_context *rsa, const char *path )
2044{
2045 int ret;
2046 size_t n;
2047 unsigned char *buf;
2048
Paul Bakker69e095c2011-12-10 21:55:01 +00002049 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2050 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002051
Paul Bakker27fdf462011-06-09 13:55:13 +00002052 ret = x509parse_public_key( rsa, buf, n );
Paul Bakker335db3f2011-04-25 15:28:35 +00002053
2054 memset( buf, 0, n + 1 );
2055 free( buf );
2056
2057 return( ret );
2058}
2059#endif /* POLARSSL_FS_IO */
2060
2061/*
Paul Bakker65a19092013-06-06 21:14:58 +02002062 * Parse a PKCS#1 encoded private RSA key
Paul Bakker5121ce52009-01-03 21:22:43 +00002063 */
Paul Bakker65a19092013-06-06 21:14:58 +02002064static int x509parse_key_pkcs1_der( rsa_context *rsa,
2065 const unsigned char *key,
2066 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +00002067{
Paul Bakker23986e52011-04-24 08:57:21 +00002068 int ret;
2069 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00002070 unsigned char *p, *end;
Paul Bakkered56b222011-07-13 11:26:43 +00002071
Paul Bakker96743fc2011-02-12 14:30:57 +00002072 p = (unsigned char *) key;
Paul Bakker96743fc2011-02-12 14:30:57 +00002073 end = p + keylen;
2074
Paul Bakker5121ce52009-01-03 21:22:43 +00002075 /*
Paul Bakker65a19092013-06-06 21:14:58 +02002076 * This function parses the RSAPrivateKey (PKCS#1)
Paul Bakkered56b222011-07-13 11:26:43 +00002077 *
Paul Bakker5121ce52009-01-03 21:22:43 +00002078 * RSAPrivateKey ::= SEQUENCE {
2079 * version Version,
2080 * modulus INTEGER, -- n
2081 * publicExponent INTEGER, -- e
2082 * privateExponent INTEGER, -- d
2083 * prime1 INTEGER, -- p
2084 * prime2 INTEGER, -- q
2085 * exponent1 INTEGER, -- d mod (p-1)
2086 * exponent2 INTEGER, -- d mod (q-1)
2087 * coefficient INTEGER, -- (inverse of q) mod p
2088 * otherPrimeInfos OtherPrimeInfos OPTIONAL
2089 * }
2090 */
2091 if( ( ret = asn1_get_tag( &p, end, &len,
2092 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2093 {
Paul Bakker9d781402011-05-09 16:17:09 +00002094 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002095 }
2096
2097 end = p + len;
2098
2099 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2100 {
Paul Bakker9d781402011-05-09 16:17:09 +00002101 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002102 }
2103
2104 if( rsa->ver != 0 )
2105 {
Paul Bakker9d781402011-05-09 16:17:09 +00002106 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002107 }
2108
2109 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
2110 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
2111 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
2112 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
2113 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
2114 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
2115 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
2116 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
2117 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002118 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002119 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002120 }
2121
2122 rsa->len = mpi_size( &rsa->N );
2123
2124 if( p != end )
2125 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002126 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002127 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00002128 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002129 }
2130
2131 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2132 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002133 rsa_free( rsa );
2134 return( ret );
2135 }
2136
Paul Bakker65a19092013-06-06 21:14:58 +02002137 return( 0 );
2138}
2139
2140/*
2141 * Parse an unencrypted PKCS#8 encoded private RSA key
2142 */
2143static int x509parse_key_pkcs8_unencrypted_der(
2144 rsa_context *rsa,
2145 const unsigned char *key,
2146 size_t keylen )
2147{
2148 int ret;
2149 size_t len;
2150 unsigned char *p, *end;
2151 x509_buf pk_alg_oid;
2152
2153 p = (unsigned char *) key;
2154 end = p + keylen;
2155
2156 /*
2157 * This function parses the PrivatKeyInfo object (PKCS#8)
2158 *
2159 * PrivateKeyInfo ::= SEQUENCE {
2160 * version Version,
2161 * algorithm AlgorithmIdentifier,
2162 * PrivateKey BIT STRING
2163 * }
2164 *
2165 * AlgorithmIdentifier ::= SEQUENCE {
2166 * algorithm OBJECT IDENTIFIER,
2167 * parameters ANY DEFINED BY algorithm OPTIONAL
2168 * }
2169 *
2170 * The PrivateKey BIT STRING is a PKCS#1 RSAPrivateKey
2171 */
2172 if( ( ret = asn1_get_tag( &p, end, &len,
2173 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2174 {
2175 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2176 }
2177
2178 end = p + len;
2179
2180 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2181 {
2182 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2183 }
2184
2185 if( rsa->ver != 0 )
2186 {
2187 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2188 }
2189
2190 if( ( ret = x509_get_alg( &p, end, &pk_alg_oid ) ) != 0 )
2191 {
2192 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2193 }
2194
2195 /*
2196 * only RSA keys handled at this time
2197 */
2198 if( pk_alg_oid.len != 9 ||
2199 memcmp( pk_alg_oid.p, OID_PKCS1_RSA, 9 ) != 0 )
2200 {
2201 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
2202 }
2203
2204 /*
2205 * Get the OCTET STRING and parse the PKCS#1 format inside
2206 */
2207 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2208 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2209
2210 if( ( end - p ) < 1 )
2211 {
2212 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
2213 POLARSSL_ERR_ASN1_OUT_OF_DATA );
2214 }
2215
2216 end = p + len;
2217
2218 if( ( ret = x509parse_key_pkcs1_der( rsa, p, end - p ) ) != 0 )
2219 return( ret );
2220
2221 return( 0 );
2222}
2223
2224/*
Paul Bakkerda7fdbd2013-06-19 11:15:43 +02002225 * Parse an encrypted PKCS#8 encoded private RSA key
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002226 */
2227static int x509parse_key_pkcs8_encrypted_der(
2228 rsa_context *rsa,
2229 const unsigned char *key,
2230 size_t keylen,
2231 const unsigned char *pwd,
2232 size_t pwdlen )
2233{
2234 int ret;
2235 size_t len;
2236 unsigned char *p, *end, *end2;
2237 x509_buf pbe_alg_oid, pbe_params;
2238 unsigned char buf[2048];
2239
2240 memset(buf, 0, 2048);
2241
2242 p = (unsigned char *) key;
2243 end = p + keylen;
2244
Paul Bakker1fd43212013-06-17 15:14:42 +02002245 if( pwdlen == 0 )
2246 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
2247
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002248 /*
2249 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
2250 *
2251 * EncryptedPrivateKeyInfo ::= SEQUENCE {
2252 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
2253 * encryptedData EncryptedData
2254 * }
2255 *
2256 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
2257 *
2258 * EncryptedData ::= OCTET STRING
2259 *
2260 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
2261 */
2262 if( ( ret = asn1_get_tag( &p, end, &len,
2263 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2264 {
2265 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2266 }
2267
2268 end = p + len;
2269
2270 if( ( ret = asn1_get_tag( &p, end, &len,
2271 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2272 {
2273 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2274 }
2275
2276 end2 = p + len;
2277
2278 if( ( ret = asn1_get_tag( &p, end, &pbe_alg_oid.len, ASN1_OID ) ) != 0 )
2279 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2280
2281 pbe_alg_oid.p = p;
2282 p += pbe_alg_oid.len;
2283
2284 /*
2285 * Store the algorithm parameters
2286 */
2287 pbe_params.p = p;
2288 pbe_params.len = end2 - p;
2289 p += pbe_params.len;
2290
2291 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2292 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2293
2294 // buf has been sized to 2048 bytes
2295 if( len > 2048 )
2296 return( POLARSSL_ERR_X509_INVALID_INPUT );
2297
2298 /*
2299 * Decrypt EncryptedData with appropriate PDE
2300 */
Paul Bakker14a222c2013-06-18 16:35:48 +02002301#if defined(POLARSSL_PKCS12_C)
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002302 if( OID_CMP( OID_PKCS12_PBE_SHA1_DES3_EDE_CBC, &pbe_alg_oid ) )
2303 {
Paul Bakker14a222c2013-06-18 16:35:48 +02002304 if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
2305 POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1,
2306 pwd, pwdlen, p, len, buf ) ) != 0 )
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002307 {
Paul Bakker14a222c2013-06-18 16:35:48 +02002308 if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH )
2309 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2310
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002311 return( ret );
2312 }
2313 }
2314 else if( OID_CMP( OID_PKCS12_PBE_SHA1_DES2_EDE_CBC, &pbe_alg_oid ) )
2315 {
Paul Bakker14a222c2013-06-18 16:35:48 +02002316 if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
2317 POLARSSL_CIPHER_DES_EDE_CBC, POLARSSL_MD_SHA1,
2318 pwd, pwdlen, p, len, buf ) ) != 0 )
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002319 {
Paul Bakker14a222c2013-06-18 16:35:48 +02002320 if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH )
2321 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2322
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002323 return( ret );
2324 }
2325 }
2326 else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) )
2327 {
2328 if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params,
2329 PKCS12_PBE_DECRYPT,
2330 pwd, pwdlen,
2331 p, len, buf ) ) != 0 )
2332 {
2333 return( ret );
2334 }
Paul Bakker14a222c2013-06-18 16:35:48 +02002335
2336 // Best guess for password mismatch when using RC4. If first tag is
2337 // not ASN1_CONSTRUCTED | ASN1_SEQUENCE
2338 //
2339 if( *buf != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
2340 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002341 }
Paul Bakker14a222c2013-06-18 16:35:48 +02002342 else
2343#endif /* POLARSSL_PKCS12_C */
Paul Bakker1fd43212013-06-17 15:14:42 +02002344#if defined(POLARSSL_PKCS5_C)
Paul Bakker14a222c2013-06-18 16:35:48 +02002345 if( OID_CMP( OID_PKCS5_PBES2, &pbe_alg_oid ) )
Paul Bakker1fd43212013-06-17 15:14:42 +02002346 {
2347 if( ( ret = pkcs5_pbes2( &pbe_params, PKCS5_DECRYPT, pwd, pwdlen,
2348 p, len, buf ) ) != 0 )
2349 {
2350 if( ret == POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH )
2351 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2352
2353 return( ret );
2354 }
2355 }
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002356 else
Paul Bakker14a222c2013-06-18 16:35:48 +02002357#endif /* POLARSSL_PKCS5_C */
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002358 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
2359
2360 return x509parse_key_pkcs8_unencrypted_der( rsa, buf, len );
2361}
2362
2363/*
Paul Bakker65a19092013-06-06 21:14:58 +02002364 * Parse a private RSA key
2365 */
2366int x509parse_key( rsa_context *rsa, const unsigned char *key, size_t keylen,
2367 const unsigned char *pwd, size_t pwdlen )
2368{
2369 int ret;
2370
Paul Bakker96743fc2011-02-12 14:30:57 +00002371#if defined(POLARSSL_PEM_C)
Paul Bakker65a19092013-06-06 21:14:58 +02002372 size_t len;
2373 pem_context pem;
2374
2375 pem_init( &pem );
2376 ret = pem_read_buffer( &pem,
2377 "-----BEGIN RSA PRIVATE KEY-----",
2378 "-----END RSA PRIVATE KEY-----",
2379 key, pwd, pwdlen, &len );
2380 if( ret == 0 )
2381 {
2382 if( ( ret = x509parse_key_pkcs1_der( rsa, pem.buf, pem.buflen ) ) != 0 )
2383 {
2384 rsa_free( rsa );
2385 }
2386
2387 pem_free( &pem );
2388 return( ret );
2389 }
Paul Bakkerb495d3a2013-06-17 15:58:04 +02002390 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
2391 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2392 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
2393 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
Paul Bakker65a19092013-06-06 21:14:58 +02002394 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker65a19092013-06-06 21:14:58 +02002395 return( ret );
Paul Bakker65a19092013-06-06 21:14:58 +02002396
2397 ret = pem_read_buffer( &pem,
2398 "-----BEGIN PRIVATE KEY-----",
2399 "-----END PRIVATE KEY-----",
2400 key, NULL, 0, &len );
2401 if( ret == 0 )
2402 {
2403 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa,
2404 pem.buf, pem.buflen ) ) != 0 )
2405 {
2406 rsa_free( rsa );
2407 }
2408
2409 pem_free( &pem );
2410 return( ret );
2411 }
2412 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker65a19092013-06-06 21:14:58 +02002413 return( ret );
Paul Bakker65a19092013-06-06 21:14:58 +02002414
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002415 ret = pem_read_buffer( &pem,
2416 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
2417 "-----END ENCRYPTED PRIVATE KEY-----",
2418 key, NULL, 0, &len );
2419 if( ret == 0 )
2420 {
2421 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa,
2422 pem.buf, pem.buflen,
2423 pwd, pwdlen ) ) != 0 )
2424 {
2425 rsa_free( rsa );
2426 }
2427
2428 pem_free( &pem );
2429 return( ret );
2430 }
2431 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002432 return( ret );
Paul Bakker65a19092013-06-06 21:14:58 +02002433#else
2434 ((void) pwd);
2435 ((void) pwdlen);
2436#endif /* POLARSSL_PEM_C */
2437
2438 // At this point we only know it's not a PEM formatted key. Could be any
2439 // of the known DER encoded private key formats
2440 //
2441 // We try the different DER format parsers to see if one passes without
2442 // error
2443 //
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002444 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa, key, keylen,
2445 pwd, pwdlen ) ) == 0 )
Paul Bakker65a19092013-06-06 21:14:58 +02002446 {
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002447 return( 0 );
Paul Bakker65a19092013-06-06 21:14:58 +02002448 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002449
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002450 rsa_free( rsa );
Paul Bakker1fd43212013-06-17 15:14:42 +02002451
2452 if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH )
2453 {
2454 return( ret );
2455 }
2456
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002457 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa, key, keylen ) ) == 0 )
2458 return( 0 );
2459
2460 rsa_free( rsa );
Paul Bakker1fd43212013-06-17 15:14:42 +02002461
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002462 if( ( ret = x509parse_key_pkcs1_der( rsa, key, keylen ) ) == 0 )
2463 return( 0 );
2464
2465 rsa_free( rsa );
Paul Bakker1fd43212013-06-17 15:14:42 +02002466
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002467 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00002468}
2469
2470/*
Paul Bakker53019ae2011-03-25 13:58:48 +00002471 * Parse a public RSA key
2472 */
Paul Bakker23986e52011-04-24 08:57:21 +00002473int x509parse_public_key( rsa_context *rsa, const unsigned char *key, size_t keylen )
Paul Bakker53019ae2011-03-25 13:58:48 +00002474{
Paul Bakker23986e52011-04-24 08:57:21 +00002475 int ret;
2476 size_t len;
Paul Bakker53019ae2011-03-25 13:58:48 +00002477 unsigned char *p, *end;
2478 x509_buf alg_oid;
2479#if defined(POLARSSL_PEM_C)
2480 pem_context pem;
2481
2482 pem_init( &pem );
2483 ret = pem_read_buffer( &pem,
2484 "-----BEGIN PUBLIC KEY-----",
2485 "-----END PUBLIC KEY-----",
2486 key, NULL, 0, &len );
2487
2488 if( ret == 0 )
2489 {
2490 /*
2491 * Was PEM encoded
2492 */
2493 keylen = pem.buflen;
2494 }
Paul Bakker9255e832013-06-06 14:58:28 +02002495 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker53019ae2011-03-25 13:58:48 +00002496 {
2497 pem_free( &pem );
2498 return( ret );
2499 }
2500
2501 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2502#else
2503 p = (unsigned char *) key;
2504#endif
2505 end = p + keylen;
2506
2507 /*
2508 * PublicKeyInfo ::= SEQUENCE {
2509 * algorithm AlgorithmIdentifier,
2510 * PublicKey BIT STRING
2511 * }
2512 *
2513 * AlgorithmIdentifier ::= SEQUENCE {
2514 * algorithm OBJECT IDENTIFIER,
2515 * parameters ANY DEFINED BY algorithm OPTIONAL
2516 * }
2517 *
2518 * RSAPublicKey ::= SEQUENCE {
2519 * modulus INTEGER, -- n
2520 * publicExponent INTEGER -- e
2521 * }
2522 */
2523
2524 if( ( ret = asn1_get_tag( &p, end, &len,
2525 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2526 {
2527#if defined(POLARSSL_PEM_C)
2528 pem_free( &pem );
2529#endif
2530 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002531 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002532 }
2533
2534 if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
2535 {
2536#if defined(POLARSSL_PEM_C)
2537 pem_free( &pem );
2538#endif
2539 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002540 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002541 }
2542
2543 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
2544 {
2545#if defined(POLARSSL_PEM_C)
2546 pem_free( &pem );
2547#endif
2548 rsa_free( rsa );
2549 return( ret );
2550 }
2551
2552 rsa->len = mpi_size( &rsa->N );
2553
2554#if defined(POLARSSL_PEM_C)
2555 pem_free( &pem );
2556#endif
2557
2558 return( 0 );
2559}
2560
Paul Bakkereaa89f82011-04-04 21:36:15 +00002561#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00002562/*
Paul Bakker1b57b062011-01-06 15:48:19 +00002563 * Parse DHM parameters
2564 */
Paul Bakker23986e52011-04-24 08:57:21 +00002565int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
Paul Bakker1b57b062011-01-06 15:48:19 +00002566{
Paul Bakker23986e52011-04-24 08:57:21 +00002567 int ret;
2568 size_t len;
Paul Bakker1b57b062011-01-06 15:48:19 +00002569 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00002570#if defined(POLARSSL_PEM_C)
2571 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00002572
Paul Bakker96743fc2011-02-12 14:30:57 +00002573 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00002574
Paul Bakker96743fc2011-02-12 14:30:57 +00002575 ret = pem_read_buffer( &pem,
2576 "-----BEGIN DH PARAMETERS-----",
2577 "-----END DH PARAMETERS-----",
2578 dhmin, NULL, 0, &dhminlen );
2579
2580 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00002581 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002582 /*
2583 * Was PEM encoded
2584 */
2585 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00002586 }
Paul Bakker9255e832013-06-06 14:58:28 +02002587 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00002588 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002589 pem_free( &pem );
2590 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002591 }
2592
Paul Bakker96743fc2011-02-12 14:30:57 +00002593 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
2594#else
2595 p = (unsigned char *) dhmin;
2596#endif
2597 end = p + dhminlen;
2598
Paul Bakker1b57b062011-01-06 15:48:19 +00002599 memset( dhm, 0, sizeof( dhm_context ) );
2600
Paul Bakker1b57b062011-01-06 15:48:19 +00002601 /*
2602 * DHParams ::= SEQUENCE {
2603 * prime INTEGER, -- P
2604 * generator INTEGER, -- g
2605 * }
2606 */
2607 if( ( ret = asn1_get_tag( &p, end, &len,
2608 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2609 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002610#if defined(POLARSSL_PEM_C)
2611 pem_free( &pem );
2612#endif
Paul Bakker9d781402011-05-09 16:17:09 +00002613 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002614 }
2615
2616 end = p + len;
2617
2618 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
2619 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
2620 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002621#if defined(POLARSSL_PEM_C)
2622 pem_free( &pem );
2623#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002624 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002625 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002626 }
2627
2628 if( p != end )
2629 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002630#if defined(POLARSSL_PEM_C)
2631 pem_free( &pem );
2632#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002633 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002634 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker1b57b062011-01-06 15:48:19 +00002635 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
2636 }
2637
Paul Bakker96743fc2011-02-12 14:30:57 +00002638#if defined(POLARSSL_PEM_C)
2639 pem_free( &pem );
2640#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002641
2642 return( 0 );
2643}
2644
Paul Bakker335db3f2011-04-25 15:28:35 +00002645#if defined(POLARSSL_FS_IO)
Paul Bakker1b57b062011-01-06 15:48:19 +00002646/*
2647 * Load and parse a private RSA key
2648 */
2649int x509parse_dhmfile( dhm_context *dhm, const char *path )
2650{
2651 int ret;
2652 size_t n;
2653 unsigned char *buf;
2654
Paul Bakker69e095c2011-12-10 21:55:01 +00002655 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
2656 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002657
Paul Bakker27fdf462011-06-09 13:55:13 +00002658 ret = x509parse_dhm( dhm, buf, n );
Paul Bakker1b57b062011-01-06 15:48:19 +00002659
2660 memset( buf, 0, n + 1 );
2661 free( buf );
2662
2663 return( ret );
2664}
Paul Bakker335db3f2011-04-25 15:28:35 +00002665#endif /* POLARSSL_FS_IO */
Paul Bakkereaa89f82011-04-04 21:36:15 +00002666#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00002667
Paul Bakker5121ce52009-01-03 21:22:43 +00002668#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002669#include <stdarg.h>
2670
2671#if !defined vsnprintf
2672#define vsnprintf _vsnprintf
2673#endif // vsnprintf
2674
2675/*
2676 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2677 * Result value is not size of buffer needed, but -1 if no fit is possible.
2678 *
2679 * This fuction tries to 'fix' this by at least suggesting enlarging the
2680 * size by 20.
2681 */
2682int compat_snprintf(char *str, size_t size, const char *format, ...)
2683{
2684 va_list ap;
2685 int res = -1;
2686
2687 va_start( ap, format );
2688
2689 res = vsnprintf( str, size, format, ap );
2690
2691 va_end( ap );
2692
2693 // No quick fix possible
2694 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00002695 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002696
2697 return res;
2698}
2699
2700#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002701#endif
2702
Paul Bakkerd98030e2009-05-02 15:13:40 +00002703#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2704
2705#define SAFE_SNPRINTF() \
2706{ \
2707 if( ret == -1 ) \
2708 return( -1 ); \
2709 \
Paul Bakker23986e52011-04-24 08:57:21 +00002710 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002711 p[n - 1] = '\0'; \
2712 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2713 } \
2714 \
Paul Bakker23986e52011-04-24 08:57:21 +00002715 n -= (unsigned int) ret; \
2716 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002717}
2718
Paul Bakker5121ce52009-01-03 21:22:43 +00002719/*
2720 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002721 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002722 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002723int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002724{
Paul Bakker23986e52011-04-24 08:57:21 +00002725 int ret;
2726 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002727 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002728 const x509_name *name;
Paul Bakker5121ce52009-01-03 21:22:43 +00002729 char s[128], *p;
2730
2731 memset( s, 0, sizeof( s ) );
2732
2733 name = dn;
2734 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002735 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002736
2737 while( name != NULL )
2738 {
Paul Bakkercefb3962012-06-27 11:51:09 +00002739 if( !name->oid.p )
2740 {
2741 name = name->next;
2742 continue;
2743 }
2744
Paul Bakker74111d32011-01-15 16:57:55 +00002745 if( name != dn )
2746 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002747 ret = snprintf( p, n, ", " );
2748 SAFE_SNPRINTF();
2749 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002750
Paul Bakker535e97d2012-08-23 10:49:55 +00002751 if( name->oid.len == 3 &&
2752 memcmp( name->oid.p, OID_X520, 2 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002753 {
2754 switch( name->oid.p[2] )
2755 {
2756 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002757 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002758
2759 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002760 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002761
2762 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002763 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002764
2765 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002766 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002767
2768 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002769 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002770
2771 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002772 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002773
2774 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002775 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002776 name->oid.p[2] );
2777 break;
2778 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002779 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002780 }
Paul Bakker535e97d2012-08-23 10:49:55 +00002781 else if( name->oid.len == 9 &&
2782 memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002783 {
2784 switch( name->oid.p[8] )
2785 {
2786 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002787 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002788
2789 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002790 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002791 name->oid.p[8] );
2792 break;
2793 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002794 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002795 }
2796 else
Paul Bakker74111d32011-01-15 16:57:55 +00002797 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002798 ret = snprintf( p, n, "\?\?=" );
Paul Bakker74111d32011-01-15 16:57:55 +00002799 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002800 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002801
2802 for( i = 0; i < name->val.len; i++ )
2803 {
Paul Bakker27fdf462011-06-09 13:55:13 +00002804 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002805 break;
2806
2807 c = name->val.p[i];
2808 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2809 s[i] = '?';
2810 else s[i] = c;
2811 }
2812 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002813 ret = snprintf( p, n, "%s", s );
2814 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002815 name = name->next;
2816 }
2817
Paul Bakker23986e52011-04-24 08:57:21 +00002818 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002819}
2820
2821/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002822 * Store the serial in printable form into buf; no more
2823 * than size characters will be written
2824 */
2825int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2826{
Paul Bakker23986e52011-04-24 08:57:21 +00002827 int ret;
2828 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00002829 char *p;
2830
2831 p = buf;
2832 n = size;
2833
2834 nr = ( serial->len <= 32 )
Paul Bakker03c7c252011-11-25 12:37:37 +00002835 ? serial->len : 28;
Paul Bakkerdd476992011-01-16 21:34:59 +00002836
2837 for( i = 0; i < nr; i++ )
2838 {
Paul Bakker93048802011-12-05 14:38:06 +00002839 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002840 continue;
2841
Paul Bakkerdd476992011-01-16 21:34:59 +00002842 ret = snprintf( p, n, "%02X%s",
2843 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2844 SAFE_SNPRINTF();
2845 }
2846
Paul Bakker03c7c252011-11-25 12:37:37 +00002847 if( nr != serial->len )
2848 {
2849 ret = snprintf( p, n, "...." );
2850 SAFE_SNPRINTF();
2851 }
2852
Paul Bakker23986e52011-04-24 08:57:21 +00002853 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00002854}
2855
2856/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002857 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002858 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002859int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2860 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002861{
Paul Bakker23986e52011-04-24 08:57:21 +00002862 int ret;
2863 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002864 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00002865
2866 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002867 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002868
Paul Bakkerd98030e2009-05-02 15:13:40 +00002869 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002870 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002871 SAFE_SNPRINTF();
2872 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002873 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002874 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002875
Paul Bakkerdd476992011-01-16 21:34:59 +00002876 ret = x509parse_serial_gets( p, n, &crt->serial);
2877 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002878
Paul Bakkerd98030e2009-05-02 15:13:40 +00002879 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2880 SAFE_SNPRINTF();
2881 ret = x509parse_dn_gets( p, n, &crt->issuer );
2882 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002883
Paul Bakkerd98030e2009-05-02 15:13:40 +00002884 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2885 SAFE_SNPRINTF();
2886 ret = x509parse_dn_gets( p, n, &crt->subject );
2887 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002888
Paul Bakkerd98030e2009-05-02 15:13:40 +00002889 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002890 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2891 crt->valid_from.year, crt->valid_from.mon,
2892 crt->valid_from.day, crt->valid_from.hour,
2893 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002894 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002895
Paul Bakkerd98030e2009-05-02 15:13:40 +00002896 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002897 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2898 crt->valid_to.year, crt->valid_to.mon,
2899 crt->valid_to.day, crt->valid_to.hour,
2900 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002901 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002902
Paul Bakkerd98030e2009-05-02 15:13:40 +00002903 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2904 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002905
Paul Bakker27d66162010-03-17 06:56:01 +00002906 switch( crt->sig_alg )
Paul Bakker5121ce52009-01-03 21:22:43 +00002907 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002908 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2909 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2910 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2911 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2912 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2913 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2914 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2915 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2916 default: ret = snprintf( p, n, "???" ); break;
2917 }
2918 SAFE_SNPRINTF();
2919
2920 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
Paul Bakker5c2364c2012-10-01 14:41:15 +00002921 (int) crt->rsa.N.n * (int) sizeof( t_uint ) * 8 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002922 SAFE_SNPRINTF();
2923
Paul Bakker23986e52011-04-24 08:57:21 +00002924 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002925}
2926
Paul Bakker74111d32011-01-15 16:57:55 +00002927/*
2928 * Return an informational string describing the given OID
2929 */
2930const char *x509_oid_get_description( x509_buf *oid )
2931{
2932 if ( oid == NULL )
2933 return ( NULL );
2934
2935 else if( OID_CMP( OID_SERVER_AUTH, oid ) )
2936 return( STRING_SERVER_AUTH );
2937
2938 else if( OID_CMP( OID_CLIENT_AUTH, oid ) )
2939 return( STRING_CLIENT_AUTH );
2940
2941 else if( OID_CMP( OID_CODE_SIGNING, oid ) )
2942 return( STRING_CODE_SIGNING );
2943
2944 else if( OID_CMP( OID_EMAIL_PROTECTION, oid ) )
2945 return( STRING_EMAIL_PROTECTION );
2946
2947 else if( OID_CMP( OID_TIME_STAMPING, oid ) )
2948 return( STRING_TIME_STAMPING );
2949
2950 else if( OID_CMP( OID_OCSP_SIGNING, oid ) )
2951 return( STRING_OCSP_SIGNING );
2952
2953 return( NULL );
2954}
2955
2956/* Return the x.y.z.... style numeric string for the given OID */
2957int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2958{
Paul Bakker23986e52011-04-24 08:57:21 +00002959 int ret;
2960 size_t i, n;
Paul Bakker74111d32011-01-15 16:57:55 +00002961 unsigned int value;
2962 char *p;
2963
2964 p = buf;
2965 n = size;
2966
2967 /* First byte contains first two dots */
2968 if( oid->len > 0 )
2969 {
2970 ret = snprintf( p, n, "%d.%d", oid->p[0]/40, oid->p[0]%40 );
2971 SAFE_SNPRINTF();
2972 }
2973
2974 /* TODO: value can overflow in value. */
2975 value = 0;
Paul Bakker23986e52011-04-24 08:57:21 +00002976 for( i = 1; i < oid->len; i++ )
Paul Bakker74111d32011-01-15 16:57:55 +00002977 {
2978 value <<= 7;
2979 value += oid->p[i] & 0x7F;
2980
2981 if( !( oid->p[i] & 0x80 ) )
2982 {
2983 /* Last byte */
2984 ret = snprintf( p, n, ".%d", value );
2985 SAFE_SNPRINTF();
2986 value = 0;
2987 }
2988 }
2989
Paul Bakker23986e52011-04-24 08:57:21 +00002990 return( (int) ( size - n ) );
Paul Bakker74111d32011-01-15 16:57:55 +00002991}
2992
Paul Bakkerd98030e2009-05-02 15:13:40 +00002993/*
2994 * Return an informational string about the CRL.
2995 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002996int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2997 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002998{
Paul Bakker23986e52011-04-24 08:57:21 +00002999 int ret;
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003000 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003001 char *p;
Paul Bakkerff60ee62010-03-16 21:09:09 +00003002 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00003003
3004 p = buf;
3005 n = size;
3006
3007 ret = snprintf( p, n, "%sCRL version : %d",
3008 prefix, crl->version );
3009 SAFE_SNPRINTF();
3010
3011 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
3012 SAFE_SNPRINTF();
3013 ret = x509parse_dn_gets( p, n, &crl->issuer );
3014 SAFE_SNPRINTF();
3015
3016 ret = snprintf( p, n, "\n%sthis update : " \
3017 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3018 crl->this_update.year, crl->this_update.mon,
3019 crl->this_update.day, crl->this_update.hour,
3020 crl->this_update.min, crl->this_update.sec );
3021 SAFE_SNPRINTF();
3022
3023 ret = snprintf( p, n, "\n%snext update : " \
3024 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
3025 crl->next_update.year, crl->next_update.mon,
3026 crl->next_update.day, crl->next_update.hour,
3027 crl->next_update.min, crl->next_update.sec );
3028 SAFE_SNPRINTF();
3029
3030 entry = &crl->entry;
3031
3032 ret = snprintf( p, n, "\n%sRevoked certificates:",
3033 prefix );
3034 SAFE_SNPRINTF();
3035
Paul Bakker9be19372009-07-27 20:21:53 +00003036 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003037 {
3038 ret = snprintf( p, n, "\n%sserial number: ",
3039 prefix );
3040 SAFE_SNPRINTF();
3041
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003042 ret = x509parse_serial_gets( p, n, &entry->serial);
3043 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003044
Paul Bakkerd98030e2009-05-02 15:13:40 +00003045 ret = snprintf( p, n, " revocation date: " \
3046 "%04d-%02d-%02d %02d:%02d:%02d",
3047 entry->revocation_date.year, entry->revocation_date.mon,
3048 entry->revocation_date.day, entry->revocation_date.hour,
3049 entry->revocation_date.min, entry->revocation_date.sec );
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003050 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003051
3052 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003053 }
3054
Paul Bakkerd98030e2009-05-02 15:13:40 +00003055 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
3056 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003057
Paul Bakker27d66162010-03-17 06:56:01 +00003058 switch( crl->sig_alg )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003059 {
3060 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
3061 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
3062 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
3063 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
3064 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
3065 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
3066 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
3067 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
3068 default: ret = snprintf( p, n, "???" ); break;
3069 }
3070 SAFE_SNPRINTF();
3071
Paul Bakker1e27bb22009-07-19 20:25:25 +00003072 ret = snprintf( p, n, "\n" );
3073 SAFE_SNPRINTF();
3074
Paul Bakker23986e52011-04-24 08:57:21 +00003075 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003076}
3077
3078/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00003079 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00003080 */
Paul Bakker0d844dd2014-07-07 17:44:14 +02003081static void x509_get_current_time( x509_time *now )
Paul Bakker5121ce52009-01-03 21:22:43 +00003082{
Paul Bakkercce9d772011-11-18 14:26:47 +00003083#if defined(_WIN32)
3084 SYSTEMTIME st;
3085
Paul Bakkerf48de952014-07-08 14:39:41 +02003086 GetSystemTime(&st);
Paul Bakkercce9d772011-11-18 14:26:47 +00003087
Paul Bakker0d844dd2014-07-07 17:44:14 +02003088 now->year = st.wYear;
3089 now->mon = st.wMonth;
3090 now->day = st.wDay;
3091 now->hour = st.wHour;
3092 now->min = st.wMinute;
3093 now->sec = st.wSecond;
Paul Bakkercce9d772011-11-18 14:26:47 +00003094#else
Paul Bakker358a8412014-07-08 12:14:37 +02003095 struct tm lt;
Paul Bakker5121ce52009-01-03 21:22:43 +00003096 time_t tt;
3097
3098 tt = time( NULL );
Paul Bakkerf48de952014-07-08 14:39:41 +02003099 gmtime_r( &tt, &lt );
Paul Bakker5121ce52009-01-03 21:22:43 +00003100
Paul Bakker358a8412014-07-08 12:14:37 +02003101 now->year = lt.tm_year + 1900;
3102 now->mon = lt.tm_mon + 1;
3103 now->day = lt.tm_mday;
3104 now->hour = lt.tm_hour;
3105 now->min = lt.tm_min;
3106 now->sec = lt.tm_sec;
Paul Bakkercce9d772011-11-18 14:26:47 +00003107#endif
Paul Bakker0d844dd2014-07-07 17:44:14 +02003108}
Paul Bakkercce9d772011-11-18 14:26:47 +00003109
Paul Bakker0d844dd2014-07-07 17:44:14 +02003110/*
3111 * Return 0 if before <= after, 1 otherwise
3112 */
3113static int x509_check_time( const x509_time *before, const x509_time *after )
3114{
3115 if( before->year > after->year )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003116 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003117
Paul Bakker0d844dd2014-07-07 17:44:14 +02003118 if( before->year == after->year &&
3119 before->mon > after->mon )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003120 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003121
Paul Bakker0d844dd2014-07-07 17:44:14 +02003122 if( before->year == after->year &&
3123 before->mon == after->mon &&
3124 before->day > after->day )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003125 return( 1 );
3126
Paul Bakker0d844dd2014-07-07 17:44:14 +02003127 if( before->year == after->year &&
3128 before->mon == after->mon &&
3129 before->day == after->day &&
3130 before->hour > after->hour )
Paul Bakkerb6194992011-01-16 21:40:22 +00003131 return( 1 );
3132
Paul Bakker0d844dd2014-07-07 17:44:14 +02003133 if( before->year == after->year &&
3134 before->mon == after->mon &&
3135 before->day == after->day &&
3136 before->hour == after->hour &&
3137 before->min > after->min )
Paul Bakkerb6194992011-01-16 21:40:22 +00003138 return( 1 );
3139
Paul Bakker0d844dd2014-07-07 17:44:14 +02003140 if( before->year == after->year &&
3141 before->mon == after->mon &&
3142 before->day == after->day &&
3143 before->hour == after->hour &&
3144 before->min == after->min &&
3145 before->sec > after->sec )
Paul Bakkerb6194992011-01-16 21:40:22 +00003146 return( 1 );
3147
Paul Bakker40ea7de2009-05-03 10:18:48 +00003148 return( 0 );
3149}
3150
Paul Bakker0d844dd2014-07-07 17:44:14 +02003151int x509parse_time_expired( const x509_time *to )
3152{
3153 x509_time now;
3154
3155 x509_get_current_time( &now );
3156
3157 return( x509_check_time( &now, to ) );
3158}
3159
3160int x509parse_time_future( const x509_time *from )
3161{
3162 x509_time now;
3163
3164 x509_get_current_time( &now );
3165
3166 return( x509_check_time( from, &now ) );
3167}
3168
Paul Bakker40ea7de2009-05-03 10:18:48 +00003169/*
3170 * Return 1 if the certificate is revoked, or 0 otherwise.
3171 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003172int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003173{
Paul Bakkerff60ee62010-03-16 21:09:09 +00003174 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00003175
3176 while( cur != NULL && cur->serial.len != 0 )
3177 {
Paul Bakkera056efc2011-01-16 21:38:35 +00003178 if( crt->serial.len == cur->serial.len &&
3179 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003180 {
3181 if( x509parse_time_expired( &cur->revocation_date ) )
3182 return( 1 );
3183 }
3184
3185 cur = cur->next;
3186 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003187
3188 return( 0 );
3189}
3190
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003191/*
3192 * Wrapper for x509 hashes.
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003193 */
Paul Bakker23986e52011-04-24 08:57:21 +00003194static void x509_hash( const unsigned char *in, size_t len, int alg,
Paul Bakker5121ce52009-01-03 21:22:43 +00003195 unsigned char *out )
3196{
3197 switch( alg )
3198 {
Paul Bakker40e46942009-01-03 21:51:57 +00003199#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003200 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003201#endif
Paul Bakker40e46942009-01-03 21:51:57 +00003202#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003203 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003204#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003205#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003206 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003207#endif
3208#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003209 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003210#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00003211#if defined(POLARSSL_SHA2_C)
3212 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
3213 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
3214#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00003215#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003216 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
3217 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
3218#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003219 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003220 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003221 break;
3222 }
3223}
3224
3225/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00003226 * Check that the given certificate is valid accoring to the CRL.
3227 */
3228static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
3229 x509_crl *crl_list)
3230{
3231 int flags = 0;
3232 int hash_id;
3233 unsigned char hash[64];
3234
Paul Bakker915275b2012-09-28 07:10:55 +00003235 if( ca == NULL )
3236 return( flags );
3237
Paul Bakker76fd75a2011-01-16 21:12:10 +00003238 /*
3239 * TODO: What happens if no CRL is present?
3240 * Suggestion: Revocation state should be unknown if no CRL is present.
3241 * For backwards compatibility this is not yet implemented.
3242 */
3243
Paul Bakker915275b2012-09-28 07:10:55 +00003244 while( crl_list != NULL )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003245 {
Paul Bakker915275b2012-09-28 07:10:55 +00003246 if( crl_list->version == 0 ||
3247 crl_list->issuer_raw.len != ca->subject_raw.len ||
Paul Bakker76fd75a2011-01-16 21:12:10 +00003248 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
3249 crl_list->issuer_raw.len ) != 0 )
3250 {
3251 crl_list = crl_list->next;
3252 continue;
3253 }
3254
3255 /*
3256 * Check if CRL is correctly signed by the trusted CA
3257 */
3258 hash_id = crl_list->sig_alg;
3259
3260 x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
3261
Paul Bakker43f97992013-09-23 11:23:31 +02003262 if( !rsa_pkcs1_verify( &ca->rsa, NULL, NULL, RSA_PUBLIC, hash_id,
Paul Bakker76fd75a2011-01-16 21:12:10 +00003263 0, hash, crl_list->sig.p ) == 0 )
3264 {
3265 /*
3266 * CRL is not trusted
3267 */
3268 flags |= BADCRL_NOT_TRUSTED;
3269 break;
3270 }
3271
3272 /*
3273 * Check for validity of CRL (Do not drop out)
3274 */
3275 if( x509parse_time_expired( &crl_list->next_update ) )
3276 flags |= BADCRL_EXPIRED;
3277
Paul Bakker50a5c532014-07-08 10:59:10 +02003278 if( x509parse_time_future( &crl_list->this_update ) )
3279 flags |= BADCRL_FUTURE;
3280
Paul Bakker76fd75a2011-01-16 21:12:10 +00003281 /*
3282 * Check if certificate is revoked
3283 */
3284 if( x509parse_revoked(crt, crl_list) )
3285 {
3286 flags |= BADCERT_REVOKED;
3287 break;
3288 }
3289
3290 crl_list = crl_list->next;
3291 }
3292 return flags;
3293}
3294
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003295// Equal == 0, inequal == 1
3296static int x509_name_cmp( const void *s1, const void *s2, size_t len )
3297{
3298 size_t i;
3299 unsigned char diff;
3300 const unsigned char *n1 = s1, *n2 = s2;
3301
3302 for( i = 0; i < len; i++ )
3303 {
3304 diff = n1[i] ^ n2[i];
3305
Paul Bakkerc941adb2014-07-07 14:17:24 +02003306 if( diff == 0 )
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003307 continue;
3308
Paul Bakkerc941adb2014-07-07 14:17:24 +02003309 if( diff == 32 &&
3310 ( ( n1[i] >= 'a' && n1[i] <= 'z' ) ||
3311 ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) )
3312 {
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003313 continue;
Paul Bakkerc941adb2014-07-07 14:17:24 +02003314 }
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003315
3316 return( 1 );
3317 }
3318
3319 return( 0 );
3320}
3321
Paul Bakker57b12982012-02-11 17:38:38 +00003322int x509_wildcard_verify( const char *cn, x509_buf *name )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003323{
3324 size_t i;
3325 size_t cn_idx = 0;
3326
Paul Bakker57b12982012-02-11 17:38:38 +00003327 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003328 return( 0 );
3329
3330 for( i = 0; i < strlen( cn ); ++i )
3331 {
3332 if( cn[i] == '.' )
3333 {
3334 cn_idx = i;
3335 break;
3336 }
3337 }
3338
3339 if( cn_idx == 0 )
3340 return( 0 );
3341
Paul Bakker535e97d2012-08-23 10:49:55 +00003342 if( strlen( cn ) - cn_idx == name->len - 1 &&
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003343 x509_name_cmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003344 {
3345 return( 1 );
3346 }
3347
3348 return( 0 );
3349}
3350
Paul Bakker915275b2012-09-28 07:10:55 +00003351static int x509parse_verify_top(
3352 x509_cert *child, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003353 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003354 int (*f_vrfy)(void *, x509_cert *, int, int *),
3355 void *p_vrfy )
3356{
3357 int hash_id, ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003358 int ca_flags = 0, check_path_cnt = path_cnt + 1;
Paul Bakker915275b2012-09-28 07:10:55 +00003359 unsigned char hash[64];
3360
3361 if( x509parse_time_expired( &child->valid_to ) )
3362 *flags |= BADCERT_EXPIRED;
3363
Paul Bakker50a5c532014-07-08 10:59:10 +02003364 if( x509parse_time_future( &child->valid_from ) )
3365 *flags |= BADCERT_FUTURE;
3366
Paul Bakker915275b2012-09-28 07:10:55 +00003367 /*
3368 * Child is the top of the chain. Check against the trust_ca list.
3369 */
3370 *flags |= BADCERT_NOT_TRUSTED;
3371
3372 while( trust_ca != NULL )
3373 {
3374 if( trust_ca->version == 0 ||
3375 child->issuer_raw.len != trust_ca->subject_raw.len ||
3376 memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
3377 child->issuer_raw.len ) != 0 )
3378 {
3379 trust_ca = trust_ca->next;
3380 continue;
3381 }
3382
Paul Bakker9a736322012-11-14 12:39:52 +00003383 /*
3384 * Reduce path_len to check against if top of the chain is
3385 * the same as the trusted CA
3386 */
3387 if( child->subject_raw.len == trust_ca->subject_raw.len &&
3388 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3389 child->issuer_raw.len ) == 0 )
3390 {
3391 check_path_cnt--;
3392 }
3393
Paul Bakker915275b2012-09-28 07:10:55 +00003394 if( trust_ca->max_pathlen > 0 &&
Paul Bakker9a736322012-11-14 12:39:52 +00003395 trust_ca->max_pathlen < check_path_cnt )
Paul Bakker915275b2012-09-28 07:10:55 +00003396 {
3397 trust_ca = trust_ca->next;
3398 continue;
3399 }
3400
3401 hash_id = child->sig_alg;
3402
3403 x509_hash( child->tbs.p, child->tbs.len, hash_id, hash );
3404
Paul Bakker43f97992013-09-23 11:23:31 +02003405 if( rsa_pkcs1_verify( &trust_ca->rsa, NULL, NULL, RSA_PUBLIC, hash_id,
Paul Bakker915275b2012-09-28 07:10:55 +00003406 0, hash, child->sig.p ) != 0 )
3407 {
3408 trust_ca = trust_ca->next;
3409 continue;
3410 }
3411
3412 /*
3413 * Top of chain is signed by a trusted CA
3414 */
3415 *flags &= ~BADCERT_NOT_TRUSTED;
3416 break;
3417 }
3418
Paul Bakker9a736322012-11-14 12:39:52 +00003419 /*
Paul Bakker3497d8c2012-11-24 11:53:17 +01003420 * If top of chain is not the same as the trusted CA send a verify request
3421 * to the callback for any issues with validity and CRL presence for the
3422 * trusted CA certificate.
Paul Bakker9a736322012-11-14 12:39:52 +00003423 */
3424 if( trust_ca != NULL &&
3425 ( child->subject_raw.len != trust_ca->subject_raw.len ||
3426 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3427 child->issuer_raw.len ) != 0 ) )
Paul Bakker915275b2012-09-28 07:10:55 +00003428 {
3429 /* Check trusted CA's CRL for then chain's top crt */
3430 *flags |= x509parse_verifycrl( child, trust_ca, ca_crl );
3431
3432 if( x509parse_time_expired( &trust_ca->valid_to ) )
3433 ca_flags |= BADCERT_EXPIRED;
3434
Paul Bakker50a5c532014-07-08 10:59:10 +02003435 if( x509parse_time_future( &trust_ca->valid_from ) )
3436 ca_flags |= BADCERT_FUTURE;
3437
Paul Bakker915275b2012-09-28 07:10:55 +00003438 if( NULL != f_vrfy )
3439 {
Paul Bakker9a736322012-11-14 12:39:52 +00003440 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003441 return( ret );
3442 }
3443 }
3444
3445 /* Call callback on top cert */
3446 if( NULL != f_vrfy )
3447 {
Paul Bakker9a736322012-11-14 12:39:52 +00003448 if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003449 return( ret );
3450 }
3451
Paul Bakker915275b2012-09-28 07:10:55 +00003452 *flags |= ca_flags;
3453
3454 return( 0 );
3455}
3456
3457static int x509parse_verify_child(
3458 x509_cert *child, x509_cert *parent, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003459 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003460 int (*f_vrfy)(void *, x509_cert *, int, int *),
3461 void *p_vrfy )
3462{
3463 int hash_id, ret;
3464 int parent_flags = 0;
3465 unsigned char hash[64];
3466 x509_cert *grandparent;
3467
3468 if( x509parse_time_expired( &child->valid_to ) )
3469 *flags |= BADCERT_EXPIRED;
3470
Paul Bakker50a5c532014-07-08 10:59:10 +02003471 if( x509parse_time_future( &child->valid_from ) )
3472 *flags |= BADCERT_FUTURE;
3473
Paul Bakker915275b2012-09-28 07:10:55 +00003474 hash_id = child->sig_alg;
3475
3476 x509_hash( child->tbs.p, child->tbs.len, hash_id, hash );
3477
Paul Bakker43f97992013-09-23 11:23:31 +02003478 if( rsa_pkcs1_verify( &parent->rsa, NULL, NULL, RSA_PUBLIC, hash_id, 0,
3479 hash, child->sig.p ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003480 *flags |= BADCERT_NOT_TRUSTED;
3481
3482 /* Check trusted CA's CRL for the given crt */
3483 *flags |= x509parse_verifycrl(child, parent, ca_crl);
3484
3485 grandparent = parent->next;
3486
3487 while( grandparent != NULL )
3488 {
3489 if( grandparent->version == 0 ||
3490 grandparent->ca_istrue == 0 ||
3491 parent->issuer_raw.len != grandparent->subject_raw.len ||
3492 memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
3493 parent->issuer_raw.len ) != 0 )
3494 {
3495 grandparent = grandparent->next;
3496 continue;
3497 }
3498 break;
3499 }
3500
Paul Bakker915275b2012-09-28 07:10:55 +00003501 if( grandparent != NULL )
3502 {
3503 /*
3504 * Part of the chain
3505 */
Paul Bakker9a736322012-11-14 12:39:52 +00003506 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 +00003507 if( ret != 0 )
3508 return( ret );
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003509 }
Paul Bakker915275b2012-09-28 07:10:55 +00003510 else
3511 {
Paul Bakker9a736322012-11-14 12:39:52 +00003512 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 +00003513 if( ret != 0 )
3514 return( ret );
3515 }
3516
3517 /* child is verified to be a child of the parent, call verify callback */
3518 if( NULL != f_vrfy )
Paul Bakker9a736322012-11-14 12:39:52 +00003519 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003520 return( ret );
Paul Bakker915275b2012-09-28 07:10:55 +00003521
3522 *flags |= parent_flags;
3523
3524 return( 0 );
3525}
3526
Paul Bakker76fd75a2011-01-16 21:12:10 +00003527/*
Paul Bakker5121ce52009-01-03 21:22:43 +00003528 * Verify the certificate validity
3529 */
3530int x509parse_verify( x509_cert *crt,
3531 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00003532 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003533 const char *cn, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003534 int (*f_vrfy)(void *, x509_cert *, int, int *),
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003535 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00003536{
Paul Bakker23986e52011-04-24 08:57:21 +00003537 size_t cn_len;
Paul Bakker915275b2012-09-28 07:10:55 +00003538 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003539 int pathlen = 0;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003540 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00003541 x509_name *name;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003542 x509_sequence *cur = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003543
Paul Bakker40ea7de2009-05-03 10:18:48 +00003544 *flags = 0;
3545
Paul Bakker5121ce52009-01-03 21:22:43 +00003546 if( cn != NULL )
3547 {
3548 name = &crt->subject;
3549 cn_len = strlen( cn );
3550
Paul Bakker4d2c1242012-05-10 14:12:46 +00003551 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
Paul Bakker5121ce52009-01-03 21:22:43 +00003552 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00003553 cur = &crt->subject_alt_names;
3554
3555 while( cur != NULL )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003556 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003557 if( cur->buf.len == cn_len &&
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003558 x509_name_cmp( cn, cur->buf.p, cn_len ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003559 break;
3560
Paul Bakker535e97d2012-08-23 10:49:55 +00003561 if( cur->buf.len > 2 &&
3562 memcmp( cur->buf.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003563 x509_wildcard_verify( cn, &cur->buf ) )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003564 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003565
Paul Bakker4d2c1242012-05-10 14:12:46 +00003566 cur = cur->next;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003567 }
3568
3569 if( cur == NULL )
3570 *flags |= BADCERT_CN_MISMATCH;
3571 }
Paul Bakker4d2c1242012-05-10 14:12:46 +00003572 else
3573 {
3574 while( name != NULL )
3575 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003576 if( name->oid.len == 3 &&
3577 memcmp( name->oid.p, OID_CN, 3 ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003578 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003579 if( name->val.len == cn_len &&
Paul Bakkerf65fbee2013-09-11 11:52:17 +02003580 x509_name_cmp( name->val.p, cn, cn_len ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003581 break;
3582
Paul Bakker535e97d2012-08-23 10:49:55 +00003583 if( name->val.len > 2 &&
3584 memcmp( name->val.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003585 x509_wildcard_verify( cn, &name->val ) )
3586 break;
3587 }
3588
3589 name = name->next;
3590 }
3591
3592 if( name == NULL )
3593 *flags |= BADCERT_CN_MISMATCH;
3594 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003595 }
3596
Paul Bakker5121ce52009-01-03 21:22:43 +00003597 /*
Paul Bakker915275b2012-09-28 07:10:55 +00003598 * Iterate upwards in the given cert chain, to find our crt parent.
3599 * Ignore any upper cert with CA != TRUE.
Paul Bakker5121ce52009-01-03 21:22:43 +00003600 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003601 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003602
Paul Bakker76fd75a2011-01-16 21:12:10 +00003603 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003604 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003605 if( parent->ca_istrue == 0 ||
3606 crt->issuer_raw.len != parent->subject_raw.len ||
3607 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00003608 crt->issuer_raw.len ) != 0 )
3609 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003610 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003611 continue;
3612 }
Paul Bakker915275b2012-09-28 07:10:55 +00003613 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003614 }
3615
Paul Bakker915275b2012-09-28 07:10:55 +00003616 if( parent != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003617 {
Paul Bakker915275b2012-09-28 07:10:55 +00003618 /*
3619 * Part of the chain
3620 */
Paul Bakker9a736322012-11-14 12:39:52 +00003621 ret = x509parse_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003622 if( ret != 0 )
3623 return( ret );
3624 }
3625 else
Paul Bakker74111d32011-01-15 16:57:55 +00003626 {
Paul Bakker9a736322012-11-14 12:39:52 +00003627 ret = x509parse_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003628 if( ret != 0 )
3629 return( ret );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003630 }
Paul Bakker915275b2012-09-28 07:10:55 +00003631
3632 if( *flags != 0 )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003633 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003634
Paul Bakker5121ce52009-01-03 21:22:43 +00003635 return( 0 );
3636}
3637
3638/*
3639 * Unallocate all certificate data
3640 */
3641void x509_free( x509_cert *crt )
3642{
3643 x509_cert *cert_cur = crt;
3644 x509_cert *cert_prv;
3645 x509_name *name_cur;
3646 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00003647 x509_sequence *seq_cur;
3648 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00003649
3650 if( crt == NULL )
3651 return;
3652
3653 do
3654 {
3655 rsa_free( &cert_cur->rsa );
3656
3657 name_cur = cert_cur->issuer.next;
3658 while( name_cur != NULL )
3659 {
3660 name_prv = name_cur;
3661 name_cur = name_cur->next;
3662 memset( name_prv, 0, sizeof( x509_name ) );
3663 free( name_prv );
3664 }
3665
3666 name_cur = cert_cur->subject.next;
3667 while( name_cur != NULL )
3668 {
3669 name_prv = name_cur;
3670 name_cur = name_cur->next;
3671 memset( name_prv, 0, sizeof( x509_name ) );
3672 free( name_prv );
3673 }
3674
Paul Bakker74111d32011-01-15 16:57:55 +00003675 seq_cur = cert_cur->ext_key_usage.next;
3676 while( seq_cur != NULL )
3677 {
3678 seq_prv = seq_cur;
3679 seq_cur = seq_cur->next;
3680 memset( seq_prv, 0, sizeof( x509_sequence ) );
3681 free( seq_prv );
3682 }
3683
Paul Bakker8afa70d2012-02-11 18:42:45 +00003684 seq_cur = cert_cur->subject_alt_names.next;
3685 while( seq_cur != NULL )
3686 {
3687 seq_prv = seq_cur;
3688 seq_cur = seq_cur->next;
3689 memset( seq_prv, 0, sizeof( x509_sequence ) );
3690 free( seq_prv );
3691 }
3692
Paul Bakker5121ce52009-01-03 21:22:43 +00003693 if( cert_cur->raw.p != NULL )
3694 {
3695 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
3696 free( cert_cur->raw.p );
3697 }
3698
3699 cert_cur = cert_cur->next;
3700 }
3701 while( cert_cur != NULL );
3702
3703 cert_cur = crt;
3704 do
3705 {
3706 cert_prv = cert_cur;
3707 cert_cur = cert_cur->next;
3708
3709 memset( cert_prv, 0, sizeof( x509_cert ) );
3710 if( cert_prv != crt )
3711 free( cert_prv );
3712 }
3713 while( cert_cur != NULL );
3714}
3715
Paul Bakkerd98030e2009-05-02 15:13:40 +00003716/*
3717 * Unallocate all CRL data
3718 */
3719void x509_crl_free( x509_crl *crl )
3720{
3721 x509_crl *crl_cur = crl;
3722 x509_crl *crl_prv;
3723 x509_name *name_cur;
3724 x509_name *name_prv;
3725 x509_crl_entry *entry_cur;
3726 x509_crl_entry *entry_prv;
3727
3728 if( crl == NULL )
3729 return;
3730
3731 do
3732 {
3733 name_cur = crl_cur->issuer.next;
3734 while( name_cur != NULL )
3735 {
3736 name_prv = name_cur;
3737 name_cur = name_cur->next;
3738 memset( name_prv, 0, sizeof( x509_name ) );
3739 free( name_prv );
3740 }
3741
3742 entry_cur = crl_cur->entry.next;
3743 while( entry_cur != NULL )
3744 {
3745 entry_prv = entry_cur;
3746 entry_cur = entry_cur->next;
3747 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
3748 free( entry_prv );
3749 }
3750
3751 if( crl_cur->raw.p != NULL )
3752 {
3753 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
3754 free( crl_cur->raw.p );
3755 }
3756
3757 crl_cur = crl_cur->next;
3758 }
3759 while( crl_cur != NULL );
3760
3761 crl_cur = crl;
3762 do
3763 {
3764 crl_prv = crl_cur;
3765 crl_cur = crl_cur->next;
3766
3767 memset( crl_prv, 0, sizeof( x509_crl ) );
3768 if( crl_prv != crl )
3769 free( crl_prv );
3770 }
3771 while( crl_cur != NULL );
3772}
3773
Paul Bakker40e46942009-01-03 21:51:57 +00003774#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00003775
Paul Bakker40e46942009-01-03 21:51:57 +00003776#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00003777
3778/*
3779 * Checkup routine
3780 */
3781int x509_self_test( int verbose )
3782{
Paul Bakker5690efc2011-05-26 13:16:06 +00003783#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00003784 int ret;
3785 int flags;
3786 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00003787 x509_cert cacert;
3788 x509_cert clicert;
3789 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00003790#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003791 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00003792#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003793
3794 if( verbose != 0 )
3795 printf( " X.509 certificate load: " );
3796
3797 memset( &clicert, 0, sizeof( x509_cert ) );
3798
Paul Bakkereae09db2013-06-06 12:35:54 +02003799 ret = x509parse_crt( &clicert, (const unsigned char *) test_cli_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003800 strlen( test_cli_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003801 if( ret != 0 )
3802 {
3803 if( verbose != 0 )
3804 printf( "failed\n" );
3805
3806 return( ret );
3807 }
3808
3809 memset( &cacert, 0, sizeof( x509_cert ) );
3810
Paul Bakkereae09db2013-06-06 12:35:54 +02003811 ret = x509parse_crt( &cacert, (const unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003812 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003813 if( ret != 0 )
3814 {
3815 if( verbose != 0 )
3816 printf( "failed\n" );
3817
3818 return( ret );
3819 }
3820
3821 if( verbose != 0 )
3822 printf( "passed\n X.509 private key load: " );
3823
3824 i = strlen( test_ca_key );
3825 j = strlen( test_ca_pwd );
3826
Paul Bakker66b78b22011-03-25 14:22:50 +00003827 rsa_init( &rsa, RSA_PKCS_V15, 0 );
3828
Paul Bakker5121ce52009-01-03 21:22:43 +00003829 if( ( ret = x509parse_key( &rsa,
Paul Bakkereae09db2013-06-06 12:35:54 +02003830 (const unsigned char *) test_ca_key, i,
3831 (const unsigned char *) test_ca_pwd, j ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003832 {
3833 if( verbose != 0 )
3834 printf( "failed\n" );
3835
3836 return( ret );
3837 }
3838
3839 if( verbose != 0 )
3840 printf( "passed\n X.509 signature verify: ");
3841
Paul Bakker23986e52011-04-24 08:57:21 +00003842 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003843 if( ret != 0 )
3844 {
3845 if( verbose != 0 )
3846 printf( "failed\n" );
3847
3848 return( ret );
3849 }
3850
Paul Bakker5690efc2011-05-26 13:16:06 +00003851#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003852 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003853 printf( "passed\n X.509 DHM parameter load: " );
3854
3855 i = strlen( test_dhm_params );
3856 j = strlen( test_ca_pwd );
3857
Paul Bakkereae09db2013-06-06 12:35:54 +02003858 if( ( ret = x509parse_dhm( &dhm, (const unsigned char *) test_dhm_params, i ) ) != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003859 {
3860 if( verbose != 0 )
3861 printf( "failed\n" );
3862
3863 return( ret );
3864 }
3865
3866 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003867 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00003868#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003869
3870 x509_free( &cacert );
3871 x509_free( &clicert );
3872 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00003873#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003874 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00003875#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003876
3877 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003878#else
3879 ((void) verbose);
3880 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3881#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003882}
3883
3884#endif
3885
3886#endif