blob: 08297ee65acf3f9ef481c4c4656e68fd416ceafc [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 Bakkercf6e95d2013-06-12 13:18:15 +020064#include "polarssl/pkcs12.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000065
66#include <string.h>
67#include <stdlib.h>
Paul Bakker4f229e52011-12-04 22:11:35 +000068#if defined(_WIN32)
Paul Bakkercce9d772011-11-18 14:26:47 +000069#include <windows.h>
70#else
Paul Bakker5121ce52009-01-03 21:22:43 +000071#include <time.h>
Paul Bakkercce9d772011-11-18 14:26:47 +000072#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000073
Paul Bakker335db3f2011-04-25 15:28:35 +000074#if defined(POLARSSL_FS_IO)
75#include <stdio.h>
Paul Bakker4a2bd0d2012-11-02 11:06:08 +000076#if !defined(_WIN32)
Paul Bakker8d914582012-06-04 12:46:42 +000077#include <sys/types.h>
78#include <dirent.h>
79#endif
Paul Bakker335db3f2011-04-25 15:28:35 +000080#endif
81
Paul Bakkercf6e95d2013-06-12 13:18:15 +020082/* Compare a given OID string with an OID x509_buf * */
83#define OID_CMP(oid_str, oid_buf) \
84 ( ( OID_SIZE(oid_str) == (oid_buf)->len ) && \
85 memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0)
86
Paul Bakker5121ce52009-01-03 21:22:43 +000087/*
Paul Bakker5121ce52009-01-03 21:22:43 +000088 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
89 */
90static int x509_get_version( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +000091 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +000092 int *ver )
93{
Paul Bakker23986e52011-04-24 08:57:21 +000094 int ret;
95 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +000096
97 if( ( ret = asn1_get_tag( p, end, &len,
98 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
99 {
Paul Bakker40e46942009-01-03 21:51:57 +0000100 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +0000101 {
102 *ver = 0;
103 return( 0 );
104 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000105
106 return( ret );
107 }
108
109 end = *p + len;
110
111 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000112 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000113
114 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000115 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION +
Paul Bakker40e46942009-01-03 21:51:57 +0000116 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000117
118 return( 0 );
119}
120
121/*
Paul Bakkerfae618f2011-10-12 11:53:52 +0000122 * Version ::= INTEGER { v1(0), v2(1) }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000123 */
124static int x509_crl_get_version( unsigned char **p,
125 const unsigned char *end,
126 int *ver )
127{
128 int ret;
129
130 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
131 {
132 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +0000133 {
134 *ver = 0;
135 return( 0 );
136 }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000137
138 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
139 }
140
141 return( 0 );
142}
143
144/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000145 * CertificateSerialNumber ::= INTEGER
146 */
147static int x509_get_serial( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000148 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000149 x509_buf *serial )
150{
151 int ret;
152
153 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000154 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000155 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000156
157 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
158 **p != ASN1_INTEGER )
Paul Bakker9d781402011-05-09 16:17:09 +0000159 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000160 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000161
162 serial->tag = *(*p)++;
163
164 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000165 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000166
167 serial->p = *p;
168 *p += serial->len;
169
170 return( 0 );
171}
172
173/*
174 * AlgorithmIdentifier ::= SEQUENCE {
175 * algorithm OBJECT IDENTIFIER,
176 * parameters ANY DEFINED BY algorithm OPTIONAL }
177 */
178static int x509_get_alg( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000179 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000180 x509_buf *alg )
181{
Paul Bakker23986e52011-04-24 08:57:21 +0000182 int ret;
183 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000184
185 if( ( ret = asn1_get_tag( p, end, &len,
186 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000187 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000188
189 end = *p + len;
190 alg->tag = **p;
191
192 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 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 alg->p = *p;
196 *p += alg->len;
197
198 if( *p == end )
199 return( 0 );
200
201 /*
202 * assume the algorithm parameters must be NULL
203 */
204 if( ( ret = asn1_get_tag( p, end, &len, ASN1_NULL ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000205 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000206
207 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000208 return( POLARSSL_ERR_X509_CERT_INVALID_ALG +
Paul Bakker40e46942009-01-03 21:51:57 +0000209 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000210
211 return( 0 );
212}
213
214/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000215 * AttributeTypeAndValue ::= SEQUENCE {
216 * type AttributeType,
217 * value AttributeValue }
218 *
219 * AttributeType ::= OBJECT IDENTIFIER
220 *
221 * AttributeValue ::= ANY DEFINED BY AttributeType
222 */
Paul Bakker400ff6f2011-02-20 10:40:16 +0000223static int x509_get_attr_type_value( unsigned char **p,
224 const unsigned char *end,
225 x509_name *cur )
Paul Bakker5121ce52009-01-03 21:22:43 +0000226{
Paul Bakker23986e52011-04-24 08:57:21 +0000227 int ret;
228 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000229 x509_buf *oid;
230 x509_buf *val;
231
232 if( ( ret = asn1_get_tag( p, end, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000233 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000234 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000235
Paul Bakker5121ce52009-01-03 21:22:43 +0000236 oid = &cur->oid;
237 oid->tag = **p;
238
239 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 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
242 oid->p = *p;
243 *p += oid->len;
244
245 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000246 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000247 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000248
249 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
250 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
251 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
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_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000254
255 val = &cur->val;
256 val->tag = *(*p)++;
257
258 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000259 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000260
261 val->p = *p;
262 *p += val->len;
263
264 cur->next = NULL;
265
Paul Bakker400ff6f2011-02-20 10:40:16 +0000266 return( 0 );
267}
268
269/*
270 * RelativeDistinguishedName ::=
271 * SET OF AttributeTypeAndValue
272 *
273 * AttributeTypeAndValue ::= SEQUENCE {
274 * type AttributeType,
275 * value AttributeValue }
276 *
277 * AttributeType ::= OBJECT IDENTIFIER
278 *
279 * AttributeValue ::= ANY DEFINED BY AttributeType
280 */
281static int x509_get_name( unsigned char **p,
282 const unsigned char *end,
283 x509_name *cur )
284{
Paul Bakker23986e52011-04-24 08:57:21 +0000285 int ret;
286 size_t len;
Paul Bakker400ff6f2011-02-20 10:40:16 +0000287 const unsigned char *end2;
288 x509_name *use;
289
290 if( ( ret = asn1_get_tag( p, end, &len,
291 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000292 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000293
294 end2 = end;
295 end = *p + len;
296 use = cur;
297
298 do
299 {
300 if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
301 return( ret );
302
303 if( *p != end )
304 {
305 use->next = (x509_name *) malloc(
306 sizeof( x509_name ) );
307
308 if( use->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000309 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000310
311 memset( use->next, 0, sizeof( x509_name ) );
312
313 use = use->next;
314 }
315 }
316 while( *p != end );
Paul Bakker5121ce52009-01-03 21:22:43 +0000317
318 /*
319 * recurse until end of SEQUENCE is reached
320 */
321 if( *p == end2 )
322 return( 0 );
323
324 cur->next = (x509_name *) malloc(
325 sizeof( x509_name ) );
326
327 if( cur->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000328 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000329
Paul Bakker430ffbe2012-05-01 08:14:20 +0000330 memset( cur->next, 0, sizeof( x509_name ) );
331
Paul Bakker5121ce52009-01-03 21:22:43 +0000332 return( x509_get_name( p, end2, cur->next ) );
333}
334
335/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000336 * Time ::= CHOICE {
337 * utcTime UTCTime,
338 * generalTime GeneralizedTime }
339 */
Paul Bakker91200182010-02-18 21:26:15 +0000340static int x509_get_time( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000341 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000342 x509_time *time )
343{
Paul Bakker23986e52011-04-24 08:57:21 +0000344 int ret;
345 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000346 char date[64];
Paul Bakker91200182010-02-18 21:26:15 +0000347 unsigned char tag;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000348
Paul Bakker91200182010-02-18 21:26:15 +0000349 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000350 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
351 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000352
Paul Bakker91200182010-02-18 21:26:15 +0000353 tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000354
Paul Bakker91200182010-02-18 21:26:15 +0000355 if ( tag == ASN1_UTC_TIME )
356 {
357 (*p)++;
358 ret = asn1_get_len( p, end, &len );
359
360 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000361 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000362
Paul Bakker91200182010-02-18 21:26:15 +0000363 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000364 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
365 len : sizeof( date ) - 1 );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000366
Paul Bakker91200182010-02-18 21:26:15 +0000367 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
368 &time->year, &time->mon, &time->day,
369 &time->hour, &time->min, &time->sec ) < 5 )
370 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000371
Paul Bakker400ff6f2011-02-20 10:40:16 +0000372 time->year += 100 * ( time->year < 50 );
Paul Bakker91200182010-02-18 21:26:15 +0000373 time->year += 1900;
374
375 *p += len;
376
377 return( 0 );
378 }
379 else if ( tag == ASN1_GENERALIZED_TIME )
380 {
381 (*p)++;
382 ret = asn1_get_len( p, end, &len );
383
384 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000385 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker91200182010-02-18 21:26:15 +0000386
387 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000388 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
389 len : sizeof( date ) - 1 );
Paul Bakker91200182010-02-18 21:26:15 +0000390
391 if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
392 &time->year, &time->mon, &time->day,
393 &time->hour, &time->min, &time->sec ) < 5 )
394 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
395
396 *p += len;
397
398 return( 0 );
399 }
400 else
Paul Bakker9d781402011-05-09 16:17:09 +0000401 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000402}
403
404
405/*
406 * Validity ::= SEQUENCE {
407 * notBefore Time,
408 * notAfter Time }
409 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000410static int x509_get_dates( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000411 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000412 x509_time *from,
413 x509_time *to )
414{
Paul Bakker23986e52011-04-24 08:57:21 +0000415 int ret;
416 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000417
418 if( ( ret = asn1_get_tag( p, end, &len,
419 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000420 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000421
422 end = *p + len;
423
Paul Bakker91200182010-02-18 21:26:15 +0000424 if( ( ret = x509_get_time( p, end, from ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000425 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000426
Paul Bakker91200182010-02-18 21:26:15 +0000427 if( ( ret = x509_get_time( p, end, to ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000428 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000429
430 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000431 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker40e46942009-01-03 21:51:57 +0000432 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000433
434 return( 0 );
435}
436
437/*
438 * SubjectPublicKeyInfo ::= SEQUENCE {
439 * algorithm AlgorithmIdentifier,
440 * subjectPublicKey BIT STRING }
441 */
442static int x509_get_pubkey( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000443 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000444 x509_buf *pk_alg_oid,
445 mpi *N, mpi *E )
446{
Paul Bakker65a19092013-06-06 21:14:58 +0200447 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000448 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000449 unsigned char *end2;
450
451 if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 )
452 return( ret );
453
454 /*
455 * only RSA public keys handled at this time
456 */
Paul Bakker65a19092013-06-06 21:14:58 +0200457 if( pk_alg_oid->len != 9 ||
458 memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) != 0 )
Paul Bakker400ff6f2011-02-20 10:40:16 +0000459 {
Paul Bakkered56b222011-07-13 11:26:43 +0000460 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
Paul Bakker65a19092013-06-06 21:14:58 +0200461 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000462
463 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000464 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000465
466 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000467 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000468 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000469
470 end2 = *p + len;
471
472 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000473 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000474
475 /*
476 * RSAPublicKey ::= SEQUENCE {
477 * modulus INTEGER, -- n
478 * publicExponent INTEGER -- e
479 * }
480 */
481 if( ( ret = asn1_get_tag( p, end2, &len,
482 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000483 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000484
485 if( *p + len != end2 )
Paul Bakker9d781402011-05-09 16:17:09 +0000486 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000487 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000488
489 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
490 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000491 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000492
493 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000494 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000495 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000496
497 return( 0 );
498}
499
500static int x509_get_sig( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000501 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000502 x509_buf *sig )
503{
Paul Bakker23986e52011-04-24 08:57:21 +0000504 int ret;
505 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000506
Paul Bakker8afa70d2012-02-11 18:42:45 +0000507 if( ( end - *p ) < 1 )
508 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE +
509 POLARSSL_ERR_ASN1_OUT_OF_DATA );
510
Paul Bakker5121ce52009-01-03 21:22:43 +0000511 sig->tag = **p;
512
513 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000514 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000515
Paul Bakker74111d32011-01-15 16:57:55 +0000516
Paul Bakker5121ce52009-01-03 21:22:43 +0000517 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000518 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000519
520 sig->len = len;
521 sig->p = *p;
522
523 *p += len;
524
525 return( 0 );
526}
527
528/*
529 * X.509 v2/v3 unique identifier (not parsed)
530 */
531static int x509_get_uid( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000532 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000533 x509_buf *uid, int n )
534{
535 int ret;
536
537 if( *p == end )
538 return( 0 );
539
540 uid->tag = **p;
541
542 if( ( ret = asn1_get_tag( p, end, &uid->len,
543 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
544 {
Paul Bakker40e46942009-01-03 21:51:57 +0000545 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000546 return( 0 );
547
548 return( ret );
549 }
550
551 uid->p = *p;
552 *p += uid->len;
553
554 return( 0 );
555}
556
557/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000558 * X.509 Extensions (No parsing of extensions, pointer should
559 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000560 */
561static int x509_get_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000562 const unsigned char *end,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000563 x509_buf *ext, int tag )
Paul Bakker5121ce52009-01-03 21:22:43 +0000564{
Paul Bakker23986e52011-04-24 08:57:21 +0000565 int ret;
566 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000567
568 if( *p == end )
569 return( 0 );
570
571 ext->tag = **p;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000572
Paul Bakker5121ce52009-01-03 21:22:43 +0000573 if( ( ret = asn1_get_tag( p, end, &ext->len,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000574 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000575 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000576
577 ext->p = *p;
578 end = *p + ext->len;
579
580 /*
581 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
582 *
583 * Extension ::= SEQUENCE {
584 * extnID OBJECT IDENTIFIER,
585 * critical BOOLEAN DEFAULT FALSE,
586 * extnValue OCTET STRING }
587 */
588 if( ( ret = asn1_get_tag( p, end, &len,
589 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000590 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000591
592 if( end != *p + len )
Paul Bakker9d781402011-05-09 16:17:09 +0000593 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +0000594 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000595
Paul Bakkerd98030e2009-05-02 15:13:40 +0000596 return( 0 );
597}
598
599/*
600 * X.509 CRL v2 extensions (no extensions parsed yet.)
601 */
602static int x509_get_crl_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000603 const unsigned char *end,
604 x509_buf *ext )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000605{
Paul Bakker23986e52011-04-24 08:57:21 +0000606 int ret;
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000607 size_t len = 0;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000608
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000609 /* Get explicit tag */
610 if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000611 {
612 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
613 return( 0 );
614
615 return( ret );
616 }
617
618 while( *p < end )
619 {
620 if( ( ret = asn1_get_tag( p, end, &len,
621 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000622 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000623
624 *p += len;
625 }
626
627 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000628 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerd98030e2009-05-02 15:13:40 +0000629 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
630
631 return( 0 );
632}
633
Paul Bakkerb5a11ab2011-10-12 09:58:41 +0000634/*
635 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
636 */
637static int x509_get_crl_entry_ext( unsigned char **p,
638 const unsigned char *end,
639 x509_buf *ext )
640{
641 int ret;
642 size_t len = 0;
643
644 /* OPTIONAL */
645 if (end <= *p)
646 return( 0 );
647
648 ext->tag = **p;
649 ext->p = *p;
650
651 /*
652 * Get CRL-entry extension sequence header
653 * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
654 */
655 if( ( ret = asn1_get_tag( p, end, &ext->len,
656 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
657 {
658 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
659 {
660 ext->p = NULL;
661 return( 0 );
662 }
663 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
664 }
665
666 end = *p + ext->len;
667
668 if( end != *p + ext->len )
669 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
670 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
671
672 while( *p < end )
673 {
674 if( ( ret = asn1_get_tag( p, end, &len,
675 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
676 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
677
678 *p += len;
679 }
680
681 if( *p != end )
682 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
683 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
684
685 return( 0 );
686}
687
Paul Bakker74111d32011-01-15 16:57:55 +0000688static int x509_get_basic_constraints( unsigned char **p,
689 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000690 int *ca_istrue,
691 int *max_pathlen )
692{
Paul Bakker23986e52011-04-24 08:57:21 +0000693 int ret;
694 size_t len;
Paul Bakker74111d32011-01-15 16:57:55 +0000695
696 /*
697 * BasicConstraints ::= SEQUENCE {
698 * cA BOOLEAN DEFAULT FALSE,
699 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
700 */
Paul Bakker3cccddb2011-01-16 21:46:31 +0000701 *ca_istrue = 0; /* DEFAULT FALSE */
Paul Bakker74111d32011-01-15 16:57:55 +0000702 *max_pathlen = 0; /* endless */
703
704 if( ( ret = asn1_get_tag( p, end, &len,
705 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000706 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000707
708 if( *p == end )
709 return 0;
710
Paul Bakker3cccddb2011-01-16 21:46:31 +0000711 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000712 {
713 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker3cccddb2011-01-16 21:46:31 +0000714 ret = asn1_get_int( p, end, ca_istrue );
Paul Bakker74111d32011-01-15 16:57:55 +0000715
716 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000717 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000718
Paul Bakker3cccddb2011-01-16 21:46:31 +0000719 if( *ca_istrue != 0 )
720 *ca_istrue = 1;
Paul Bakker74111d32011-01-15 16:57:55 +0000721 }
722
723 if( *p == end )
724 return 0;
725
726 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000727 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000728
729 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000730 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000731 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
732
733 (*max_pathlen)++;
734
Paul Bakker74111d32011-01-15 16:57:55 +0000735 return 0;
736}
737
738static int x509_get_ns_cert_type( unsigned char **p,
739 const unsigned char *end,
740 unsigned char *ns_cert_type)
741{
742 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000743 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000744
745 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000746 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000747
748 if( bs.len != 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000749 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000750 POLARSSL_ERR_ASN1_INVALID_LENGTH );
751
752 /* Get actual bitstring */
753 *ns_cert_type = *bs.p;
754 return 0;
755}
756
757static int x509_get_key_usage( unsigned char **p,
758 const unsigned char *end,
759 unsigned char *key_usage)
760{
761 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000762 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000763
764 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000765 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000766
Paul Bakker94a67962012-08-23 13:03:52 +0000767 if( bs.len < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000768 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000769 POLARSSL_ERR_ASN1_INVALID_LENGTH );
770
771 /* Get actual bitstring */
772 *key_usage = *bs.p;
773 return 0;
774}
775
Paul Bakkerd98030e2009-05-02 15:13:40 +0000776/*
Paul Bakker74111d32011-01-15 16:57:55 +0000777 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
778 *
779 * KeyPurposeId ::= OBJECT IDENTIFIER
780 */
781static int x509_get_ext_key_usage( unsigned char **p,
782 const unsigned char *end,
783 x509_sequence *ext_key_usage)
784{
785 int ret;
786
787 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000788 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000789
790 /* Sequence length must be >= 1 */
791 if( ext_key_usage->buf.p == NULL )
Paul Bakker9d781402011-05-09 16:17:09 +0000792 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000793 POLARSSL_ERR_ASN1_INVALID_LENGTH );
794
795 return 0;
796}
797
798/*
Paul Bakkera8cd2392012-02-11 16:09:32 +0000799 * SubjectAltName ::= GeneralNames
800 *
801 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
802 *
803 * GeneralName ::= CHOICE {
804 * otherName [0] OtherName,
805 * rfc822Name [1] IA5String,
806 * dNSName [2] IA5String,
807 * x400Address [3] ORAddress,
808 * directoryName [4] Name,
809 * ediPartyName [5] EDIPartyName,
810 * uniformResourceIdentifier [6] IA5String,
811 * iPAddress [7] OCTET STRING,
812 * registeredID [8] OBJECT IDENTIFIER }
813 *
814 * OtherName ::= SEQUENCE {
815 * type-id OBJECT IDENTIFIER,
816 * value [0] EXPLICIT ANY DEFINED BY type-id }
817 *
818 * EDIPartyName ::= SEQUENCE {
819 * nameAssigner [0] DirectoryString OPTIONAL,
820 * partyName [1] DirectoryString }
821 *
822 * NOTE: PolarSSL only parses and uses dNSName at this point.
823 */
824static int x509_get_subject_alt_name( unsigned char **p,
825 const unsigned char *end,
826 x509_sequence *subject_alt_name )
827{
828 int ret;
829 size_t len, tag_len;
830 asn1_buf *buf;
831 unsigned char tag;
832 asn1_sequence *cur = subject_alt_name;
833
834 /* Get main sequence tag */
835 if( ( ret = asn1_get_tag( p, end, &len,
836 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
837 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
838
839 if( *p + len != end )
840 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
841 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
842
843 while( *p < end )
844 {
845 if( ( end - *p ) < 1 )
846 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
847 POLARSSL_ERR_ASN1_OUT_OF_DATA );
848
849 tag = **p;
850 (*p)++;
851 if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 )
852 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
853
854 if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC )
855 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
856 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
857
858 if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) )
859 {
860 *p += tag_len;
861 continue;
862 }
863
864 buf = &(cur->buf);
865 buf->tag = tag;
866 buf->p = *p;
867 buf->len = tag_len;
868 *p += buf->len;
869
870 /* Allocate and assign next pointer */
871 if (*p < end)
872 {
873 cur->next = (asn1_sequence *) malloc(
874 sizeof( asn1_sequence ) );
875
876 if( cur->next == NULL )
877 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
878 POLARSSL_ERR_ASN1_MALLOC_FAILED );
879
Paul Bakker535e97d2012-08-23 10:49:55 +0000880 memset( cur->next, 0, sizeof( asn1_sequence ) );
Paul Bakkera8cd2392012-02-11 16:09:32 +0000881 cur = cur->next;
882 }
883 }
884
885 /* Set final sequence entry's next pointer to NULL */
886 cur->next = NULL;
887
888 if( *p != end )
889 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
890 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
891
892 return( 0 );
893}
894
895/*
Paul Bakker74111d32011-01-15 16:57:55 +0000896 * X.509 v3 extensions
897 *
898 * TODO: Perform all of the basic constraints tests required by the RFC
899 * TODO: Set values for undetected extensions to a sane default?
900 *
Paul Bakkerd98030e2009-05-02 15:13:40 +0000901 */
902static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000903 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000904 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000905{
Paul Bakker23986e52011-04-24 08:57:21 +0000906 int ret;
907 size_t len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000908 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000909
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000910 if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000911 {
912 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
913 return( 0 );
914
915 return( ret );
916 }
917
Paul Bakker5121ce52009-01-03 21:22:43 +0000918 while( *p < end )
919 {
Paul Bakker74111d32011-01-15 16:57:55 +0000920 /*
921 * Extension ::= SEQUENCE {
922 * extnID OBJECT IDENTIFIER,
923 * critical BOOLEAN DEFAULT FALSE,
924 * extnValue OCTET STRING }
925 */
926 x509_buf extn_oid = {0, 0, NULL};
927 int is_critical = 0; /* DEFAULT FALSE */
928
Paul Bakker5121ce52009-01-03 21:22:43 +0000929 if( ( ret = asn1_get_tag( p, end, &len,
930 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000931 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000932
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000933 end_ext_data = *p + len;
934
Paul Bakker74111d32011-01-15 16:57:55 +0000935 /* Get extension ID */
936 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000937
Paul Bakker74111d32011-01-15 16:57:55 +0000938 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000939 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000940
Paul Bakker74111d32011-01-15 16:57:55 +0000941 extn_oid.p = *p;
942 *p += extn_oid.len;
943
944 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000945 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000946 POLARSSL_ERR_ASN1_OUT_OF_DATA );
947
948 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000949 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000950 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
Paul Bakker9d781402011-05-09 16:17:09 +0000951 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000952
Paul Bakker74111d32011-01-15 16:57:55 +0000953 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000954 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000955 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000956 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000957
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000958 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000959
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000960 if( end_ext_octet != end_ext_data )
Paul Bakker9d781402011-05-09 16:17:09 +0000961 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000962 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000963
Paul Bakker74111d32011-01-15 16:57:55 +0000964 /*
965 * Detect supported extensions
966 */
967 if( ( OID_SIZE( OID_BASIC_CONSTRAINTS ) == extn_oid.len ) &&
968 memcmp( extn_oid.p, OID_BASIC_CONSTRAINTS, extn_oid.len ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000969 {
Paul Bakker74111d32011-01-15 16:57:55 +0000970 /* Parse basic constraints */
971 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
Paul Bakker3cccddb2011-01-16 21:46:31 +0000972 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000973 return ( ret );
974 crt->ext_types |= EXT_BASIC_CONSTRAINTS;
Paul Bakker5121ce52009-01-03 21:22:43 +0000975 }
Paul Bakker74111d32011-01-15 16:57:55 +0000976 else if( ( OID_SIZE( OID_NS_CERT_TYPE ) == extn_oid.len ) &&
977 memcmp( extn_oid.p, OID_NS_CERT_TYPE, extn_oid.len ) == 0 )
978 {
979 /* Parse netscape certificate type */
980 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
981 &crt->ns_cert_type ) ) != 0 )
982 return ( ret );
983 crt->ext_types |= EXT_NS_CERT_TYPE;
984 }
985 else if( ( OID_SIZE( OID_KEY_USAGE ) == extn_oid.len ) &&
986 memcmp( extn_oid.p, OID_KEY_USAGE, extn_oid.len ) == 0 )
987 {
988 /* Parse key usage */
989 if( ( ret = x509_get_key_usage( p, end_ext_octet,
990 &crt->key_usage ) ) != 0 )
991 return ( ret );
992 crt->ext_types |= EXT_KEY_USAGE;
993 }
994 else if( ( OID_SIZE( OID_EXTENDED_KEY_USAGE ) == extn_oid.len ) &&
995 memcmp( extn_oid.p, OID_EXTENDED_KEY_USAGE, extn_oid.len ) == 0 )
996 {
997 /* Parse extended key usage */
998 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
999 &crt->ext_key_usage ) ) != 0 )
1000 return ( ret );
1001 crt->ext_types |= EXT_EXTENDED_KEY_USAGE;
1002 }
Paul Bakkera8cd2392012-02-11 16:09:32 +00001003 else if( ( OID_SIZE( OID_SUBJECT_ALT_NAME ) == extn_oid.len ) &&
1004 memcmp( extn_oid.p, OID_SUBJECT_ALT_NAME, extn_oid.len ) == 0 )
1005 {
1006 /* Parse extended key usage */
1007 if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
1008 &crt->subject_alt_names ) ) != 0 )
1009 return ( ret );
1010 crt->ext_types |= EXT_SUBJECT_ALT_NAME;
1011 }
Paul Bakker74111d32011-01-15 16:57:55 +00001012 else
1013 {
1014 /* No parser found, skip extension */
1015 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +00001016
Paul Bakker5c721f92011-07-27 16:51:09 +00001017#if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
Paul Bakker74111d32011-01-15 16:57:55 +00001018 if( is_critical )
1019 {
1020 /* Data is marked as critical: fail */
Paul Bakker9d781402011-05-09 16:17:09 +00001021 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +00001022 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
1023 }
Paul Bakker5c721f92011-07-27 16:51:09 +00001024#endif
Paul Bakker74111d32011-01-15 16:57:55 +00001025 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001026 }
1027
1028 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +00001029 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +00001030 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001031
Paul Bakker5121ce52009-01-03 21:22:43 +00001032 return( 0 );
1033}
1034
1035/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001036 * X.509 CRL Entries
1037 */
1038static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001039 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001040 x509_crl_entry *entry )
1041{
Paul Bakker23986e52011-04-24 08:57:21 +00001042 int ret;
1043 size_t entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001044 x509_crl_entry *cur_entry = entry;
1045
1046 if( *p == end )
1047 return( 0 );
1048
Paul Bakker9be19372009-07-27 20:21:53 +00001049 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001050 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1051 {
1052 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
1053 return( 0 );
1054
1055 return( ret );
1056 }
1057
Paul Bakker9be19372009-07-27 20:21:53 +00001058 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001059
1060 while( *p < end )
1061 {
Paul Bakker23986e52011-04-24 08:57:21 +00001062 size_t len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001063 const unsigned char *end2;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001064
1065 if( ( ret = asn1_get_tag( p, end, &len2,
1066 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1067 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001068 return( ret );
1069 }
1070
Paul Bakker9be19372009-07-27 20:21:53 +00001071 cur_entry->raw.tag = **p;
1072 cur_entry->raw.p = *p;
1073 cur_entry->raw.len = len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001074 end2 = *p + len2;
Paul Bakker9be19372009-07-27 20:21:53 +00001075
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001076 if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001077 return( ret );
1078
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001079 if( ( ret = x509_get_time( p, end2, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001080 return( ret );
1081
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001082 if( ( ret = x509_get_crl_entry_ext( p, end2, &cur_entry->entry_ext ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001083 return( ret );
1084
Paul Bakker74111d32011-01-15 16:57:55 +00001085 if ( *p < end )
1086 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001087 cur_entry->next = malloc( sizeof( x509_crl_entry ) );
Paul Bakkerb15b8512012-01-13 13:44:06 +00001088
1089 if( cur_entry->next == NULL )
1090 return( POLARSSL_ERR_X509_MALLOC_FAILED );
1091
Paul Bakkerd98030e2009-05-02 15:13:40 +00001092 cur_entry = cur_entry->next;
1093 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
1094 }
1095 }
1096
1097 return( 0 );
1098}
1099
Paul Bakker27d66162010-03-17 06:56:01 +00001100static int x509_get_sig_alg( const x509_buf *sig_oid, int *sig_alg )
1101{
1102 if( sig_oid->len == 9 &&
1103 memcmp( sig_oid->p, OID_PKCS1, 8 ) == 0 )
1104 {
1105 if( sig_oid->p[8] >= 2 && sig_oid->p[8] <= 5 )
1106 {
1107 *sig_alg = sig_oid->p[8];
1108 return( 0 );
1109 }
1110
1111 if ( sig_oid->p[8] >= 11 && sig_oid->p[8] <= 14 )
1112 {
1113 *sig_alg = sig_oid->p[8];
1114 return( 0 );
1115 }
1116
1117 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1118 }
Paul Bakker400ff6f2011-02-20 10:40:16 +00001119 if( sig_oid->len == 5 &&
1120 memcmp( sig_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
1121 {
1122 *sig_alg = SIG_RSA_SHA1;
1123 return( 0 );
1124 }
Paul Bakker27d66162010-03-17 06:56:01 +00001125
1126 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1127}
1128
Paul Bakkerd98030e2009-05-02 15:13:40 +00001129/*
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001130 * Parse and fill a single X.509 certificate in DER format
Paul Bakker5121ce52009-01-03 21:22:43 +00001131 */
Paul Bakkerd6d41092013-06-13 09:00:25 +02001132int x509parse_crt_der_core( x509_cert *crt, const unsigned char *buf,
1133 size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001134{
Paul Bakker23986e52011-04-24 08:57:21 +00001135 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001136 size_t len;
Paul Bakkerb00ca422012-09-25 12:10:00 +00001137 unsigned char *p, *end, *crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001138
Paul Bakker320a4b52009-03-28 18:52:39 +00001139 /*
1140 * Check for valid input
1141 */
1142 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001143 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker320a4b52009-03-28 18:52:39 +00001144
Paul Bakker96743fc2011-02-12 14:30:57 +00001145 p = (unsigned char *) malloc( len = buflen );
1146
1147 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001148 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001149
1150 memcpy( p, buf, buflen );
1151
1152 buflen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001153
1154 crt->raw.p = p;
1155 crt->raw.len = len;
1156 end = p + len;
1157
1158 /*
1159 * Certificate ::= SEQUENCE {
1160 * tbsCertificate TBSCertificate,
1161 * signatureAlgorithm AlgorithmIdentifier,
1162 * signatureValue BIT STRING }
1163 */
1164 if( ( ret = asn1_get_tag( &p, end, &len,
1165 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1166 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001167 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001168 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001169 }
1170
Paul Bakkerb00ca422012-09-25 12:10:00 +00001171 if( len > (size_t) ( end - p ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001172 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001173 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001174 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001175 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001176 }
Paul Bakkerb00ca422012-09-25 12:10:00 +00001177 crt_end = p + len;
Paul Bakkerd6d41092013-06-13 09:00:25 +02001178
Paul Bakker5121ce52009-01-03 21:22:43 +00001179 /*
1180 * TBSCertificate ::= SEQUENCE {
1181 */
1182 crt->tbs.p = p;
1183
1184 if( ( ret = asn1_get_tag( &p, end, &len,
1185 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1186 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001187 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001188 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001189 }
1190
1191 end = p + len;
1192 crt->tbs.len = end - crt->tbs.p;
1193
1194 /*
1195 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1196 *
1197 * CertificateSerialNumber ::= INTEGER
1198 *
1199 * signature AlgorithmIdentifier
1200 */
1201 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1202 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1203 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
1204 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001205 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001206 return( ret );
1207 }
1208
1209 crt->version++;
1210
1211 if( crt->version > 3 )
1212 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001213 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001214 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001215 }
1216
Paul Bakker27d66162010-03-17 06:56:01 +00001217 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_alg ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001218 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001219 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001220 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001221 }
1222
1223 /*
1224 * issuer Name
1225 */
1226 crt->issuer_raw.p = p;
1227
1228 if( ( ret = asn1_get_tag( &p, end, &len,
1229 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1230 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001231 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001232 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001233 }
1234
1235 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1236 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001237 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001238 return( ret );
1239 }
1240
1241 crt->issuer_raw.len = p - crt->issuer_raw.p;
1242
1243 /*
1244 * Validity ::= SEQUENCE {
1245 * notBefore Time,
1246 * notAfter Time }
1247 *
1248 */
1249 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1250 &crt->valid_to ) ) != 0 )
1251 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001252 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001253 return( ret );
1254 }
1255
1256 /*
1257 * subject Name
1258 */
1259 crt->subject_raw.p = p;
1260
1261 if( ( ret = asn1_get_tag( &p, end, &len,
1262 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1263 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001264 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001265 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001266 }
1267
Paul Bakkercefb3962012-06-27 11:51:09 +00001268 if( len && ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001269 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001270 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001271 return( ret );
1272 }
1273
1274 crt->subject_raw.len = p - crt->subject_raw.p;
1275
1276 /*
1277 * SubjectPublicKeyInfo ::= SEQUENCE
1278 * algorithm AlgorithmIdentifier,
1279 * subjectPublicKey BIT STRING }
1280 */
1281 if( ( ret = asn1_get_tag( &p, end, &len,
1282 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1283 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001284 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001285 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001286 }
1287
1288 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1289 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1290 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001291 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001292 return( ret );
1293 }
1294
1295 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1296 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001297 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001298 return( ret );
1299 }
1300
1301 crt->rsa.len = mpi_size( &crt->rsa.N );
1302
1303 /*
1304 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1305 * -- If present, version shall be v2 or v3
1306 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1307 * -- If present, version shall be v2 or v3
1308 * extensions [3] EXPLICIT Extensions OPTIONAL
1309 * -- If present, version shall be v3
1310 */
1311 if( crt->version == 2 || crt->version == 3 )
1312 {
1313 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1314 if( ret != 0 )
1315 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001316 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001317 return( ret );
1318 }
1319 }
1320
1321 if( crt->version == 2 || crt->version == 3 )
1322 {
1323 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1324 if( ret != 0 )
1325 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001326 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001327 return( ret );
1328 }
1329 }
1330
1331 if( crt->version == 3 )
1332 {
Paul Bakker74111d32011-01-15 16:57:55 +00001333 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001334 if( ret != 0 )
1335 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001336 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001337 return( ret );
1338 }
1339 }
1340
1341 if( p != end )
1342 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001343 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001344 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001345 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001346 }
1347
Paul Bakkerb00ca422012-09-25 12:10:00 +00001348 end = crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001349
1350 /*
1351 * signatureAlgorithm AlgorithmIdentifier,
1352 * signatureValue BIT STRING
1353 */
1354 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1355 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001356 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001357 return( ret );
1358 }
1359
Paul Bakker535e97d2012-08-23 10:49:55 +00001360 if( crt->sig_oid1.len != crt->sig_oid2.len ||
1361 memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001362 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001363 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001364 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001365 }
1366
1367 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1368 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001369 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001370 return( ret );
1371 }
1372
1373 if( p != end )
1374 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001375 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001376 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001377 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001378 }
1379
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001380 return( 0 );
1381}
1382
1383/*
Paul Bakkerd6d41092013-06-13 09:00:25 +02001384 * Parse one X.509 certificate in DER format from a buffer and add them to a
1385 * chained list
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001386 */
Paul Bakkerd6d41092013-06-13 09:00:25 +02001387int x509parse_crt_der( x509_cert *chain, const unsigned char *buf, size_t buflen )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001388{
Paul Bakkerd6d41092013-06-13 09:00:25 +02001389 int ret;
1390 x509_cert *crt = chain, *prev = NULL;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001391
1392 /*
1393 * Check for valid input
1394 */
1395 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001396 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001397
1398 while( crt->version != 0 && crt->next != NULL )
1399 {
1400 prev = crt;
1401 crt = crt->next;
1402 }
1403
1404 /*
1405 * Add new certificate on the end of the chain if needed.
1406 */
1407 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001408 {
1409 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1410
Paul Bakker7d06ad22009-05-02 15:53:56 +00001411 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001412 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker320a4b52009-03-28 18:52:39 +00001413
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001414 prev = crt;
Paul Bakker7d06ad22009-05-02 15:53:56 +00001415 crt = crt->next;
1416 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001417 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001418
Paul Bakkerd6d41092013-06-13 09:00:25 +02001419 if( ( ret = x509parse_crt_der_core( crt, buf, buflen ) ) != 0 )
1420 {
1421 if( prev )
1422 prev->next = NULL;
1423
1424 if( crt != chain )
1425 free( crt );
1426
1427 return( ret );
1428 }
1429
1430 return( 0 );
1431}
1432
1433/*
1434 * Parse one or more PEM certificates from a buffer and add them to the chained list
1435 */
1436int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
1437{
1438 int ret, success = 0, first_error = 0, total_failed = 0;
1439 int buf_format = X509_FORMAT_DER;
1440
1441 /*
1442 * Check for valid input
1443 */
1444 if( chain == NULL || buf == NULL )
1445 return( POLARSSL_ERR_X509_INVALID_INPUT );
1446
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001447 /*
1448 * Determine buffer content. Buffer contains either one DER certificate or
1449 * one or more PEM certificates.
1450 */
1451#if defined(POLARSSL_PEM_C)
Paul Bakkereae09db2013-06-06 12:35:54 +02001452 if( strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001453 buf_format = X509_FORMAT_PEM;
1454#endif
1455
1456 if( buf_format == X509_FORMAT_DER )
Paul Bakkerd6d41092013-06-13 09:00:25 +02001457 return x509parse_crt_der( chain, buf, buflen );
1458
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001459#if defined(POLARSSL_PEM_C)
1460 if( buf_format == X509_FORMAT_PEM )
1461 {
1462 pem_context pem;
1463
1464 while( buflen > 0 )
1465 {
1466 size_t use_len;
1467 pem_init( &pem );
1468
1469 ret = pem_read_buffer( &pem,
1470 "-----BEGIN CERTIFICATE-----",
1471 "-----END CERTIFICATE-----",
1472 buf, NULL, 0, &use_len );
1473
1474 if( ret == 0 )
1475 {
1476 /*
1477 * Was PEM encoded
1478 */
1479 buflen -= use_len;
1480 buf += use_len;
1481 }
Paul Bakker64171862013-06-06 15:01:18 +02001482 else if( ret == POLARSSL_ERR_PEM_BAD_INPUT_DATA )
1483 {
1484 return( ret );
1485 }
Paul Bakker9255e832013-06-06 14:58:28 +02001486 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001487 {
1488 pem_free( &pem );
1489
Paul Bakker64171862013-06-06 15:01:18 +02001490 /*
1491 * PEM header and footer were found
1492 */
1493 buflen -= use_len;
1494 buf += use_len;
1495
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001496 if( first_error == 0 )
1497 first_error = ret;
1498
1499 continue;
1500 }
1501 else
1502 break;
1503
Paul Bakkerd6d41092013-06-13 09:00:25 +02001504 ret = x509parse_crt_der( chain, pem.buf, pem.buflen );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001505
1506 pem_free( &pem );
1507
1508 if( ret != 0 )
1509 {
1510 /*
Paul Bakkerd6d41092013-06-13 09:00:25 +02001511 * Quit parsing on a memory error
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001512 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001513 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001514 return( ret );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001515
1516 if( first_error == 0 )
1517 first_error = ret;
1518
Paul Bakkerd6d41092013-06-13 09:00:25 +02001519 total_failed++;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001520 continue;
1521 }
1522
1523 success = 1;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001524 }
1525 }
1526#endif
1527
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001528 if( success )
Paul Bakker69e095c2011-12-10 21:55:01 +00001529 return( total_failed );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001530 else if( first_error )
1531 return( first_error );
1532 else
1533 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001534}
1535
1536/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001537 * Parse one or more CRLs and add them to the chained list
1538 */
Paul Bakker23986e52011-04-24 08:57:21 +00001539int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001540{
Paul Bakker23986e52011-04-24 08:57:21 +00001541 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001542 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001543 unsigned char *p, *end;
1544 x509_crl *crl;
Paul Bakker96743fc2011-02-12 14:30:57 +00001545#if defined(POLARSSL_PEM_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00001546 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001547 pem_context pem;
1548#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001549
1550 crl = chain;
1551
1552 /*
1553 * Check for valid input
1554 */
1555 if( crl == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001556 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001557
1558 while( crl->version != 0 && crl->next != NULL )
1559 crl = crl->next;
1560
1561 /*
1562 * Add new CRL on the end of the chain if needed.
1563 */
1564 if ( crl->version != 0 && crl->next == NULL)
1565 {
1566 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1567
Paul Bakker7d06ad22009-05-02 15:53:56 +00001568 if( crl->next == NULL )
1569 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001570 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001571 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001572 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001573
Paul Bakker7d06ad22009-05-02 15:53:56 +00001574 crl = crl->next;
1575 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001576 }
1577
Paul Bakker96743fc2011-02-12 14:30:57 +00001578#if defined(POLARSSL_PEM_C)
1579 pem_init( &pem );
1580 ret = pem_read_buffer( &pem,
1581 "-----BEGIN X509 CRL-----",
1582 "-----END X509 CRL-----",
1583 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001584
Paul Bakker96743fc2011-02-12 14:30:57 +00001585 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001586 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001587 /*
1588 * Was PEM encoded
1589 */
1590 buflen -= use_len;
1591 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001592
1593 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001594 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001595 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001596 p = pem.buf;
1597 pem.buf = NULL;
1598 len = pem.buflen;
1599 pem_free( &pem );
1600 }
Paul Bakker9255e832013-06-06 14:58:28 +02001601 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker96743fc2011-02-12 14:30:57 +00001602 {
1603 pem_free( &pem );
1604 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001605 }
1606 else
1607 {
1608 /*
1609 * nope, copy the raw DER data
1610 */
1611 p = (unsigned char *) malloc( len = buflen );
1612
1613 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001614 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001615
1616 memcpy( p, buf, buflen );
1617
1618 buflen = 0;
1619 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001620#else
1621 p = (unsigned char *) malloc( len = buflen );
1622
1623 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001624 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001625
1626 memcpy( p, buf, buflen );
1627
1628 buflen = 0;
1629#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001630
1631 crl->raw.p = p;
1632 crl->raw.len = len;
1633 end = p + len;
1634
1635 /*
1636 * CertificateList ::= SEQUENCE {
1637 * tbsCertList TBSCertList,
1638 * signatureAlgorithm AlgorithmIdentifier,
1639 * signatureValue BIT STRING }
1640 */
1641 if( ( ret = asn1_get_tag( &p, end, &len,
1642 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1643 {
1644 x509_crl_free( crl );
1645 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1646 }
1647
Paul Bakker23986e52011-04-24 08:57:21 +00001648 if( len != (size_t) ( end - p ) )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001649 {
1650 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001651 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001652 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1653 }
1654
1655 /*
1656 * TBSCertList ::= SEQUENCE {
1657 */
1658 crl->tbs.p = p;
1659
1660 if( ( ret = asn1_get_tag( &p, end, &len,
1661 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1662 {
1663 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001664 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001665 }
1666
1667 end = p + len;
1668 crl->tbs.len = end - crl->tbs.p;
1669
1670 /*
1671 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1672 * -- if present, MUST be v2
1673 *
1674 * signature AlgorithmIdentifier
1675 */
Paul Bakker3329d1f2011-10-12 09:55:01 +00001676 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
Paul Bakkerd98030e2009-05-02 15:13:40 +00001677 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1678 {
1679 x509_crl_free( crl );
1680 return( ret );
1681 }
1682
1683 crl->version++;
1684
1685 if( crl->version > 2 )
1686 {
1687 x509_crl_free( crl );
1688 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1689 }
1690
Paul Bakker27d66162010-03-17 06:56:01 +00001691 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_alg ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001692 {
1693 x509_crl_free( crl );
1694 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1695 }
1696
1697 /*
1698 * issuer Name
1699 */
1700 crl->issuer_raw.p = p;
1701
1702 if( ( ret = asn1_get_tag( &p, end, &len,
1703 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1704 {
1705 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001706 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001707 }
1708
1709 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1710 {
1711 x509_crl_free( crl );
1712 return( ret );
1713 }
1714
1715 crl->issuer_raw.len = p - crl->issuer_raw.p;
1716
1717 /*
1718 * thisUpdate Time
1719 * nextUpdate Time OPTIONAL
1720 */
Paul Bakker91200182010-02-18 21:26:15 +00001721 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001722 {
1723 x509_crl_free( crl );
1724 return( ret );
1725 }
1726
Paul Bakker91200182010-02-18 21:26:15 +00001727 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001728 {
Paul Bakker9d781402011-05-09 16:17:09 +00001729 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001730 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker9d781402011-05-09 16:17:09 +00001731 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001732 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001733 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001734 x509_crl_free( crl );
1735 return( ret );
1736 }
1737 }
1738
1739 /*
1740 * revokedCertificates SEQUENCE OF SEQUENCE {
1741 * userCertificate CertificateSerialNumber,
1742 * revocationDate Time,
1743 * crlEntryExtensions Extensions OPTIONAL
1744 * -- if present, MUST be v2
1745 * } OPTIONAL
1746 */
1747 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1748 {
1749 x509_crl_free( crl );
1750 return( ret );
1751 }
1752
1753 /*
1754 * crlExtensions EXPLICIT Extensions OPTIONAL
1755 * -- if present, MUST be v2
1756 */
1757 if( crl->version == 2 )
1758 {
1759 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1760
1761 if( ret != 0 )
1762 {
1763 x509_crl_free( crl );
1764 return( ret );
1765 }
1766 }
1767
1768 if( p != end )
1769 {
1770 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001771 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001772 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1773 }
1774
1775 end = crl->raw.p + crl->raw.len;
1776
1777 /*
1778 * signatureAlgorithm AlgorithmIdentifier,
1779 * signatureValue BIT STRING
1780 */
1781 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1782 {
1783 x509_crl_free( crl );
1784 return( ret );
1785 }
1786
Paul Bakker535e97d2012-08-23 10:49:55 +00001787 if( crl->sig_oid1.len != crl->sig_oid2.len ||
1788 memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001789 {
1790 x509_crl_free( crl );
1791 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1792 }
1793
1794 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1795 {
1796 x509_crl_free( crl );
1797 return( ret );
1798 }
1799
1800 if( p != end )
1801 {
1802 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001803 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001804 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1805 }
1806
1807 if( buflen > 0 )
1808 {
1809 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1810
Paul Bakker7d06ad22009-05-02 15:53:56 +00001811 if( crl->next == NULL )
1812 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001813 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001814 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001815 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001816
Paul Bakker7d06ad22009-05-02 15:53:56 +00001817 crl = crl->next;
1818 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001819
1820 return( x509parse_crl( crl, buf, buflen ) );
1821 }
1822
1823 return( 0 );
1824}
1825
Paul Bakker335db3f2011-04-25 15:28:35 +00001826#if defined(POLARSSL_FS_IO)
Paul Bakkerd98030e2009-05-02 15:13:40 +00001827/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001828 * Load all data from a file into a given buffer.
1829 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001830int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001831{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001832 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001833
Paul Bakkerd98030e2009-05-02 15:13:40 +00001834 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001835 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001836
Paul Bakkerd98030e2009-05-02 15:13:40 +00001837 fseek( f, 0, SEEK_END );
1838 *n = (size_t) ftell( f );
1839 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001840
Paul Bakkerd98030e2009-05-02 15:13:40 +00001841 if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001842 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001843
Paul Bakkerd98030e2009-05-02 15:13:40 +00001844 if( fread( *buf, 1, *n, f ) != *n )
1845 {
1846 fclose( f );
1847 free( *buf );
Paul Bakker69e095c2011-12-10 21:55:01 +00001848 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001849 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001850
Paul Bakkerd98030e2009-05-02 15:13:40 +00001851 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001852
Paul Bakkerd98030e2009-05-02 15:13:40 +00001853 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001854
Paul Bakkerd98030e2009-05-02 15:13:40 +00001855 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001856}
1857
1858/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001859 * Load one or more certificates and add them to the chained list
1860 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001861int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001862{
1863 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001864 size_t n;
1865 unsigned char *buf;
1866
Paul Bakker69e095c2011-12-10 21:55:01 +00001867 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1868 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001869
Paul Bakker69e095c2011-12-10 21:55:01 +00001870 ret = x509parse_crt( chain, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001871
1872 memset( buf, 0, n + 1 );
1873 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001874
1875 return( ret );
1876}
1877
Paul Bakker8d914582012-06-04 12:46:42 +00001878int x509parse_crtpath( x509_cert *chain, const char *path )
1879{
1880 int ret = 0;
1881#if defined(_WIN32)
Paul Bakker3338b792012-10-01 21:13:10 +00001882 int w_ret;
1883 WCHAR szDir[MAX_PATH];
1884 char filename[MAX_PATH];
1885 char *p;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001886 int len = strlen( path );
Paul Bakker3338b792012-10-01 21:13:10 +00001887
Paul Bakker97872ac2012-11-02 12:53:26 +00001888 WIN32_FIND_DATAW file_data;
Paul Bakker8d914582012-06-04 12:46:42 +00001889 HANDLE hFind;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001890
1891 if( len > MAX_PATH - 3 )
1892 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker8d914582012-06-04 12:46:42 +00001893
Paul Bakker3338b792012-10-01 21:13:10 +00001894 memset( szDir, 0, sizeof(szDir) );
1895 memset( filename, 0, MAX_PATH );
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001896 memcpy( filename, path, len );
1897 filename[len++] = '\\';
1898 p = filename + len;
1899 filename[len++] = '*';
Paul Bakker3338b792012-10-01 21:13:10 +00001900
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001901 w_ret = MultiByteToWideChar( CP_ACP, 0, path, len, szDir, MAX_PATH - 3 );
Paul Bakker8d914582012-06-04 12:46:42 +00001902
Paul Bakker97872ac2012-11-02 12:53:26 +00001903 hFind = FindFirstFileW( szDir, &file_data );
Paul Bakker8d914582012-06-04 12:46:42 +00001904 if (hFind == INVALID_HANDLE_VALUE)
1905 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1906
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001907 len = MAX_PATH - len;
Paul Bakker8d914582012-06-04 12:46:42 +00001908 do
1909 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001910 memset( p, 0, len );
Paul Bakker3338b792012-10-01 21:13:10 +00001911
Paul Bakkere4791f32012-06-04 21:29:15 +00001912 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
Paul Bakker8d914582012-06-04 12:46:42 +00001913 continue;
1914
Paul Bakker3338b792012-10-01 21:13:10 +00001915 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
1916 lstrlenW(file_data.cFileName),
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001917 p, len - 1,
1918 NULL, NULL );
Paul Bakker8d914582012-06-04 12:46:42 +00001919
Paul Bakker3338b792012-10-01 21:13:10 +00001920 w_ret = x509parse_crtfile( chain, filename );
1921 if( w_ret < 0 )
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001922 {
1923 ret = w_ret;
1924 goto cleanup;
1925 }
Paul Bakker3338b792012-10-01 21:13:10 +00001926
1927 ret += w_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001928 }
Paul Bakker97872ac2012-11-02 12:53:26 +00001929 while( FindNextFileW( hFind, &file_data ) != 0 );
Paul Bakker8d914582012-06-04 12:46:42 +00001930
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001931 if (GetLastError() != ERROR_NO_MORE_FILES)
1932 ret = POLARSSL_ERR_X509_FILE_IO_ERROR;
Paul Bakker8d914582012-06-04 12:46:42 +00001933
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001934cleanup:
Paul Bakker8d914582012-06-04 12:46:42 +00001935 FindClose( hFind );
1936#else
1937 int t_ret;
1938 struct dirent *entry;
1939 char entry_name[255];
1940 DIR *dir = opendir( path );
1941
1942 if( dir == NULL)
1943 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1944
1945 while( ( entry = readdir( dir ) ) != NULL )
1946 {
1947 if( entry->d_type != DT_REG )
1948 continue;
1949
1950 snprintf( entry_name, sizeof(entry_name), "%s/%s", path, entry->d_name );
1951 t_ret = x509parse_crtfile( chain, entry_name );
1952 if( t_ret < 0 )
Paul Bakker97872ac2012-11-02 12:53:26 +00001953 {
1954 ret = t_ret;
1955 break;
1956 }
Paul Bakker8d914582012-06-04 12:46:42 +00001957
1958 ret += t_ret;
1959 }
1960 closedir( dir );
1961#endif
1962
1963 return( ret );
1964}
1965
Paul Bakkerd98030e2009-05-02 15:13:40 +00001966/*
1967 * Load one or more CRLs and add them to the chained list
1968 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001969int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001970{
1971 int ret;
1972 size_t n;
1973 unsigned char *buf;
1974
Paul Bakker69e095c2011-12-10 21:55:01 +00001975 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1976 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001977
Paul Bakker27fdf462011-06-09 13:55:13 +00001978 ret = x509parse_crl( chain, buf, n );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001979
1980 memset( buf, 0, n + 1 );
1981 free( buf );
1982
1983 return( ret );
1984}
1985
Paul Bakker5121ce52009-01-03 21:22:43 +00001986/*
Paul Bakker335db3f2011-04-25 15:28:35 +00001987 * Load and parse a private RSA key
1988 */
1989int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
1990{
1991 int ret;
1992 size_t n;
1993 unsigned char *buf;
1994
Paul Bakker69e095c2011-12-10 21:55:01 +00001995 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1996 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00001997
1998 if( pwd == NULL )
Paul Bakker27fdf462011-06-09 13:55:13 +00001999 ret = x509parse_key( rsa, buf, n, NULL, 0 );
Paul Bakker335db3f2011-04-25 15:28:35 +00002000 else
Paul Bakker27fdf462011-06-09 13:55:13 +00002001 ret = x509parse_key( rsa, buf, n,
Paul Bakker335db3f2011-04-25 15:28:35 +00002002 (unsigned char *) pwd, strlen( pwd ) );
2003
2004 memset( buf, 0, n + 1 );
2005 free( buf );
2006
2007 return( ret );
2008}
2009
2010/*
2011 * Load and parse a public RSA key
2012 */
2013int x509parse_public_keyfile( rsa_context *rsa, const char *path )
2014{
2015 int ret;
2016 size_t n;
2017 unsigned char *buf;
2018
Paul Bakker69e095c2011-12-10 21:55:01 +00002019 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2020 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002021
Paul Bakker27fdf462011-06-09 13:55:13 +00002022 ret = x509parse_public_key( rsa, buf, n );
Paul Bakker335db3f2011-04-25 15:28:35 +00002023
2024 memset( buf, 0, n + 1 );
2025 free( buf );
2026
2027 return( ret );
2028}
2029#endif /* POLARSSL_FS_IO */
2030
2031/*
Paul Bakker65a19092013-06-06 21:14:58 +02002032 * Parse a PKCS#1 encoded private RSA key
Paul Bakker5121ce52009-01-03 21:22:43 +00002033 */
Paul Bakker65a19092013-06-06 21:14:58 +02002034static int x509parse_key_pkcs1_der( rsa_context *rsa,
2035 const unsigned char *key,
2036 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +00002037{
Paul Bakker23986e52011-04-24 08:57:21 +00002038 int ret;
2039 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00002040 unsigned char *p, *end;
Paul Bakkered56b222011-07-13 11:26:43 +00002041
Paul Bakker96743fc2011-02-12 14:30:57 +00002042 p = (unsigned char *) key;
Paul Bakker96743fc2011-02-12 14:30:57 +00002043 end = p + keylen;
2044
Paul Bakker5121ce52009-01-03 21:22:43 +00002045 /*
Paul Bakker65a19092013-06-06 21:14:58 +02002046 * This function parses the RSAPrivateKey (PKCS#1)
Paul Bakkered56b222011-07-13 11:26:43 +00002047 *
Paul Bakker5121ce52009-01-03 21:22:43 +00002048 * RSAPrivateKey ::= SEQUENCE {
2049 * version Version,
2050 * modulus INTEGER, -- n
2051 * publicExponent INTEGER, -- e
2052 * privateExponent INTEGER, -- d
2053 * prime1 INTEGER, -- p
2054 * prime2 INTEGER, -- q
2055 * exponent1 INTEGER, -- d mod (p-1)
2056 * exponent2 INTEGER, -- d mod (q-1)
2057 * coefficient INTEGER, -- (inverse of q) mod p
2058 * otherPrimeInfos OtherPrimeInfos OPTIONAL
2059 * }
2060 */
2061 if( ( ret = asn1_get_tag( &p, end, &len,
2062 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2063 {
Paul Bakker9d781402011-05-09 16:17:09 +00002064 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002065 }
2066
2067 end = p + len;
2068
2069 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2070 {
Paul Bakker9d781402011-05-09 16:17:09 +00002071 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002072 }
2073
2074 if( rsa->ver != 0 )
2075 {
Paul Bakker9d781402011-05-09 16:17:09 +00002076 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002077 }
2078
2079 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
2080 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
2081 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
2082 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
2083 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
2084 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
2085 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
2086 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
2087 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002088 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002089 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002090 }
2091
2092 rsa->len = mpi_size( &rsa->N );
2093
2094 if( p != end )
2095 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002096 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002097 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00002098 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002099 }
2100
2101 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2102 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002103 rsa_free( rsa );
2104 return( ret );
2105 }
2106
Paul Bakker65a19092013-06-06 21:14:58 +02002107 return( 0 );
2108}
2109
2110/*
2111 * Parse an unencrypted PKCS#8 encoded private RSA key
2112 */
2113static int x509parse_key_pkcs8_unencrypted_der(
2114 rsa_context *rsa,
2115 const unsigned char *key,
2116 size_t keylen )
2117{
2118 int ret;
2119 size_t len;
2120 unsigned char *p, *end;
2121 x509_buf pk_alg_oid;
2122
2123 p = (unsigned char *) key;
2124 end = p + keylen;
2125
2126 /*
2127 * This function parses the PrivatKeyInfo object (PKCS#8)
2128 *
2129 * PrivateKeyInfo ::= SEQUENCE {
2130 * version Version,
2131 * algorithm AlgorithmIdentifier,
2132 * PrivateKey BIT STRING
2133 * }
2134 *
2135 * AlgorithmIdentifier ::= SEQUENCE {
2136 * algorithm OBJECT IDENTIFIER,
2137 * parameters ANY DEFINED BY algorithm OPTIONAL
2138 * }
2139 *
2140 * The PrivateKey BIT STRING is a PKCS#1 RSAPrivateKey
2141 */
2142 if( ( ret = asn1_get_tag( &p, end, &len,
2143 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2144 {
2145 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2146 }
2147
2148 end = p + len;
2149
2150 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2151 {
2152 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2153 }
2154
2155 if( rsa->ver != 0 )
2156 {
2157 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2158 }
2159
2160 if( ( ret = x509_get_alg( &p, end, &pk_alg_oid ) ) != 0 )
2161 {
2162 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2163 }
2164
2165 /*
2166 * only RSA keys handled at this time
2167 */
2168 if( pk_alg_oid.len != 9 ||
2169 memcmp( pk_alg_oid.p, OID_PKCS1_RSA, 9 ) != 0 )
2170 {
2171 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
2172 }
2173
2174 /*
2175 * Get the OCTET STRING and parse the PKCS#1 format inside
2176 */
2177 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2178 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2179
2180 if( ( end - p ) < 1 )
2181 {
2182 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
2183 POLARSSL_ERR_ASN1_OUT_OF_DATA );
2184 }
2185
2186 end = p + len;
2187
2188 if( ( ret = x509parse_key_pkcs1_der( rsa, p, end - p ) ) != 0 )
2189 return( ret );
2190
2191 return( 0 );
2192}
2193
2194/*
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002195 * Parse an unencrypted PKCS#8 encoded private RSA key
2196 */
2197static int x509parse_key_pkcs8_encrypted_der(
2198 rsa_context *rsa,
2199 const unsigned char *key,
2200 size_t keylen,
2201 const unsigned char *pwd,
2202 size_t pwdlen )
2203{
2204 int ret;
2205 size_t len;
2206 unsigned char *p, *end, *end2;
2207 x509_buf pbe_alg_oid, pbe_params;
2208 unsigned char buf[2048];
2209
2210 memset(buf, 0, 2048);
2211
2212 p = (unsigned char *) key;
2213 end = p + keylen;
2214
2215 /*
2216 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
2217 *
2218 * EncryptedPrivateKeyInfo ::= SEQUENCE {
2219 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
2220 * encryptedData EncryptedData
2221 * }
2222 *
2223 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
2224 *
2225 * EncryptedData ::= OCTET STRING
2226 *
2227 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
2228 */
2229 if( ( ret = asn1_get_tag( &p, end, &len,
2230 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2231 {
2232 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2233 }
2234
2235 end = p + len;
2236
2237 if( ( ret = asn1_get_tag( &p, end, &len,
2238 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2239 {
2240 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2241 }
2242
2243 end2 = p + len;
2244
2245 if( ( ret = asn1_get_tag( &p, end, &pbe_alg_oid.len, ASN1_OID ) ) != 0 )
2246 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2247
2248 pbe_alg_oid.p = p;
2249 p += pbe_alg_oid.len;
2250
2251 /*
2252 * Store the algorithm parameters
2253 */
2254 pbe_params.p = p;
2255 pbe_params.len = end2 - p;
2256 p += pbe_params.len;
2257
2258 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2259 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2260
2261 // buf has been sized to 2048 bytes
2262 if( len > 2048 )
2263 return( POLARSSL_ERR_X509_INVALID_INPUT );
2264
2265 /*
2266 * Decrypt EncryptedData with appropriate PDE
2267 */
2268 if( OID_CMP( OID_PKCS12_PBE_SHA1_DES3_EDE_CBC, &pbe_alg_oid ) )
2269 {
2270 if( ( ret = pkcs12_pbe_sha1_des3_ede_cbc( &pbe_params,
2271 PKCS12_PBE_DECRYPT,
2272 pwd, pwdlen,
2273 p, len, buf ) ) != 0 )
2274 {
2275 return( ret );
2276 }
2277 }
2278 else if( OID_CMP( OID_PKCS12_PBE_SHA1_DES2_EDE_CBC, &pbe_alg_oid ) )
2279 {
2280 if( ( ret = pkcs12_pbe_sha1_des2_ede_cbc( &pbe_params,
2281 PKCS12_PBE_DECRYPT,
2282 pwd, pwdlen,
2283 p, len, buf ) ) != 0 )
2284 {
2285 return( ret );
2286 }
2287 }
2288 else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) )
2289 {
2290 if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params,
2291 PKCS12_PBE_DECRYPT,
2292 pwd, pwdlen,
2293 p, len, buf ) ) != 0 )
2294 {
2295 return( ret );
2296 }
2297 }
2298 else
2299 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
2300
2301 return x509parse_key_pkcs8_unencrypted_der( rsa, buf, len );
2302}
2303
2304/*
Paul Bakker65a19092013-06-06 21:14:58 +02002305 * Parse a private RSA key
2306 */
2307int x509parse_key( rsa_context *rsa, const unsigned char *key, size_t keylen,
2308 const unsigned char *pwd, size_t pwdlen )
2309{
2310 int ret;
2311
Paul Bakker96743fc2011-02-12 14:30:57 +00002312#if defined(POLARSSL_PEM_C)
Paul Bakker65a19092013-06-06 21:14:58 +02002313 size_t len;
2314 pem_context pem;
2315
2316 pem_init( &pem );
2317 ret = pem_read_buffer( &pem,
2318 "-----BEGIN RSA PRIVATE KEY-----",
2319 "-----END RSA PRIVATE KEY-----",
2320 key, pwd, pwdlen, &len );
2321 if( ret == 0 )
2322 {
2323 if( ( ret = x509parse_key_pkcs1_der( rsa, pem.buf, pem.buflen ) ) != 0 )
2324 {
2325 rsa_free( rsa );
2326 }
2327
2328 pem_free( &pem );
2329 return( ret );
2330 }
2331 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2332 {
2333 pem_free( &pem );
2334 return( ret );
2335 }
2336
2337 ret = pem_read_buffer( &pem,
2338 "-----BEGIN PRIVATE KEY-----",
2339 "-----END PRIVATE KEY-----",
2340 key, NULL, 0, &len );
2341 if( ret == 0 )
2342 {
2343 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa,
2344 pem.buf, pem.buflen ) ) != 0 )
2345 {
2346 rsa_free( rsa );
2347 }
2348
2349 pem_free( &pem );
2350 return( ret );
2351 }
2352 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2353 {
2354 pem_free( &pem );
2355 return( ret );
2356 }
2357
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002358 ret = pem_read_buffer( &pem,
2359 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
2360 "-----END ENCRYPTED PRIVATE KEY-----",
2361 key, NULL, 0, &len );
2362 if( ret == 0 )
2363 {
2364 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa,
2365 pem.buf, pem.buflen,
2366 pwd, pwdlen ) ) != 0 )
2367 {
2368 rsa_free( rsa );
2369 }
2370
2371 pem_free( &pem );
2372 return( ret );
2373 }
2374 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2375 {
2376 pem_free( &pem );
2377 return( ret );
2378 }
Paul Bakker65a19092013-06-06 21:14:58 +02002379#else
2380 ((void) pwd);
2381 ((void) pwdlen);
2382#endif /* POLARSSL_PEM_C */
2383
2384 // At this point we only know it's not a PEM formatted key. Could be any
2385 // of the known DER encoded private key formats
2386 //
2387 // We try the different DER format parsers to see if one passes without
2388 // error
2389 //
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002390 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa, key, keylen,
2391 pwd, pwdlen ) ) == 0 )
Paul Bakker65a19092013-06-06 21:14:58 +02002392 {
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002393 return( 0 );
Paul Bakker65a19092013-06-06 21:14:58 +02002394 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002395
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002396 rsa_free( rsa );
2397 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa, key, keylen ) ) == 0 )
2398 return( 0 );
2399
2400 rsa_free( rsa );
2401 if( ( ret = x509parse_key_pkcs1_der( rsa, key, keylen ) ) == 0 )
2402 return( 0 );
2403
2404 rsa_free( rsa );
2405 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00002406}
2407
2408/*
Paul Bakker53019ae2011-03-25 13:58:48 +00002409 * Parse a public RSA key
2410 */
Paul Bakker23986e52011-04-24 08:57:21 +00002411int x509parse_public_key( rsa_context *rsa, const unsigned char *key, size_t keylen )
Paul Bakker53019ae2011-03-25 13:58:48 +00002412{
Paul Bakker23986e52011-04-24 08:57:21 +00002413 int ret;
2414 size_t len;
Paul Bakker53019ae2011-03-25 13:58:48 +00002415 unsigned char *p, *end;
2416 x509_buf alg_oid;
2417#if defined(POLARSSL_PEM_C)
2418 pem_context pem;
2419
2420 pem_init( &pem );
2421 ret = pem_read_buffer( &pem,
2422 "-----BEGIN PUBLIC KEY-----",
2423 "-----END PUBLIC KEY-----",
2424 key, NULL, 0, &len );
2425
2426 if( ret == 0 )
2427 {
2428 /*
2429 * Was PEM encoded
2430 */
2431 keylen = pem.buflen;
2432 }
Paul Bakker9255e832013-06-06 14:58:28 +02002433 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker53019ae2011-03-25 13:58:48 +00002434 {
2435 pem_free( &pem );
2436 return( ret );
2437 }
2438
2439 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2440#else
2441 p = (unsigned char *) key;
2442#endif
2443 end = p + keylen;
2444
2445 /*
2446 * PublicKeyInfo ::= SEQUENCE {
2447 * algorithm AlgorithmIdentifier,
2448 * PublicKey BIT STRING
2449 * }
2450 *
2451 * AlgorithmIdentifier ::= SEQUENCE {
2452 * algorithm OBJECT IDENTIFIER,
2453 * parameters ANY DEFINED BY algorithm OPTIONAL
2454 * }
2455 *
2456 * RSAPublicKey ::= SEQUENCE {
2457 * modulus INTEGER, -- n
2458 * publicExponent INTEGER -- e
2459 * }
2460 */
2461
2462 if( ( ret = asn1_get_tag( &p, end, &len,
2463 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2464 {
2465#if defined(POLARSSL_PEM_C)
2466 pem_free( &pem );
2467#endif
2468 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002469 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002470 }
2471
2472 if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
2473 {
2474#if defined(POLARSSL_PEM_C)
2475 pem_free( &pem );
2476#endif
2477 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002478 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002479 }
2480
2481 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
2482 {
2483#if defined(POLARSSL_PEM_C)
2484 pem_free( &pem );
2485#endif
2486 rsa_free( rsa );
2487 return( ret );
2488 }
2489
2490 rsa->len = mpi_size( &rsa->N );
2491
2492#if defined(POLARSSL_PEM_C)
2493 pem_free( &pem );
2494#endif
2495
2496 return( 0 );
2497}
2498
Paul Bakkereaa89f82011-04-04 21:36:15 +00002499#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00002500/*
Paul Bakker1b57b062011-01-06 15:48:19 +00002501 * Parse DHM parameters
2502 */
Paul Bakker23986e52011-04-24 08:57:21 +00002503int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
Paul Bakker1b57b062011-01-06 15:48:19 +00002504{
Paul Bakker23986e52011-04-24 08:57:21 +00002505 int ret;
2506 size_t len;
Paul Bakker1b57b062011-01-06 15:48:19 +00002507 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00002508#if defined(POLARSSL_PEM_C)
2509 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00002510
Paul Bakker96743fc2011-02-12 14:30:57 +00002511 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00002512
Paul Bakker96743fc2011-02-12 14:30:57 +00002513 ret = pem_read_buffer( &pem,
2514 "-----BEGIN DH PARAMETERS-----",
2515 "-----END DH PARAMETERS-----",
2516 dhmin, NULL, 0, &dhminlen );
2517
2518 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00002519 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002520 /*
2521 * Was PEM encoded
2522 */
2523 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00002524 }
Paul Bakker9255e832013-06-06 14:58:28 +02002525 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00002526 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002527 pem_free( &pem );
2528 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002529 }
2530
Paul Bakker96743fc2011-02-12 14:30:57 +00002531 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
2532#else
2533 p = (unsigned char *) dhmin;
2534#endif
2535 end = p + dhminlen;
2536
Paul Bakker1b57b062011-01-06 15:48:19 +00002537 memset( dhm, 0, sizeof( dhm_context ) );
2538
Paul Bakker1b57b062011-01-06 15:48:19 +00002539 /*
2540 * DHParams ::= SEQUENCE {
2541 * prime INTEGER, -- P
2542 * generator INTEGER, -- g
2543 * }
2544 */
2545 if( ( ret = asn1_get_tag( &p, end, &len,
2546 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2547 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002548#if defined(POLARSSL_PEM_C)
2549 pem_free( &pem );
2550#endif
Paul Bakker9d781402011-05-09 16:17:09 +00002551 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002552 }
2553
2554 end = p + len;
2555
2556 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
2557 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
2558 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002559#if defined(POLARSSL_PEM_C)
2560 pem_free( &pem );
2561#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002562 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002563 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002564 }
2565
2566 if( p != end )
2567 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002568#if defined(POLARSSL_PEM_C)
2569 pem_free( &pem );
2570#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002571 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002572 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker1b57b062011-01-06 15:48:19 +00002573 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
2574 }
2575
Paul Bakker96743fc2011-02-12 14:30:57 +00002576#if defined(POLARSSL_PEM_C)
2577 pem_free( &pem );
2578#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002579
2580 return( 0 );
2581}
2582
Paul Bakker335db3f2011-04-25 15:28:35 +00002583#if defined(POLARSSL_FS_IO)
Paul Bakker1b57b062011-01-06 15:48:19 +00002584/*
2585 * Load and parse a private RSA key
2586 */
2587int x509parse_dhmfile( dhm_context *dhm, const char *path )
2588{
2589 int ret;
2590 size_t n;
2591 unsigned char *buf;
2592
Paul Bakker69e095c2011-12-10 21:55:01 +00002593 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
2594 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002595
Paul Bakker27fdf462011-06-09 13:55:13 +00002596 ret = x509parse_dhm( dhm, buf, n );
Paul Bakker1b57b062011-01-06 15:48:19 +00002597
2598 memset( buf, 0, n + 1 );
2599 free( buf );
2600
2601 return( ret );
2602}
Paul Bakker335db3f2011-04-25 15:28:35 +00002603#endif /* POLARSSL_FS_IO */
Paul Bakkereaa89f82011-04-04 21:36:15 +00002604#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00002605
Paul Bakker5121ce52009-01-03 21:22:43 +00002606#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002607#include <stdarg.h>
2608
2609#if !defined vsnprintf
2610#define vsnprintf _vsnprintf
2611#endif // vsnprintf
2612
2613/*
2614 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2615 * Result value is not size of buffer needed, but -1 if no fit is possible.
2616 *
2617 * This fuction tries to 'fix' this by at least suggesting enlarging the
2618 * size by 20.
2619 */
2620int compat_snprintf(char *str, size_t size, const char *format, ...)
2621{
2622 va_list ap;
2623 int res = -1;
2624
2625 va_start( ap, format );
2626
2627 res = vsnprintf( str, size, format, ap );
2628
2629 va_end( ap );
2630
2631 // No quick fix possible
2632 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00002633 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002634
2635 return res;
2636}
2637
2638#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002639#endif
2640
Paul Bakkerd98030e2009-05-02 15:13:40 +00002641#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2642
2643#define SAFE_SNPRINTF() \
2644{ \
2645 if( ret == -1 ) \
2646 return( -1 ); \
2647 \
Paul Bakker23986e52011-04-24 08:57:21 +00002648 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002649 p[n - 1] = '\0'; \
2650 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2651 } \
2652 \
Paul Bakker23986e52011-04-24 08:57:21 +00002653 n -= (unsigned int) ret; \
2654 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002655}
2656
Paul Bakker5121ce52009-01-03 21:22:43 +00002657/*
2658 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002659 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002660 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002661int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002662{
Paul Bakker23986e52011-04-24 08:57:21 +00002663 int ret;
2664 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002665 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002666 const x509_name *name;
Paul Bakker5121ce52009-01-03 21:22:43 +00002667 char s[128], *p;
2668
2669 memset( s, 0, sizeof( s ) );
2670
2671 name = dn;
2672 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002673 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002674
2675 while( name != NULL )
2676 {
Paul Bakkercefb3962012-06-27 11:51:09 +00002677 if( !name->oid.p )
2678 {
2679 name = name->next;
2680 continue;
2681 }
2682
Paul Bakker74111d32011-01-15 16:57:55 +00002683 if( name != dn )
2684 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002685 ret = snprintf( p, n, ", " );
2686 SAFE_SNPRINTF();
2687 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002688
Paul Bakker535e97d2012-08-23 10:49:55 +00002689 if( name->oid.len == 3 &&
2690 memcmp( name->oid.p, OID_X520, 2 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002691 {
2692 switch( name->oid.p[2] )
2693 {
2694 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002695 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002696
2697 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002698 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002699
2700 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002701 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002702
2703 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002704 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002705
2706 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002707 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002708
2709 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002710 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002711
2712 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002713 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002714 name->oid.p[2] );
2715 break;
2716 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002717 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002718 }
Paul Bakker535e97d2012-08-23 10:49:55 +00002719 else if( name->oid.len == 9 &&
2720 memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002721 {
2722 switch( name->oid.p[8] )
2723 {
2724 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002725 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002726
2727 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002728 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002729 name->oid.p[8] );
2730 break;
2731 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002732 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002733 }
2734 else
Paul Bakker74111d32011-01-15 16:57:55 +00002735 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002736 ret = snprintf( p, n, "\?\?=" );
Paul Bakker74111d32011-01-15 16:57:55 +00002737 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002738 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002739
2740 for( i = 0; i < name->val.len; i++ )
2741 {
Paul Bakker27fdf462011-06-09 13:55:13 +00002742 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002743 break;
2744
2745 c = name->val.p[i];
2746 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2747 s[i] = '?';
2748 else s[i] = c;
2749 }
2750 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002751 ret = snprintf( p, n, "%s", s );
2752 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002753 name = name->next;
2754 }
2755
Paul Bakker23986e52011-04-24 08:57:21 +00002756 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002757}
2758
2759/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002760 * Store the serial in printable form into buf; no more
2761 * than size characters will be written
2762 */
2763int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2764{
Paul Bakker23986e52011-04-24 08:57:21 +00002765 int ret;
2766 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00002767 char *p;
2768
2769 p = buf;
2770 n = size;
2771
2772 nr = ( serial->len <= 32 )
Paul Bakker03c7c252011-11-25 12:37:37 +00002773 ? serial->len : 28;
Paul Bakkerdd476992011-01-16 21:34:59 +00002774
2775 for( i = 0; i < nr; i++ )
2776 {
Paul Bakker93048802011-12-05 14:38:06 +00002777 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002778 continue;
2779
Paul Bakkerdd476992011-01-16 21:34:59 +00002780 ret = snprintf( p, n, "%02X%s",
2781 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2782 SAFE_SNPRINTF();
2783 }
2784
Paul Bakker03c7c252011-11-25 12:37:37 +00002785 if( nr != serial->len )
2786 {
2787 ret = snprintf( p, n, "...." );
2788 SAFE_SNPRINTF();
2789 }
2790
Paul Bakker23986e52011-04-24 08:57:21 +00002791 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00002792}
2793
2794/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002795 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002796 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002797int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2798 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002799{
Paul Bakker23986e52011-04-24 08:57:21 +00002800 int ret;
2801 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002802 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00002803
2804 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002805 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002806
Paul Bakkerd98030e2009-05-02 15:13:40 +00002807 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002808 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002809 SAFE_SNPRINTF();
2810 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002811 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002812 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002813
Paul Bakkerdd476992011-01-16 21:34:59 +00002814 ret = x509parse_serial_gets( p, n, &crt->serial);
2815 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002816
Paul Bakkerd98030e2009-05-02 15:13:40 +00002817 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2818 SAFE_SNPRINTF();
2819 ret = x509parse_dn_gets( p, n, &crt->issuer );
2820 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002821
Paul Bakkerd98030e2009-05-02 15:13:40 +00002822 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2823 SAFE_SNPRINTF();
2824 ret = x509parse_dn_gets( p, n, &crt->subject );
2825 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002826
Paul Bakkerd98030e2009-05-02 15:13:40 +00002827 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002828 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2829 crt->valid_from.year, crt->valid_from.mon,
2830 crt->valid_from.day, crt->valid_from.hour,
2831 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002832 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002833
Paul Bakkerd98030e2009-05-02 15:13:40 +00002834 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002835 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2836 crt->valid_to.year, crt->valid_to.mon,
2837 crt->valid_to.day, crt->valid_to.hour,
2838 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002839 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002840
Paul Bakkerd98030e2009-05-02 15:13:40 +00002841 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2842 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002843
Paul Bakker27d66162010-03-17 06:56:01 +00002844 switch( crt->sig_alg )
Paul Bakker5121ce52009-01-03 21:22:43 +00002845 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002846 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2847 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2848 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2849 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2850 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2851 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2852 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2853 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2854 default: ret = snprintf( p, n, "???" ); break;
2855 }
2856 SAFE_SNPRINTF();
2857
2858 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
Paul Bakker5c2364c2012-10-01 14:41:15 +00002859 (int) crt->rsa.N.n * (int) sizeof( t_uint ) * 8 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002860 SAFE_SNPRINTF();
2861
Paul Bakker23986e52011-04-24 08:57:21 +00002862 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002863}
2864
Paul Bakker74111d32011-01-15 16:57:55 +00002865/*
2866 * Return an informational string describing the given OID
2867 */
2868const char *x509_oid_get_description( x509_buf *oid )
2869{
2870 if ( oid == NULL )
2871 return ( NULL );
2872
2873 else if( OID_CMP( OID_SERVER_AUTH, oid ) )
2874 return( STRING_SERVER_AUTH );
2875
2876 else if( OID_CMP( OID_CLIENT_AUTH, oid ) )
2877 return( STRING_CLIENT_AUTH );
2878
2879 else if( OID_CMP( OID_CODE_SIGNING, oid ) )
2880 return( STRING_CODE_SIGNING );
2881
2882 else if( OID_CMP( OID_EMAIL_PROTECTION, oid ) )
2883 return( STRING_EMAIL_PROTECTION );
2884
2885 else if( OID_CMP( OID_TIME_STAMPING, oid ) )
2886 return( STRING_TIME_STAMPING );
2887
2888 else if( OID_CMP( OID_OCSP_SIGNING, oid ) )
2889 return( STRING_OCSP_SIGNING );
2890
2891 return( NULL );
2892}
2893
2894/* Return the x.y.z.... style numeric string for the given OID */
2895int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2896{
Paul Bakker23986e52011-04-24 08:57:21 +00002897 int ret;
2898 size_t i, n;
Paul Bakker74111d32011-01-15 16:57:55 +00002899 unsigned int value;
2900 char *p;
2901
2902 p = buf;
2903 n = size;
2904
2905 /* First byte contains first two dots */
2906 if( oid->len > 0 )
2907 {
2908 ret = snprintf( p, n, "%d.%d", oid->p[0]/40, oid->p[0]%40 );
2909 SAFE_SNPRINTF();
2910 }
2911
2912 /* TODO: value can overflow in value. */
2913 value = 0;
Paul Bakker23986e52011-04-24 08:57:21 +00002914 for( i = 1; i < oid->len; i++ )
Paul Bakker74111d32011-01-15 16:57:55 +00002915 {
2916 value <<= 7;
2917 value += oid->p[i] & 0x7F;
2918
2919 if( !( oid->p[i] & 0x80 ) )
2920 {
2921 /* Last byte */
2922 ret = snprintf( p, n, ".%d", value );
2923 SAFE_SNPRINTF();
2924 value = 0;
2925 }
2926 }
2927
Paul Bakker23986e52011-04-24 08:57:21 +00002928 return( (int) ( size - n ) );
Paul Bakker74111d32011-01-15 16:57:55 +00002929}
2930
Paul Bakkerd98030e2009-05-02 15:13:40 +00002931/*
2932 * Return an informational string about the CRL.
2933 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002934int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2935 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002936{
Paul Bakker23986e52011-04-24 08:57:21 +00002937 int ret;
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002938 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002939 char *p;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002940 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002941
2942 p = buf;
2943 n = size;
2944
2945 ret = snprintf( p, n, "%sCRL version : %d",
2946 prefix, crl->version );
2947 SAFE_SNPRINTF();
2948
2949 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2950 SAFE_SNPRINTF();
2951 ret = x509parse_dn_gets( p, n, &crl->issuer );
2952 SAFE_SNPRINTF();
2953
2954 ret = snprintf( p, n, "\n%sthis update : " \
2955 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2956 crl->this_update.year, crl->this_update.mon,
2957 crl->this_update.day, crl->this_update.hour,
2958 crl->this_update.min, crl->this_update.sec );
2959 SAFE_SNPRINTF();
2960
2961 ret = snprintf( p, n, "\n%snext update : " \
2962 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2963 crl->next_update.year, crl->next_update.mon,
2964 crl->next_update.day, crl->next_update.hour,
2965 crl->next_update.min, crl->next_update.sec );
2966 SAFE_SNPRINTF();
2967
2968 entry = &crl->entry;
2969
2970 ret = snprintf( p, n, "\n%sRevoked certificates:",
2971 prefix );
2972 SAFE_SNPRINTF();
2973
Paul Bakker9be19372009-07-27 20:21:53 +00002974 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002975 {
2976 ret = snprintf( p, n, "\n%sserial number: ",
2977 prefix );
2978 SAFE_SNPRINTF();
2979
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002980 ret = x509parse_serial_gets( p, n, &entry->serial);
2981 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002982
Paul Bakkerd98030e2009-05-02 15:13:40 +00002983 ret = snprintf( p, n, " revocation date: " \
2984 "%04d-%02d-%02d %02d:%02d:%02d",
2985 entry->revocation_date.year, entry->revocation_date.mon,
2986 entry->revocation_date.day, entry->revocation_date.hour,
2987 entry->revocation_date.min, entry->revocation_date.sec );
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002988 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002989
2990 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002991 }
2992
Paul Bakkerd98030e2009-05-02 15:13:40 +00002993 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2994 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002995
Paul Bakker27d66162010-03-17 06:56:01 +00002996 switch( crl->sig_alg )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002997 {
2998 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2999 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
3000 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
3001 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
3002 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
3003 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
3004 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
3005 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
3006 default: ret = snprintf( p, n, "???" ); break;
3007 }
3008 SAFE_SNPRINTF();
3009
Paul Bakker1e27bb22009-07-19 20:25:25 +00003010 ret = snprintf( p, n, "\n" );
3011 SAFE_SNPRINTF();
3012
Paul Bakker23986e52011-04-24 08:57:21 +00003013 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003014}
3015
3016/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00003017 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00003018 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003019int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00003020{
Paul Bakkercce9d772011-11-18 14:26:47 +00003021 int year, mon, day;
3022 int hour, min, sec;
3023
3024#if defined(_WIN32)
3025 SYSTEMTIME st;
3026
3027 GetLocalTime(&st);
3028
3029 year = st.wYear;
3030 mon = st.wMonth;
3031 day = st.wDay;
3032 hour = st.wHour;
3033 min = st.wMinute;
3034 sec = st.wSecond;
3035#else
Paul Bakker5121ce52009-01-03 21:22:43 +00003036 struct tm *lt;
3037 time_t tt;
3038
3039 tt = time( NULL );
3040 lt = localtime( &tt );
3041
Paul Bakkercce9d772011-11-18 14:26:47 +00003042 year = lt->tm_year + 1900;
3043 mon = lt->tm_mon + 1;
3044 day = lt->tm_mday;
3045 hour = lt->tm_hour;
3046 min = lt->tm_min;
3047 sec = lt->tm_sec;
3048#endif
3049
3050 if( year > to->year )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003051 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003052
Paul Bakkercce9d772011-11-18 14:26:47 +00003053 if( year == to->year &&
3054 mon > to->mon )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003055 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003056
Paul Bakkercce9d772011-11-18 14:26:47 +00003057 if( year == to->year &&
3058 mon == to->mon &&
3059 day > to->day )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003060 return( 1 );
3061
Paul Bakkercce9d772011-11-18 14:26:47 +00003062 if( year == to->year &&
3063 mon == to->mon &&
3064 day == to->day &&
3065 hour > to->hour )
Paul Bakkerb6194992011-01-16 21:40:22 +00003066 return( 1 );
3067
Paul Bakkercce9d772011-11-18 14:26:47 +00003068 if( year == to->year &&
3069 mon == to->mon &&
3070 day == to->day &&
3071 hour == to->hour &&
3072 min > to->min )
Paul Bakkerb6194992011-01-16 21:40:22 +00003073 return( 1 );
3074
Paul Bakkercce9d772011-11-18 14:26:47 +00003075 if( year == to->year &&
3076 mon == to->mon &&
3077 day == to->day &&
3078 hour == to->hour &&
3079 min == to->min &&
3080 sec > to->sec )
Paul Bakkerb6194992011-01-16 21:40:22 +00003081 return( 1 );
3082
Paul Bakker40ea7de2009-05-03 10:18:48 +00003083 return( 0 );
3084}
3085
3086/*
3087 * Return 1 if the certificate is revoked, or 0 otherwise.
3088 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003089int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003090{
Paul Bakkerff60ee62010-03-16 21:09:09 +00003091 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00003092
3093 while( cur != NULL && cur->serial.len != 0 )
3094 {
Paul Bakkera056efc2011-01-16 21:38:35 +00003095 if( crt->serial.len == cur->serial.len &&
3096 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003097 {
3098 if( x509parse_time_expired( &cur->revocation_date ) )
3099 return( 1 );
3100 }
3101
3102 cur = cur->next;
3103 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003104
3105 return( 0 );
3106}
3107
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003108/*
3109 * Wrapper for x509 hashes.
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003110 */
Paul Bakker23986e52011-04-24 08:57:21 +00003111static void x509_hash( const unsigned char *in, size_t len, int alg,
Paul Bakker5121ce52009-01-03 21:22:43 +00003112 unsigned char *out )
3113{
3114 switch( alg )
3115 {
Paul Bakker40e46942009-01-03 21:51:57 +00003116#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003117 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003118#endif
Paul Bakker40e46942009-01-03 21:51:57 +00003119#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003120 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003121#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003122#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003123 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003124#endif
3125#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003126 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003127#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00003128#if defined(POLARSSL_SHA2_C)
3129 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
3130 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
3131#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00003132#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003133 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
3134 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
3135#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003136 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003137 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003138 break;
3139 }
3140}
3141
3142/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00003143 * Check that the given certificate is valid accoring to the CRL.
3144 */
3145static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
3146 x509_crl *crl_list)
3147{
3148 int flags = 0;
3149 int hash_id;
3150 unsigned char hash[64];
3151
Paul Bakker915275b2012-09-28 07:10:55 +00003152 if( ca == NULL )
3153 return( flags );
3154
Paul Bakker76fd75a2011-01-16 21:12:10 +00003155 /*
3156 * TODO: What happens if no CRL is present?
3157 * Suggestion: Revocation state should be unknown if no CRL is present.
3158 * For backwards compatibility this is not yet implemented.
3159 */
3160
Paul Bakker915275b2012-09-28 07:10:55 +00003161 while( crl_list != NULL )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003162 {
Paul Bakker915275b2012-09-28 07:10:55 +00003163 if( crl_list->version == 0 ||
3164 crl_list->issuer_raw.len != ca->subject_raw.len ||
Paul Bakker76fd75a2011-01-16 21:12:10 +00003165 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
3166 crl_list->issuer_raw.len ) != 0 )
3167 {
3168 crl_list = crl_list->next;
3169 continue;
3170 }
3171
3172 /*
3173 * Check if CRL is correctly signed by the trusted CA
3174 */
3175 hash_id = crl_list->sig_alg;
3176
3177 x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
3178
3179 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, hash_id,
3180 0, hash, crl_list->sig.p ) == 0 )
3181 {
3182 /*
3183 * CRL is not trusted
3184 */
3185 flags |= BADCRL_NOT_TRUSTED;
3186 break;
3187 }
3188
3189 /*
3190 * Check for validity of CRL (Do not drop out)
3191 */
3192 if( x509parse_time_expired( &crl_list->next_update ) )
3193 flags |= BADCRL_EXPIRED;
3194
3195 /*
3196 * Check if certificate is revoked
3197 */
3198 if( x509parse_revoked(crt, crl_list) )
3199 {
3200 flags |= BADCERT_REVOKED;
3201 break;
3202 }
3203
3204 crl_list = crl_list->next;
3205 }
3206 return flags;
3207}
3208
Paul Bakker57b12982012-02-11 17:38:38 +00003209int x509_wildcard_verify( const char *cn, x509_buf *name )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003210{
3211 size_t i;
3212 size_t cn_idx = 0;
3213
Paul Bakker57b12982012-02-11 17:38:38 +00003214 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003215 return( 0 );
3216
3217 for( i = 0; i < strlen( cn ); ++i )
3218 {
3219 if( cn[i] == '.' )
3220 {
3221 cn_idx = i;
3222 break;
3223 }
3224 }
3225
3226 if( cn_idx == 0 )
3227 return( 0 );
3228
Paul Bakker535e97d2012-08-23 10:49:55 +00003229 if( strlen( cn ) - cn_idx == name->len - 1 &&
3230 memcmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003231 {
3232 return( 1 );
3233 }
3234
3235 return( 0 );
3236}
3237
Paul Bakker915275b2012-09-28 07:10:55 +00003238static int x509parse_verify_top(
3239 x509_cert *child, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003240 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003241 int (*f_vrfy)(void *, x509_cert *, int, int *),
3242 void *p_vrfy )
3243{
3244 int hash_id, ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003245 int ca_flags = 0, check_path_cnt = path_cnt + 1;
Paul Bakker915275b2012-09-28 07:10:55 +00003246 unsigned char hash[64];
3247
3248 if( x509parse_time_expired( &child->valid_to ) )
3249 *flags |= BADCERT_EXPIRED;
3250
3251 /*
3252 * Child is the top of the chain. Check against the trust_ca list.
3253 */
3254 *flags |= BADCERT_NOT_TRUSTED;
3255
3256 while( trust_ca != NULL )
3257 {
3258 if( trust_ca->version == 0 ||
3259 child->issuer_raw.len != trust_ca->subject_raw.len ||
3260 memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
3261 child->issuer_raw.len ) != 0 )
3262 {
3263 trust_ca = trust_ca->next;
3264 continue;
3265 }
3266
Paul Bakker9a736322012-11-14 12:39:52 +00003267 /*
3268 * Reduce path_len to check against if top of the chain is
3269 * the same as the trusted CA
3270 */
3271 if( child->subject_raw.len == trust_ca->subject_raw.len &&
3272 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3273 child->issuer_raw.len ) == 0 )
3274 {
3275 check_path_cnt--;
3276 }
3277
Paul Bakker915275b2012-09-28 07:10:55 +00003278 if( trust_ca->max_pathlen > 0 &&
Paul Bakker9a736322012-11-14 12:39:52 +00003279 trust_ca->max_pathlen < check_path_cnt )
Paul Bakker915275b2012-09-28 07:10:55 +00003280 {
3281 trust_ca = trust_ca->next;
3282 continue;
3283 }
3284
3285 hash_id = child->sig_alg;
3286
3287 x509_hash( child->tbs.p, child->tbs.len, hash_id, hash );
3288
3289 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
3290 0, hash, child->sig.p ) != 0 )
3291 {
3292 trust_ca = trust_ca->next;
3293 continue;
3294 }
3295
3296 /*
3297 * Top of chain is signed by a trusted CA
3298 */
3299 *flags &= ~BADCERT_NOT_TRUSTED;
3300 break;
3301 }
3302
Paul Bakker9a736322012-11-14 12:39:52 +00003303 /*
Paul Bakker3497d8c2012-11-24 11:53:17 +01003304 * If top of chain is not the same as the trusted CA send a verify request
3305 * to the callback for any issues with validity and CRL presence for the
3306 * trusted CA certificate.
Paul Bakker9a736322012-11-14 12:39:52 +00003307 */
3308 if( trust_ca != NULL &&
3309 ( child->subject_raw.len != trust_ca->subject_raw.len ||
3310 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3311 child->issuer_raw.len ) != 0 ) )
Paul Bakker915275b2012-09-28 07:10:55 +00003312 {
3313 /* Check trusted CA's CRL for then chain's top crt */
3314 *flags |= x509parse_verifycrl( child, trust_ca, ca_crl );
3315
3316 if( x509parse_time_expired( &trust_ca->valid_to ) )
3317 ca_flags |= BADCERT_EXPIRED;
3318
Paul Bakker915275b2012-09-28 07:10:55 +00003319 if( NULL != f_vrfy )
3320 {
Paul Bakker9a736322012-11-14 12:39:52 +00003321 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003322 return( ret );
3323 }
3324 }
3325
3326 /* Call callback on top cert */
3327 if( NULL != f_vrfy )
3328 {
Paul Bakker9a736322012-11-14 12:39:52 +00003329 if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003330 return( ret );
3331 }
3332
Paul Bakker915275b2012-09-28 07:10:55 +00003333 *flags |= ca_flags;
3334
3335 return( 0 );
3336}
3337
3338static int x509parse_verify_child(
3339 x509_cert *child, x509_cert *parent, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003340 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003341 int (*f_vrfy)(void *, x509_cert *, int, int *),
3342 void *p_vrfy )
3343{
3344 int hash_id, ret;
3345 int parent_flags = 0;
3346 unsigned char hash[64];
3347 x509_cert *grandparent;
3348
3349 if( x509parse_time_expired( &child->valid_to ) )
3350 *flags |= BADCERT_EXPIRED;
3351
3352 hash_id = child->sig_alg;
3353
3354 x509_hash( child->tbs.p, child->tbs.len, hash_id, hash );
3355
3356 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, hash_id, 0, hash,
3357 child->sig.p ) != 0 )
3358 *flags |= BADCERT_NOT_TRUSTED;
3359
3360 /* Check trusted CA's CRL for the given crt */
3361 *flags |= x509parse_verifycrl(child, parent, ca_crl);
3362
3363 grandparent = parent->next;
3364
3365 while( grandparent != NULL )
3366 {
3367 if( grandparent->version == 0 ||
3368 grandparent->ca_istrue == 0 ||
3369 parent->issuer_raw.len != grandparent->subject_raw.len ||
3370 memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
3371 parent->issuer_raw.len ) != 0 )
3372 {
3373 grandparent = grandparent->next;
3374 continue;
3375 }
3376 break;
3377 }
3378
Paul Bakker915275b2012-09-28 07:10:55 +00003379 if( grandparent != NULL )
3380 {
3381 /*
3382 * Part of the chain
3383 */
Paul Bakker9a736322012-11-14 12:39:52 +00003384 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 +00003385 if( ret != 0 )
3386 return( ret );
3387 }
3388 else
3389 {
Paul Bakker9a736322012-11-14 12:39:52 +00003390 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 +00003391 if( ret != 0 )
3392 return( ret );
3393 }
3394
3395 /* child is verified to be a child of the parent, call verify callback */
3396 if( NULL != f_vrfy )
Paul Bakker9a736322012-11-14 12:39:52 +00003397 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003398 return( ret );
Paul Bakker915275b2012-09-28 07:10:55 +00003399
3400 *flags |= parent_flags;
3401
3402 return( 0 );
3403}
3404
Paul Bakker76fd75a2011-01-16 21:12:10 +00003405/*
Paul Bakker5121ce52009-01-03 21:22:43 +00003406 * Verify the certificate validity
3407 */
3408int x509parse_verify( x509_cert *crt,
3409 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00003410 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003411 const char *cn, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003412 int (*f_vrfy)(void *, x509_cert *, int, int *),
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003413 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00003414{
Paul Bakker23986e52011-04-24 08:57:21 +00003415 size_t cn_len;
Paul Bakker915275b2012-09-28 07:10:55 +00003416 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003417 int pathlen = 0;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003418 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00003419 x509_name *name;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003420 x509_sequence *cur = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003421
Paul Bakker40ea7de2009-05-03 10:18:48 +00003422 *flags = 0;
3423
Paul Bakker5121ce52009-01-03 21:22:43 +00003424 if( cn != NULL )
3425 {
3426 name = &crt->subject;
3427 cn_len = strlen( cn );
3428
Paul Bakker4d2c1242012-05-10 14:12:46 +00003429 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
Paul Bakker5121ce52009-01-03 21:22:43 +00003430 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00003431 cur = &crt->subject_alt_names;
3432
3433 while( cur != NULL )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003434 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003435 if( cur->buf.len == cn_len &&
3436 memcmp( cn, cur->buf.p, cn_len ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003437 break;
3438
Paul Bakker535e97d2012-08-23 10:49:55 +00003439 if( cur->buf.len > 2 &&
3440 memcmp( cur->buf.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003441 x509_wildcard_verify( cn, &cur->buf ) )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003442 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003443
Paul Bakker4d2c1242012-05-10 14:12:46 +00003444 cur = cur->next;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003445 }
3446
3447 if( cur == NULL )
3448 *flags |= BADCERT_CN_MISMATCH;
3449 }
Paul Bakker4d2c1242012-05-10 14:12:46 +00003450 else
3451 {
3452 while( name != NULL )
3453 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003454 if( name->oid.len == 3 &&
3455 memcmp( name->oid.p, OID_CN, 3 ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003456 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003457 if( name->val.len == cn_len &&
3458 memcmp( name->val.p, cn, cn_len ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003459 break;
3460
Paul Bakker535e97d2012-08-23 10:49:55 +00003461 if( name->val.len > 2 &&
3462 memcmp( name->val.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003463 x509_wildcard_verify( cn, &name->val ) )
3464 break;
3465 }
3466
3467 name = name->next;
3468 }
3469
3470 if( name == NULL )
3471 *flags |= BADCERT_CN_MISMATCH;
3472 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003473 }
3474
Paul Bakker5121ce52009-01-03 21:22:43 +00003475 /*
Paul Bakker915275b2012-09-28 07:10:55 +00003476 * Iterate upwards in the given cert chain, to find our crt parent.
3477 * Ignore any upper cert with CA != TRUE.
Paul Bakker5121ce52009-01-03 21:22:43 +00003478 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003479 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003480
Paul Bakker76fd75a2011-01-16 21:12:10 +00003481 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003482 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003483 if( parent->ca_istrue == 0 ||
3484 crt->issuer_raw.len != parent->subject_raw.len ||
3485 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00003486 crt->issuer_raw.len ) != 0 )
3487 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003488 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003489 continue;
3490 }
Paul Bakker915275b2012-09-28 07:10:55 +00003491 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003492 }
3493
Paul Bakker915275b2012-09-28 07:10:55 +00003494 if( parent != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003495 {
Paul Bakker915275b2012-09-28 07:10:55 +00003496 /*
3497 * Part of the chain
3498 */
Paul Bakker9a736322012-11-14 12:39:52 +00003499 ret = x509parse_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003500 if( ret != 0 )
3501 return( ret );
3502 }
3503 else
Paul Bakker74111d32011-01-15 16:57:55 +00003504 {
Paul Bakker9a736322012-11-14 12:39:52 +00003505 ret = x509parse_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003506 if( ret != 0 )
3507 return( ret );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003508 }
Paul Bakker915275b2012-09-28 07:10:55 +00003509
3510 if( *flags != 0 )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003511 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003512
Paul Bakker5121ce52009-01-03 21:22:43 +00003513 return( 0 );
3514}
3515
3516/*
3517 * Unallocate all certificate data
3518 */
3519void x509_free( x509_cert *crt )
3520{
3521 x509_cert *cert_cur = crt;
3522 x509_cert *cert_prv;
3523 x509_name *name_cur;
3524 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00003525 x509_sequence *seq_cur;
3526 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00003527
3528 if( crt == NULL )
3529 return;
3530
3531 do
3532 {
3533 rsa_free( &cert_cur->rsa );
3534
3535 name_cur = cert_cur->issuer.next;
3536 while( name_cur != NULL )
3537 {
3538 name_prv = name_cur;
3539 name_cur = name_cur->next;
3540 memset( name_prv, 0, sizeof( x509_name ) );
3541 free( name_prv );
3542 }
3543
3544 name_cur = cert_cur->subject.next;
3545 while( name_cur != NULL )
3546 {
3547 name_prv = name_cur;
3548 name_cur = name_cur->next;
3549 memset( name_prv, 0, sizeof( x509_name ) );
3550 free( name_prv );
3551 }
3552
Paul Bakker74111d32011-01-15 16:57:55 +00003553 seq_cur = cert_cur->ext_key_usage.next;
3554 while( seq_cur != NULL )
3555 {
3556 seq_prv = seq_cur;
3557 seq_cur = seq_cur->next;
3558 memset( seq_prv, 0, sizeof( x509_sequence ) );
3559 free( seq_prv );
3560 }
3561
Paul Bakker8afa70d2012-02-11 18:42:45 +00003562 seq_cur = cert_cur->subject_alt_names.next;
3563 while( seq_cur != NULL )
3564 {
3565 seq_prv = seq_cur;
3566 seq_cur = seq_cur->next;
3567 memset( seq_prv, 0, sizeof( x509_sequence ) );
3568 free( seq_prv );
3569 }
3570
Paul Bakker5121ce52009-01-03 21:22:43 +00003571 if( cert_cur->raw.p != NULL )
3572 {
3573 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
3574 free( cert_cur->raw.p );
3575 }
3576
3577 cert_cur = cert_cur->next;
3578 }
3579 while( cert_cur != NULL );
3580
3581 cert_cur = crt;
3582 do
3583 {
3584 cert_prv = cert_cur;
3585 cert_cur = cert_cur->next;
3586
3587 memset( cert_prv, 0, sizeof( x509_cert ) );
3588 if( cert_prv != crt )
3589 free( cert_prv );
3590 }
3591 while( cert_cur != NULL );
3592}
3593
Paul Bakkerd98030e2009-05-02 15:13:40 +00003594/*
3595 * Unallocate all CRL data
3596 */
3597void x509_crl_free( x509_crl *crl )
3598{
3599 x509_crl *crl_cur = crl;
3600 x509_crl *crl_prv;
3601 x509_name *name_cur;
3602 x509_name *name_prv;
3603 x509_crl_entry *entry_cur;
3604 x509_crl_entry *entry_prv;
3605
3606 if( crl == NULL )
3607 return;
3608
3609 do
3610 {
3611 name_cur = crl_cur->issuer.next;
3612 while( name_cur != NULL )
3613 {
3614 name_prv = name_cur;
3615 name_cur = name_cur->next;
3616 memset( name_prv, 0, sizeof( x509_name ) );
3617 free( name_prv );
3618 }
3619
3620 entry_cur = crl_cur->entry.next;
3621 while( entry_cur != NULL )
3622 {
3623 entry_prv = entry_cur;
3624 entry_cur = entry_cur->next;
3625 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
3626 free( entry_prv );
3627 }
3628
3629 if( crl_cur->raw.p != NULL )
3630 {
3631 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
3632 free( crl_cur->raw.p );
3633 }
3634
3635 crl_cur = crl_cur->next;
3636 }
3637 while( crl_cur != NULL );
3638
3639 crl_cur = crl;
3640 do
3641 {
3642 crl_prv = crl_cur;
3643 crl_cur = crl_cur->next;
3644
3645 memset( crl_prv, 0, sizeof( x509_crl ) );
3646 if( crl_prv != crl )
3647 free( crl_prv );
3648 }
3649 while( crl_cur != NULL );
3650}
3651
Paul Bakker40e46942009-01-03 21:51:57 +00003652#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00003653
Paul Bakker40e46942009-01-03 21:51:57 +00003654#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00003655
3656/*
3657 * Checkup routine
3658 */
3659int x509_self_test( int verbose )
3660{
Paul Bakker5690efc2011-05-26 13:16:06 +00003661#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00003662 int ret;
3663 int flags;
3664 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00003665 x509_cert cacert;
3666 x509_cert clicert;
3667 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00003668#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003669 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00003670#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003671
3672 if( verbose != 0 )
3673 printf( " X.509 certificate load: " );
3674
3675 memset( &clicert, 0, sizeof( x509_cert ) );
3676
Paul Bakkereae09db2013-06-06 12:35:54 +02003677 ret = x509parse_crt( &clicert, (const unsigned char *) test_cli_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003678 strlen( test_cli_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003679 if( ret != 0 )
3680 {
3681 if( verbose != 0 )
3682 printf( "failed\n" );
3683
3684 return( ret );
3685 }
3686
3687 memset( &cacert, 0, sizeof( x509_cert ) );
3688
Paul Bakkereae09db2013-06-06 12:35:54 +02003689 ret = x509parse_crt( &cacert, (const unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003690 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003691 if( ret != 0 )
3692 {
3693 if( verbose != 0 )
3694 printf( "failed\n" );
3695
3696 return( ret );
3697 }
3698
3699 if( verbose != 0 )
3700 printf( "passed\n X.509 private key load: " );
3701
3702 i = strlen( test_ca_key );
3703 j = strlen( test_ca_pwd );
3704
Paul Bakker66b78b22011-03-25 14:22:50 +00003705 rsa_init( &rsa, RSA_PKCS_V15, 0 );
3706
Paul Bakker5121ce52009-01-03 21:22:43 +00003707 if( ( ret = x509parse_key( &rsa,
Paul Bakkereae09db2013-06-06 12:35:54 +02003708 (const unsigned char *) test_ca_key, i,
3709 (const unsigned char *) test_ca_pwd, j ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003710 {
3711 if( verbose != 0 )
3712 printf( "failed\n" );
3713
3714 return( ret );
3715 }
3716
3717 if( verbose != 0 )
3718 printf( "passed\n X.509 signature verify: ");
3719
Paul Bakker23986e52011-04-24 08:57:21 +00003720 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003721 if( ret != 0 )
3722 {
Paul Bakker23986e52011-04-24 08:57:21 +00003723 printf("%02x", flags);
Paul Bakker5121ce52009-01-03 21:22:43 +00003724 if( verbose != 0 )
3725 printf( "failed\n" );
3726
3727 return( ret );
3728 }
3729
Paul Bakker5690efc2011-05-26 13:16:06 +00003730#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003731 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003732 printf( "passed\n X.509 DHM parameter load: " );
3733
3734 i = strlen( test_dhm_params );
3735 j = strlen( test_ca_pwd );
3736
Paul Bakkereae09db2013-06-06 12:35:54 +02003737 if( ( ret = x509parse_dhm( &dhm, (const unsigned char *) test_dhm_params, i ) ) != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003738 {
3739 if( verbose != 0 )
3740 printf( "failed\n" );
3741
3742 return( ret );
3743 }
3744
3745 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003746 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00003747#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003748
3749 x509_free( &cacert );
3750 x509_free( &clicert );
3751 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00003752#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003753 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00003754#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003755
3756 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003757#else
3758 ((void) verbose);
3759 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3760#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003761}
3762
3763#endif
3764
3765#endif