blob: ce75d59431ce87d058f7f3d1fe5e8b7d82ae6ad7 [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 Bakker6c0ceb32011-12-04 12:24:18 +00001132int x509parse_crt_der( x509_cert *crt, const unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001133{
Paul Bakker23986e52011-04-24 08:57:21 +00001134 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001135 size_t len;
Paul Bakkerb00ca422012-09-25 12:10:00 +00001136 unsigned char *p, *end, *crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001137
Paul Bakker320a4b52009-03-28 18:52:39 +00001138 /*
1139 * Check for valid input
1140 */
1141 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001142 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker320a4b52009-03-28 18:52:39 +00001143
Paul Bakker96743fc2011-02-12 14:30:57 +00001144 p = (unsigned char *) malloc( len = buflen );
1145
1146 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001147 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001148
1149 memcpy( p, buf, buflen );
1150
1151 buflen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001152
1153 crt->raw.p = p;
1154 crt->raw.len = len;
1155 end = p + len;
1156
1157 /*
1158 * Certificate ::= SEQUENCE {
1159 * tbsCertificate TBSCertificate,
1160 * signatureAlgorithm AlgorithmIdentifier,
1161 * signatureValue BIT STRING }
1162 */
1163 if( ( ret = asn1_get_tag( &p, end, &len,
1164 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1165 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001166 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001167 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001168 }
1169
Paul Bakkerb00ca422012-09-25 12:10:00 +00001170 if( len > (size_t) ( end - p ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001171 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001172 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001173 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001174 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001175 }
Paul Bakkerb00ca422012-09-25 12:10:00 +00001176 crt_end = p + len;
1177
Paul Bakker5121ce52009-01-03 21:22:43 +00001178 /*
1179 * TBSCertificate ::= SEQUENCE {
1180 */
1181 crt->tbs.p = p;
1182
1183 if( ( ret = asn1_get_tag( &p, end, &len,
1184 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1185 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001186 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001187 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001188 }
1189
1190 end = p + len;
1191 crt->tbs.len = end - crt->tbs.p;
1192
1193 /*
1194 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1195 *
1196 * CertificateSerialNumber ::= INTEGER
1197 *
1198 * signature AlgorithmIdentifier
1199 */
1200 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1201 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1202 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
1203 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001204 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001205 return( ret );
1206 }
1207
1208 crt->version++;
1209
1210 if( crt->version > 3 )
1211 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001212 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001213 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001214 }
1215
Paul Bakker27d66162010-03-17 06:56:01 +00001216 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_alg ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001217 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001218 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001219 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001220 }
1221
1222 /*
1223 * issuer Name
1224 */
1225 crt->issuer_raw.p = p;
1226
1227 if( ( ret = asn1_get_tag( &p, end, &len,
1228 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1229 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001230 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001231 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001232 }
1233
1234 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1235 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001236 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001237 return( ret );
1238 }
1239
1240 crt->issuer_raw.len = p - crt->issuer_raw.p;
1241
1242 /*
1243 * Validity ::= SEQUENCE {
1244 * notBefore Time,
1245 * notAfter Time }
1246 *
1247 */
1248 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1249 &crt->valid_to ) ) != 0 )
1250 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001251 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001252 return( ret );
1253 }
1254
1255 /*
1256 * subject Name
1257 */
1258 crt->subject_raw.p = p;
1259
1260 if( ( ret = asn1_get_tag( &p, end, &len,
1261 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1262 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001263 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001264 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001265 }
1266
Paul Bakkercefb3962012-06-27 11:51:09 +00001267 if( len && ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001268 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001269 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001270 return( ret );
1271 }
1272
1273 crt->subject_raw.len = p - crt->subject_raw.p;
1274
1275 /*
1276 * SubjectPublicKeyInfo ::= SEQUENCE
1277 * algorithm AlgorithmIdentifier,
1278 * subjectPublicKey BIT STRING }
1279 */
1280 if( ( ret = asn1_get_tag( &p, end, &len,
1281 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1282 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001283 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001284 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001285 }
1286
1287 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1288 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1289 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001290 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001291 return( ret );
1292 }
1293
1294 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1295 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001296 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001297 return( ret );
1298 }
1299
1300 crt->rsa.len = mpi_size( &crt->rsa.N );
1301
1302 /*
1303 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1304 * -- If present, version shall be v2 or v3
1305 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1306 * -- If present, version shall be v2 or v3
1307 * extensions [3] EXPLICIT Extensions OPTIONAL
1308 * -- If present, version shall be v3
1309 */
1310 if( crt->version == 2 || crt->version == 3 )
1311 {
1312 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1313 if( ret != 0 )
1314 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001315 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001316 return( ret );
1317 }
1318 }
1319
1320 if( crt->version == 2 || crt->version == 3 )
1321 {
1322 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1323 if( ret != 0 )
1324 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001325 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001326 return( ret );
1327 }
1328 }
1329
1330 if( crt->version == 3 )
1331 {
Paul Bakker74111d32011-01-15 16:57:55 +00001332 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001333 if( ret != 0 )
1334 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001335 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001336 return( ret );
1337 }
1338 }
1339
1340 if( p != end )
1341 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001342 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001343 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001344 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001345 }
1346
Paul Bakkerb00ca422012-09-25 12:10:00 +00001347 end = crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001348
1349 /*
1350 * signatureAlgorithm AlgorithmIdentifier,
1351 * signatureValue BIT STRING
1352 */
1353 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1354 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001355 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001356 return( ret );
1357 }
1358
Paul Bakker535e97d2012-08-23 10:49:55 +00001359 if( crt->sig_oid1.len != crt->sig_oid2.len ||
1360 memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001361 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001362 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001363 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001364 }
1365
1366 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1367 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001368 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001369 return( ret );
1370 }
1371
1372 if( p != end )
1373 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001374 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001375 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001376 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001377 }
1378
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001379 return( 0 );
1380}
1381
1382/*
1383 * Parse one or more PEM certificates from a buffer and add them to the chained list
1384 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001385int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001386{
Paul Bakker69e095c2011-12-10 21:55:01 +00001387 int ret, success = 0, first_error = 0, total_failed = 0;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001388 x509_cert *crt, *prev = NULL;
1389 int buf_format = X509_FORMAT_DER;
1390
1391 crt = chain;
1392
1393 /*
1394 * Check for valid input
1395 */
1396 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001397 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001398
1399 while( crt->version != 0 && crt->next != NULL )
1400 {
1401 prev = crt;
1402 crt = crt->next;
1403 }
1404
1405 /*
1406 * Add new certificate on the end of the chain if needed.
1407 */
1408 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001409 {
1410 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1411
Paul Bakker7d06ad22009-05-02 15:53:56 +00001412 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001413 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker320a4b52009-03-28 18:52:39 +00001414
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001415 prev = crt;
Paul Bakker7d06ad22009-05-02 15:53:56 +00001416 crt = crt->next;
1417 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001418 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001419
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001420 /*
1421 * Determine buffer content. Buffer contains either one DER certificate or
1422 * one or more PEM certificates.
1423 */
1424#if defined(POLARSSL_PEM_C)
Paul Bakkereae09db2013-06-06 12:35:54 +02001425 if( strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001426 buf_format = X509_FORMAT_PEM;
1427#endif
1428
1429 if( buf_format == X509_FORMAT_DER )
1430 return x509parse_crt_der( crt, buf, buflen );
1431
1432#if defined(POLARSSL_PEM_C)
1433 if( buf_format == X509_FORMAT_PEM )
1434 {
1435 pem_context pem;
1436
1437 while( buflen > 0 )
1438 {
1439 size_t use_len;
1440 pem_init( &pem );
1441
1442 ret = pem_read_buffer( &pem,
1443 "-----BEGIN CERTIFICATE-----",
1444 "-----END CERTIFICATE-----",
1445 buf, NULL, 0, &use_len );
1446
1447 if( ret == 0 )
1448 {
1449 /*
1450 * Was PEM encoded
1451 */
1452 buflen -= use_len;
1453 buf += use_len;
1454 }
Paul Bakker64171862013-06-06 15:01:18 +02001455 else if( ret == POLARSSL_ERR_PEM_BAD_INPUT_DATA )
1456 {
1457 return( ret );
1458 }
Paul Bakker9255e832013-06-06 14:58:28 +02001459 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001460 {
1461 pem_free( &pem );
1462
Paul Bakker64171862013-06-06 15:01:18 +02001463 /*
1464 * PEM header and footer were found
1465 */
1466 buflen -= use_len;
1467 buf += use_len;
1468
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001469 if( first_error == 0 )
1470 first_error = ret;
1471
1472 continue;
1473 }
1474 else
1475 break;
1476
1477 ret = x509parse_crt_der( crt, pem.buf, pem.buflen );
1478
1479 pem_free( &pem );
1480
1481 if( ret != 0 )
1482 {
1483 /*
Paul Bakker69e095c2011-12-10 21:55:01 +00001484 * quit parsing on a memory error
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001485 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001486 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001487 {
1488 if( prev )
1489 prev->next = NULL;
1490
1491 if( crt != chain )
1492 free( crt );
1493
1494 return( ret );
1495 }
1496
1497 if( first_error == 0 )
1498 first_error = ret;
Paul Bakker69e095c2011-12-10 21:55:01 +00001499
1500 total_failed++;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001501
1502 memset( crt, 0, sizeof( x509_cert ) );
1503 continue;
1504 }
1505
1506 success = 1;
1507
1508 /*
1509 * Add new certificate to the list
1510 */
1511 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1512
1513 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001514 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001515
1516 prev = crt;
1517 crt = crt->next;
1518 memset( crt, 0, sizeof( x509_cert ) );
1519 }
1520 }
1521#endif
1522
1523 if( crt->version == 0 )
1524 {
1525 if( prev )
1526 prev->next = NULL;
1527
1528 if( crt != chain )
1529 free( crt );
1530 }
1531
1532 if( success )
Paul Bakker69e095c2011-12-10 21:55:01 +00001533 return( total_failed );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001534 else if( first_error )
1535 return( first_error );
1536 else
1537 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001538}
1539
1540/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001541 * Parse one or more CRLs and add them to the chained list
1542 */
Paul Bakker23986e52011-04-24 08:57:21 +00001543int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001544{
Paul Bakker23986e52011-04-24 08:57:21 +00001545 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001546 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001547 unsigned char *p, *end;
1548 x509_crl *crl;
Paul Bakker96743fc2011-02-12 14:30:57 +00001549#if defined(POLARSSL_PEM_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00001550 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001551 pem_context pem;
1552#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001553
1554 crl = chain;
1555
1556 /*
1557 * Check for valid input
1558 */
1559 if( crl == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001560 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001561
1562 while( crl->version != 0 && crl->next != NULL )
1563 crl = crl->next;
1564
1565 /*
1566 * Add new CRL on the end of the chain if needed.
1567 */
1568 if ( crl->version != 0 && crl->next == NULL)
1569 {
1570 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1571
Paul Bakker7d06ad22009-05-02 15:53:56 +00001572 if( crl->next == NULL )
1573 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001574 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001575 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001576 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001577
Paul Bakker7d06ad22009-05-02 15:53:56 +00001578 crl = crl->next;
1579 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001580 }
1581
Paul Bakker96743fc2011-02-12 14:30:57 +00001582#if defined(POLARSSL_PEM_C)
1583 pem_init( &pem );
1584 ret = pem_read_buffer( &pem,
1585 "-----BEGIN X509 CRL-----",
1586 "-----END X509 CRL-----",
1587 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001588
Paul Bakker96743fc2011-02-12 14:30:57 +00001589 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001590 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001591 /*
1592 * Was PEM encoded
1593 */
1594 buflen -= use_len;
1595 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001596
1597 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001598 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001599 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001600 p = pem.buf;
1601 pem.buf = NULL;
1602 len = pem.buflen;
1603 pem_free( &pem );
1604 }
Paul Bakker9255e832013-06-06 14:58:28 +02001605 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker96743fc2011-02-12 14:30:57 +00001606 {
1607 pem_free( &pem );
1608 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001609 }
1610 else
1611 {
1612 /*
1613 * nope, copy the raw DER data
1614 */
1615 p = (unsigned char *) malloc( len = buflen );
1616
1617 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001618 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001619
1620 memcpy( p, buf, buflen );
1621
1622 buflen = 0;
1623 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001624#else
1625 p = (unsigned char *) malloc( len = buflen );
1626
1627 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001628 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001629
1630 memcpy( p, buf, buflen );
1631
1632 buflen = 0;
1633#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001634
1635 crl->raw.p = p;
1636 crl->raw.len = len;
1637 end = p + len;
1638
1639 /*
1640 * CertificateList ::= SEQUENCE {
1641 * tbsCertList TBSCertList,
1642 * signatureAlgorithm AlgorithmIdentifier,
1643 * signatureValue BIT STRING }
1644 */
1645 if( ( ret = asn1_get_tag( &p, end, &len,
1646 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1647 {
1648 x509_crl_free( crl );
1649 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1650 }
1651
Paul Bakker23986e52011-04-24 08:57:21 +00001652 if( len != (size_t) ( end - p ) )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001653 {
1654 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001655 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001656 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1657 }
1658
1659 /*
1660 * TBSCertList ::= SEQUENCE {
1661 */
1662 crl->tbs.p = p;
1663
1664 if( ( ret = asn1_get_tag( &p, end, &len,
1665 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1666 {
1667 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001668 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001669 }
1670
1671 end = p + len;
1672 crl->tbs.len = end - crl->tbs.p;
1673
1674 /*
1675 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1676 * -- if present, MUST be v2
1677 *
1678 * signature AlgorithmIdentifier
1679 */
Paul Bakker3329d1f2011-10-12 09:55:01 +00001680 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
Paul Bakkerd98030e2009-05-02 15:13:40 +00001681 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1682 {
1683 x509_crl_free( crl );
1684 return( ret );
1685 }
1686
1687 crl->version++;
1688
1689 if( crl->version > 2 )
1690 {
1691 x509_crl_free( crl );
1692 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1693 }
1694
Paul Bakker27d66162010-03-17 06:56:01 +00001695 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_alg ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001696 {
1697 x509_crl_free( crl );
1698 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1699 }
1700
1701 /*
1702 * issuer Name
1703 */
1704 crl->issuer_raw.p = p;
1705
1706 if( ( ret = asn1_get_tag( &p, end, &len,
1707 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1708 {
1709 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001710 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001711 }
1712
1713 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1714 {
1715 x509_crl_free( crl );
1716 return( ret );
1717 }
1718
1719 crl->issuer_raw.len = p - crl->issuer_raw.p;
1720
1721 /*
1722 * thisUpdate Time
1723 * nextUpdate Time OPTIONAL
1724 */
Paul Bakker91200182010-02-18 21:26:15 +00001725 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001726 {
1727 x509_crl_free( crl );
1728 return( ret );
1729 }
1730
Paul Bakker91200182010-02-18 21:26:15 +00001731 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001732 {
Paul Bakker9d781402011-05-09 16:17:09 +00001733 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001734 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker9d781402011-05-09 16:17:09 +00001735 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001736 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001737 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001738 x509_crl_free( crl );
1739 return( ret );
1740 }
1741 }
1742
1743 /*
1744 * revokedCertificates SEQUENCE OF SEQUENCE {
1745 * userCertificate CertificateSerialNumber,
1746 * revocationDate Time,
1747 * crlEntryExtensions Extensions OPTIONAL
1748 * -- if present, MUST be v2
1749 * } OPTIONAL
1750 */
1751 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1752 {
1753 x509_crl_free( crl );
1754 return( ret );
1755 }
1756
1757 /*
1758 * crlExtensions EXPLICIT Extensions OPTIONAL
1759 * -- if present, MUST be v2
1760 */
1761 if( crl->version == 2 )
1762 {
1763 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1764
1765 if( ret != 0 )
1766 {
1767 x509_crl_free( crl );
1768 return( ret );
1769 }
1770 }
1771
1772 if( p != end )
1773 {
1774 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001775 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001776 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1777 }
1778
1779 end = crl->raw.p + crl->raw.len;
1780
1781 /*
1782 * signatureAlgorithm AlgorithmIdentifier,
1783 * signatureValue BIT STRING
1784 */
1785 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1786 {
1787 x509_crl_free( crl );
1788 return( ret );
1789 }
1790
Paul Bakker535e97d2012-08-23 10:49:55 +00001791 if( crl->sig_oid1.len != crl->sig_oid2.len ||
1792 memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001793 {
1794 x509_crl_free( crl );
1795 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1796 }
1797
1798 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1799 {
1800 x509_crl_free( crl );
1801 return( ret );
1802 }
1803
1804 if( p != end )
1805 {
1806 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001807 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001808 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1809 }
1810
1811 if( buflen > 0 )
1812 {
1813 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1814
Paul Bakker7d06ad22009-05-02 15:53:56 +00001815 if( crl->next == NULL )
1816 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001817 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001818 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001819 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001820
Paul Bakker7d06ad22009-05-02 15:53:56 +00001821 crl = crl->next;
1822 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001823
1824 return( x509parse_crl( crl, buf, buflen ) );
1825 }
1826
1827 return( 0 );
1828}
1829
Paul Bakker335db3f2011-04-25 15:28:35 +00001830#if defined(POLARSSL_FS_IO)
Paul Bakkerd98030e2009-05-02 15:13:40 +00001831/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001832 * Load all data from a file into a given buffer.
1833 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001834int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001835{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001836 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001837
Paul Bakkerd98030e2009-05-02 15:13:40 +00001838 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001839 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001840
Paul Bakkerd98030e2009-05-02 15:13:40 +00001841 fseek( f, 0, SEEK_END );
1842 *n = (size_t) ftell( f );
1843 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001844
Paul Bakkerd98030e2009-05-02 15:13:40 +00001845 if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001846 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001847
Paul Bakkerd98030e2009-05-02 15:13:40 +00001848 if( fread( *buf, 1, *n, f ) != *n )
1849 {
1850 fclose( f );
1851 free( *buf );
Paul Bakker69e095c2011-12-10 21:55:01 +00001852 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001853 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001854
Paul Bakkerd98030e2009-05-02 15:13:40 +00001855 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001856
Paul Bakkerd98030e2009-05-02 15:13:40 +00001857 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001858
Paul Bakkerd98030e2009-05-02 15:13:40 +00001859 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001860}
1861
1862/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001863 * Load one or more certificates and add them to the chained list
1864 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001865int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001866{
1867 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001868 size_t n;
1869 unsigned char *buf;
1870
Paul Bakker69e095c2011-12-10 21:55:01 +00001871 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1872 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001873
Paul Bakker69e095c2011-12-10 21:55:01 +00001874 ret = x509parse_crt( chain, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001875
1876 memset( buf, 0, n + 1 );
1877 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001878
1879 return( ret );
1880}
1881
Paul Bakker8d914582012-06-04 12:46:42 +00001882int x509parse_crtpath( x509_cert *chain, const char *path )
1883{
1884 int ret = 0;
1885#if defined(_WIN32)
Paul Bakker3338b792012-10-01 21:13:10 +00001886 int w_ret;
1887 WCHAR szDir[MAX_PATH];
1888 char filename[MAX_PATH];
1889 char *p;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001890 int len = strlen( path );
Paul Bakker3338b792012-10-01 21:13:10 +00001891
Paul Bakker97872ac2012-11-02 12:53:26 +00001892 WIN32_FIND_DATAW file_data;
Paul Bakker8d914582012-06-04 12:46:42 +00001893 HANDLE hFind;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001894
1895 if( len > MAX_PATH - 3 )
1896 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker8d914582012-06-04 12:46:42 +00001897
Paul Bakker3338b792012-10-01 21:13:10 +00001898 memset( szDir, 0, sizeof(szDir) );
1899 memset( filename, 0, MAX_PATH );
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001900 memcpy( filename, path, len );
1901 filename[len++] = '\\';
1902 p = filename + len;
1903 filename[len++] = '*';
Paul Bakker3338b792012-10-01 21:13:10 +00001904
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001905 w_ret = MultiByteToWideChar( CP_ACP, 0, path, len, szDir, MAX_PATH - 3 );
Paul Bakker8d914582012-06-04 12:46:42 +00001906
Paul Bakker97872ac2012-11-02 12:53:26 +00001907 hFind = FindFirstFileW( szDir, &file_data );
Paul Bakker8d914582012-06-04 12:46:42 +00001908 if (hFind == INVALID_HANDLE_VALUE)
1909 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1910
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001911 len = MAX_PATH - len;
Paul Bakker8d914582012-06-04 12:46:42 +00001912 do
1913 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001914 memset( p, 0, len );
Paul Bakker3338b792012-10-01 21:13:10 +00001915
Paul Bakkere4791f32012-06-04 21:29:15 +00001916 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
Paul Bakker8d914582012-06-04 12:46:42 +00001917 continue;
1918
Paul Bakker3338b792012-10-01 21:13:10 +00001919 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
1920 lstrlenW(file_data.cFileName),
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001921 p, len - 1,
1922 NULL, NULL );
Paul Bakker8d914582012-06-04 12:46:42 +00001923
Paul Bakker3338b792012-10-01 21:13:10 +00001924 w_ret = x509parse_crtfile( chain, filename );
1925 if( w_ret < 0 )
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001926 {
1927 ret = w_ret;
1928 goto cleanup;
1929 }
Paul Bakker3338b792012-10-01 21:13:10 +00001930
1931 ret += w_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001932 }
Paul Bakker97872ac2012-11-02 12:53:26 +00001933 while( FindNextFileW( hFind, &file_data ) != 0 );
Paul Bakker8d914582012-06-04 12:46:42 +00001934
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001935 if (GetLastError() != ERROR_NO_MORE_FILES)
1936 ret = POLARSSL_ERR_X509_FILE_IO_ERROR;
Paul Bakker8d914582012-06-04 12:46:42 +00001937
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001938cleanup:
Paul Bakker8d914582012-06-04 12:46:42 +00001939 FindClose( hFind );
1940#else
1941 int t_ret;
1942 struct dirent *entry;
1943 char entry_name[255];
1944 DIR *dir = opendir( path );
1945
1946 if( dir == NULL)
1947 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1948
1949 while( ( entry = readdir( dir ) ) != NULL )
1950 {
1951 if( entry->d_type != DT_REG )
1952 continue;
1953
1954 snprintf( entry_name, sizeof(entry_name), "%s/%s", path, entry->d_name );
1955 t_ret = x509parse_crtfile( chain, entry_name );
1956 if( t_ret < 0 )
Paul Bakker97872ac2012-11-02 12:53:26 +00001957 {
1958 ret = t_ret;
1959 break;
1960 }
Paul Bakker8d914582012-06-04 12:46:42 +00001961
1962 ret += t_ret;
1963 }
1964 closedir( dir );
1965#endif
1966
1967 return( ret );
1968}
1969
Paul Bakkerd98030e2009-05-02 15:13:40 +00001970/*
1971 * Load one or more CRLs and add them to the chained list
1972 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001973int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001974{
1975 int ret;
1976 size_t n;
1977 unsigned char *buf;
1978
Paul Bakker69e095c2011-12-10 21:55:01 +00001979 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1980 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001981
Paul Bakker27fdf462011-06-09 13:55:13 +00001982 ret = x509parse_crl( chain, buf, n );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001983
1984 memset( buf, 0, n + 1 );
1985 free( buf );
1986
1987 return( ret );
1988}
1989
Paul Bakker5121ce52009-01-03 21:22:43 +00001990/*
Paul Bakker335db3f2011-04-25 15:28:35 +00001991 * Load and parse a private RSA key
1992 */
1993int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
1994{
1995 int ret;
1996 size_t n;
1997 unsigned char *buf;
1998
Paul Bakker69e095c2011-12-10 21:55:01 +00001999 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2000 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002001
2002 if( pwd == NULL )
Paul Bakker27fdf462011-06-09 13:55:13 +00002003 ret = x509parse_key( rsa, buf, n, NULL, 0 );
Paul Bakker335db3f2011-04-25 15:28:35 +00002004 else
Paul Bakker27fdf462011-06-09 13:55:13 +00002005 ret = x509parse_key( rsa, buf, n,
Paul Bakker335db3f2011-04-25 15:28:35 +00002006 (unsigned char *) pwd, strlen( pwd ) );
2007
2008 memset( buf, 0, n + 1 );
2009 free( buf );
2010
2011 return( ret );
2012}
2013
2014/*
2015 * Load and parse a public RSA key
2016 */
2017int x509parse_public_keyfile( rsa_context *rsa, const char *path )
2018{
2019 int ret;
2020 size_t n;
2021 unsigned char *buf;
2022
Paul Bakker69e095c2011-12-10 21:55:01 +00002023 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2024 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002025
Paul Bakker27fdf462011-06-09 13:55:13 +00002026 ret = x509parse_public_key( rsa, buf, n );
Paul Bakker335db3f2011-04-25 15:28:35 +00002027
2028 memset( buf, 0, n + 1 );
2029 free( buf );
2030
2031 return( ret );
2032}
2033#endif /* POLARSSL_FS_IO */
2034
2035/*
Paul Bakker65a19092013-06-06 21:14:58 +02002036 * Parse a PKCS#1 encoded private RSA key
Paul Bakker5121ce52009-01-03 21:22:43 +00002037 */
Paul Bakker65a19092013-06-06 21:14:58 +02002038static int x509parse_key_pkcs1_der( rsa_context *rsa,
2039 const unsigned char *key,
2040 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +00002041{
Paul Bakker23986e52011-04-24 08:57:21 +00002042 int ret;
2043 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00002044 unsigned char *p, *end;
Paul Bakkered56b222011-07-13 11:26:43 +00002045
Paul Bakker96743fc2011-02-12 14:30:57 +00002046 p = (unsigned char *) key;
Paul Bakker96743fc2011-02-12 14:30:57 +00002047 end = p + keylen;
2048
Paul Bakker5121ce52009-01-03 21:22:43 +00002049 /*
Paul Bakker65a19092013-06-06 21:14:58 +02002050 * This function parses the RSAPrivateKey (PKCS#1)
Paul Bakkered56b222011-07-13 11:26:43 +00002051 *
Paul Bakker5121ce52009-01-03 21:22:43 +00002052 * RSAPrivateKey ::= SEQUENCE {
2053 * version Version,
2054 * modulus INTEGER, -- n
2055 * publicExponent INTEGER, -- e
2056 * privateExponent INTEGER, -- d
2057 * prime1 INTEGER, -- p
2058 * prime2 INTEGER, -- q
2059 * exponent1 INTEGER, -- d mod (p-1)
2060 * exponent2 INTEGER, -- d mod (q-1)
2061 * coefficient INTEGER, -- (inverse of q) mod p
2062 * otherPrimeInfos OtherPrimeInfos OPTIONAL
2063 * }
2064 */
2065 if( ( ret = asn1_get_tag( &p, end, &len,
2066 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2067 {
Paul Bakker9d781402011-05-09 16:17:09 +00002068 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002069 }
2070
2071 end = p + len;
2072
2073 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2074 {
Paul Bakker9d781402011-05-09 16:17:09 +00002075 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002076 }
2077
2078 if( rsa->ver != 0 )
2079 {
Paul Bakker9d781402011-05-09 16:17:09 +00002080 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002081 }
2082
2083 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
2084 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
2085 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
2086 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
2087 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
2088 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
2089 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
2090 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
2091 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002092 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002093 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002094 }
2095
2096 rsa->len = mpi_size( &rsa->N );
2097
2098 if( p != end )
2099 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002100 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002101 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00002102 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002103 }
2104
2105 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2106 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002107 rsa_free( rsa );
2108 return( ret );
2109 }
2110
Paul Bakker65a19092013-06-06 21:14:58 +02002111 return( 0 );
2112}
2113
2114/*
2115 * Parse an unencrypted PKCS#8 encoded private RSA key
2116 */
2117static int x509parse_key_pkcs8_unencrypted_der(
2118 rsa_context *rsa,
2119 const unsigned char *key,
2120 size_t keylen )
2121{
2122 int ret;
2123 size_t len;
2124 unsigned char *p, *end;
2125 x509_buf pk_alg_oid;
2126
2127 p = (unsigned char *) key;
2128 end = p + keylen;
2129
2130 /*
2131 * This function parses the PrivatKeyInfo object (PKCS#8)
2132 *
2133 * PrivateKeyInfo ::= SEQUENCE {
2134 * version Version,
2135 * algorithm AlgorithmIdentifier,
2136 * PrivateKey BIT STRING
2137 * }
2138 *
2139 * AlgorithmIdentifier ::= SEQUENCE {
2140 * algorithm OBJECT IDENTIFIER,
2141 * parameters ANY DEFINED BY algorithm OPTIONAL
2142 * }
2143 *
2144 * The PrivateKey BIT STRING is a PKCS#1 RSAPrivateKey
2145 */
2146 if( ( ret = asn1_get_tag( &p, end, &len,
2147 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2148 {
2149 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2150 }
2151
2152 end = p + len;
2153
2154 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2155 {
2156 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2157 }
2158
2159 if( rsa->ver != 0 )
2160 {
2161 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2162 }
2163
2164 if( ( ret = x509_get_alg( &p, end, &pk_alg_oid ) ) != 0 )
2165 {
2166 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2167 }
2168
2169 /*
2170 * only RSA keys handled at this time
2171 */
2172 if( pk_alg_oid.len != 9 ||
2173 memcmp( pk_alg_oid.p, OID_PKCS1_RSA, 9 ) != 0 )
2174 {
2175 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
2176 }
2177
2178 /*
2179 * Get the OCTET STRING and parse the PKCS#1 format inside
2180 */
2181 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2182 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2183
2184 if( ( end - p ) < 1 )
2185 {
2186 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
2187 POLARSSL_ERR_ASN1_OUT_OF_DATA );
2188 }
2189
2190 end = p + len;
2191
2192 if( ( ret = x509parse_key_pkcs1_der( rsa, p, end - p ) ) != 0 )
2193 return( ret );
2194
2195 return( 0 );
2196}
2197
2198/*
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002199 * Parse an unencrypted PKCS#8 encoded private RSA key
2200 */
2201static int x509parse_key_pkcs8_encrypted_der(
2202 rsa_context *rsa,
2203 const unsigned char *key,
2204 size_t keylen,
2205 const unsigned char *pwd,
2206 size_t pwdlen )
2207{
2208 int ret;
2209 size_t len;
2210 unsigned char *p, *end, *end2;
2211 x509_buf pbe_alg_oid, pbe_params;
2212 unsigned char buf[2048];
2213
2214 memset(buf, 0, 2048);
2215
2216 p = (unsigned char *) key;
2217 end = p + keylen;
2218
2219 /*
2220 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
2221 *
2222 * EncryptedPrivateKeyInfo ::= SEQUENCE {
2223 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
2224 * encryptedData EncryptedData
2225 * }
2226 *
2227 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
2228 *
2229 * EncryptedData ::= OCTET STRING
2230 *
2231 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
2232 */
2233 if( ( ret = asn1_get_tag( &p, end, &len,
2234 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2235 {
2236 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2237 }
2238
2239 end = p + len;
2240
2241 if( ( ret = asn1_get_tag( &p, end, &len,
2242 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2243 {
2244 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2245 }
2246
2247 end2 = p + len;
2248
2249 if( ( ret = asn1_get_tag( &p, end, &pbe_alg_oid.len, ASN1_OID ) ) != 0 )
2250 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2251
2252 pbe_alg_oid.p = p;
2253 p += pbe_alg_oid.len;
2254
2255 /*
2256 * Store the algorithm parameters
2257 */
2258 pbe_params.p = p;
2259 pbe_params.len = end2 - p;
2260 p += pbe_params.len;
2261
2262 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2263 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2264
2265 // buf has been sized to 2048 bytes
2266 if( len > 2048 )
2267 return( POLARSSL_ERR_X509_INVALID_INPUT );
2268
2269 /*
2270 * Decrypt EncryptedData with appropriate PDE
2271 */
2272 if( OID_CMP( OID_PKCS12_PBE_SHA1_DES3_EDE_CBC, &pbe_alg_oid ) )
2273 {
2274 if( ( ret = pkcs12_pbe_sha1_des3_ede_cbc( &pbe_params,
2275 PKCS12_PBE_DECRYPT,
2276 pwd, pwdlen,
2277 p, len, buf ) ) != 0 )
2278 {
2279 return( ret );
2280 }
2281 }
2282 else if( OID_CMP( OID_PKCS12_PBE_SHA1_DES2_EDE_CBC, &pbe_alg_oid ) )
2283 {
2284 if( ( ret = pkcs12_pbe_sha1_des2_ede_cbc( &pbe_params,
2285 PKCS12_PBE_DECRYPT,
2286 pwd, pwdlen,
2287 p, len, buf ) ) != 0 )
2288 {
2289 return( ret );
2290 }
2291 }
2292 else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) )
2293 {
2294 if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params,
2295 PKCS12_PBE_DECRYPT,
2296 pwd, pwdlen,
2297 p, len, buf ) ) != 0 )
2298 {
2299 return( ret );
2300 }
2301 }
2302 else
2303 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
2304
2305 return x509parse_key_pkcs8_unencrypted_der( rsa, buf, len );
2306}
2307
2308/*
Paul Bakker65a19092013-06-06 21:14:58 +02002309 * Parse a private RSA key
2310 */
2311int x509parse_key( rsa_context *rsa, const unsigned char *key, size_t keylen,
2312 const unsigned char *pwd, size_t pwdlen )
2313{
2314 int ret;
2315
Paul Bakker96743fc2011-02-12 14:30:57 +00002316#if defined(POLARSSL_PEM_C)
Paul Bakker65a19092013-06-06 21:14:58 +02002317 size_t len;
2318 pem_context pem;
2319
2320 pem_init( &pem );
2321 ret = pem_read_buffer( &pem,
2322 "-----BEGIN RSA PRIVATE KEY-----",
2323 "-----END RSA PRIVATE KEY-----",
2324 key, pwd, pwdlen, &len );
2325 if( ret == 0 )
2326 {
2327 if( ( ret = x509parse_key_pkcs1_der( rsa, pem.buf, pem.buflen ) ) != 0 )
2328 {
2329 rsa_free( rsa );
2330 }
2331
2332 pem_free( &pem );
2333 return( ret );
2334 }
2335 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2336 {
2337 pem_free( &pem );
2338 return( ret );
2339 }
2340
2341 ret = pem_read_buffer( &pem,
2342 "-----BEGIN PRIVATE KEY-----",
2343 "-----END PRIVATE KEY-----",
2344 key, NULL, 0, &len );
2345 if( ret == 0 )
2346 {
2347 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa,
2348 pem.buf, pem.buflen ) ) != 0 )
2349 {
2350 rsa_free( rsa );
2351 }
2352
2353 pem_free( &pem );
2354 return( ret );
2355 }
2356 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2357 {
2358 pem_free( &pem );
2359 return( ret );
2360 }
2361
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002362 ret = pem_read_buffer( &pem,
2363 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
2364 "-----END ENCRYPTED PRIVATE KEY-----",
2365 key, NULL, 0, &len );
2366 if( ret == 0 )
2367 {
2368 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa,
2369 pem.buf, pem.buflen,
2370 pwd, pwdlen ) ) != 0 )
2371 {
2372 rsa_free( rsa );
2373 }
2374
2375 pem_free( &pem );
2376 return( ret );
2377 }
2378 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2379 {
2380 pem_free( &pem );
2381 return( ret );
2382 }
Paul Bakker65a19092013-06-06 21:14:58 +02002383#else
2384 ((void) pwd);
2385 ((void) pwdlen);
2386#endif /* POLARSSL_PEM_C */
2387
2388 // At this point we only know it's not a PEM formatted key. Could be any
2389 // of the known DER encoded private key formats
2390 //
2391 // We try the different DER format parsers to see if one passes without
2392 // error
2393 //
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002394 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa, key, keylen,
2395 pwd, pwdlen ) ) == 0 )
Paul Bakker65a19092013-06-06 21:14:58 +02002396 {
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002397 return( 0 );
Paul Bakker65a19092013-06-06 21:14:58 +02002398 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002399
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002400 rsa_free( rsa );
2401 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa, key, keylen ) ) == 0 )
2402 return( 0 );
2403
2404 rsa_free( rsa );
2405 if( ( ret = x509parse_key_pkcs1_der( rsa, key, keylen ) ) == 0 )
2406 return( 0 );
2407
2408 rsa_free( rsa );
2409 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00002410}
2411
2412/*
Paul Bakker53019ae2011-03-25 13:58:48 +00002413 * Parse a public RSA key
2414 */
Paul Bakker23986e52011-04-24 08:57:21 +00002415int x509parse_public_key( rsa_context *rsa, const unsigned char *key, size_t keylen )
Paul Bakker53019ae2011-03-25 13:58:48 +00002416{
Paul Bakker23986e52011-04-24 08:57:21 +00002417 int ret;
2418 size_t len;
Paul Bakker53019ae2011-03-25 13:58:48 +00002419 unsigned char *p, *end;
2420 x509_buf alg_oid;
2421#if defined(POLARSSL_PEM_C)
2422 pem_context pem;
2423
2424 pem_init( &pem );
2425 ret = pem_read_buffer( &pem,
2426 "-----BEGIN PUBLIC KEY-----",
2427 "-----END PUBLIC KEY-----",
2428 key, NULL, 0, &len );
2429
2430 if( ret == 0 )
2431 {
2432 /*
2433 * Was PEM encoded
2434 */
2435 keylen = pem.buflen;
2436 }
Paul Bakker9255e832013-06-06 14:58:28 +02002437 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker53019ae2011-03-25 13:58:48 +00002438 {
2439 pem_free( &pem );
2440 return( ret );
2441 }
2442
2443 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2444#else
2445 p = (unsigned char *) key;
2446#endif
2447 end = p + keylen;
2448
2449 /*
2450 * PublicKeyInfo ::= SEQUENCE {
2451 * algorithm AlgorithmIdentifier,
2452 * PublicKey BIT STRING
2453 * }
2454 *
2455 * AlgorithmIdentifier ::= SEQUENCE {
2456 * algorithm OBJECT IDENTIFIER,
2457 * parameters ANY DEFINED BY algorithm OPTIONAL
2458 * }
2459 *
2460 * RSAPublicKey ::= SEQUENCE {
2461 * modulus INTEGER, -- n
2462 * publicExponent INTEGER -- e
2463 * }
2464 */
2465
2466 if( ( ret = asn1_get_tag( &p, end, &len,
2467 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2468 {
2469#if defined(POLARSSL_PEM_C)
2470 pem_free( &pem );
2471#endif
2472 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002473 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002474 }
2475
2476 if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
2477 {
2478#if defined(POLARSSL_PEM_C)
2479 pem_free( &pem );
2480#endif
2481 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002482 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002483 }
2484
2485 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
2486 {
2487#if defined(POLARSSL_PEM_C)
2488 pem_free( &pem );
2489#endif
2490 rsa_free( rsa );
2491 return( ret );
2492 }
2493
2494 rsa->len = mpi_size( &rsa->N );
2495
2496#if defined(POLARSSL_PEM_C)
2497 pem_free( &pem );
2498#endif
2499
2500 return( 0 );
2501}
2502
Paul Bakkereaa89f82011-04-04 21:36:15 +00002503#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00002504/*
Paul Bakker1b57b062011-01-06 15:48:19 +00002505 * Parse DHM parameters
2506 */
Paul Bakker23986e52011-04-24 08:57:21 +00002507int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
Paul Bakker1b57b062011-01-06 15:48:19 +00002508{
Paul Bakker23986e52011-04-24 08:57:21 +00002509 int ret;
2510 size_t len;
Paul Bakker1b57b062011-01-06 15:48:19 +00002511 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00002512#if defined(POLARSSL_PEM_C)
2513 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00002514
Paul Bakker96743fc2011-02-12 14:30:57 +00002515 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00002516
Paul Bakker96743fc2011-02-12 14:30:57 +00002517 ret = pem_read_buffer( &pem,
2518 "-----BEGIN DH PARAMETERS-----",
2519 "-----END DH PARAMETERS-----",
2520 dhmin, NULL, 0, &dhminlen );
2521
2522 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00002523 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002524 /*
2525 * Was PEM encoded
2526 */
2527 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00002528 }
Paul Bakker9255e832013-06-06 14:58:28 +02002529 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00002530 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002531 pem_free( &pem );
2532 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002533 }
2534
Paul Bakker96743fc2011-02-12 14:30:57 +00002535 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
2536#else
2537 p = (unsigned char *) dhmin;
2538#endif
2539 end = p + dhminlen;
2540
Paul Bakker1b57b062011-01-06 15:48:19 +00002541 memset( dhm, 0, sizeof( dhm_context ) );
2542
Paul Bakker1b57b062011-01-06 15:48:19 +00002543 /*
2544 * DHParams ::= SEQUENCE {
2545 * prime INTEGER, -- P
2546 * generator INTEGER, -- g
2547 * }
2548 */
2549 if( ( ret = asn1_get_tag( &p, end, &len,
2550 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2551 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002552#if defined(POLARSSL_PEM_C)
2553 pem_free( &pem );
2554#endif
Paul Bakker9d781402011-05-09 16:17:09 +00002555 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002556 }
2557
2558 end = p + len;
2559
2560 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
2561 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
2562 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002563#if defined(POLARSSL_PEM_C)
2564 pem_free( &pem );
2565#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002566 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002567 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002568 }
2569
2570 if( p != end )
2571 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002572#if defined(POLARSSL_PEM_C)
2573 pem_free( &pem );
2574#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002575 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002576 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker1b57b062011-01-06 15:48:19 +00002577 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
2578 }
2579
Paul Bakker96743fc2011-02-12 14:30:57 +00002580#if defined(POLARSSL_PEM_C)
2581 pem_free( &pem );
2582#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002583
2584 return( 0 );
2585}
2586
Paul Bakker335db3f2011-04-25 15:28:35 +00002587#if defined(POLARSSL_FS_IO)
Paul Bakker1b57b062011-01-06 15:48:19 +00002588/*
2589 * Load and parse a private RSA key
2590 */
2591int x509parse_dhmfile( dhm_context *dhm, const char *path )
2592{
2593 int ret;
2594 size_t n;
2595 unsigned char *buf;
2596
Paul Bakker69e095c2011-12-10 21:55:01 +00002597 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
2598 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002599
Paul Bakker27fdf462011-06-09 13:55:13 +00002600 ret = x509parse_dhm( dhm, buf, n );
Paul Bakker1b57b062011-01-06 15:48:19 +00002601
2602 memset( buf, 0, n + 1 );
2603 free( buf );
2604
2605 return( ret );
2606}
Paul Bakker335db3f2011-04-25 15:28:35 +00002607#endif /* POLARSSL_FS_IO */
Paul Bakkereaa89f82011-04-04 21:36:15 +00002608#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00002609
Paul Bakker5121ce52009-01-03 21:22:43 +00002610#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002611#include <stdarg.h>
2612
2613#if !defined vsnprintf
2614#define vsnprintf _vsnprintf
2615#endif // vsnprintf
2616
2617/*
2618 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2619 * Result value is not size of buffer needed, but -1 if no fit is possible.
2620 *
2621 * This fuction tries to 'fix' this by at least suggesting enlarging the
2622 * size by 20.
2623 */
2624int compat_snprintf(char *str, size_t size, const char *format, ...)
2625{
2626 va_list ap;
2627 int res = -1;
2628
2629 va_start( ap, format );
2630
2631 res = vsnprintf( str, size, format, ap );
2632
2633 va_end( ap );
2634
2635 // No quick fix possible
2636 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00002637 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002638
2639 return res;
2640}
2641
2642#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002643#endif
2644
Paul Bakkerd98030e2009-05-02 15:13:40 +00002645#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2646
2647#define SAFE_SNPRINTF() \
2648{ \
2649 if( ret == -1 ) \
2650 return( -1 ); \
2651 \
Paul Bakker23986e52011-04-24 08:57:21 +00002652 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002653 p[n - 1] = '\0'; \
2654 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2655 } \
2656 \
Paul Bakker23986e52011-04-24 08:57:21 +00002657 n -= (unsigned int) ret; \
2658 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002659}
2660
Paul Bakker5121ce52009-01-03 21:22:43 +00002661/*
2662 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002663 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002664 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002665int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002666{
Paul Bakker23986e52011-04-24 08:57:21 +00002667 int ret;
2668 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002669 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002670 const x509_name *name;
Paul Bakker5121ce52009-01-03 21:22:43 +00002671 char s[128], *p;
2672
2673 memset( s, 0, sizeof( s ) );
2674
2675 name = dn;
2676 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002677 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002678
2679 while( name != NULL )
2680 {
Paul Bakkercefb3962012-06-27 11:51:09 +00002681 if( !name->oid.p )
2682 {
2683 name = name->next;
2684 continue;
2685 }
2686
Paul Bakker74111d32011-01-15 16:57:55 +00002687 if( name != dn )
2688 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002689 ret = snprintf( p, n, ", " );
2690 SAFE_SNPRINTF();
2691 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002692
Paul Bakker535e97d2012-08-23 10:49:55 +00002693 if( name->oid.len == 3 &&
2694 memcmp( name->oid.p, OID_X520, 2 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002695 {
2696 switch( name->oid.p[2] )
2697 {
2698 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002699 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002700
2701 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002702 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002703
2704 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002705 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002706
2707 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002708 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002709
2710 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002711 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002712
2713 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002714 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002715
2716 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002717 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002718 name->oid.p[2] );
2719 break;
2720 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002721 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002722 }
Paul Bakker535e97d2012-08-23 10:49:55 +00002723 else if( name->oid.len == 9 &&
2724 memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002725 {
2726 switch( name->oid.p[8] )
2727 {
2728 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002729 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002730
2731 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002732 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002733 name->oid.p[8] );
2734 break;
2735 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002736 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002737 }
2738 else
Paul Bakker74111d32011-01-15 16:57:55 +00002739 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002740 ret = snprintf( p, n, "\?\?=" );
Paul Bakker74111d32011-01-15 16:57:55 +00002741 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002742 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002743
2744 for( i = 0; i < name->val.len; i++ )
2745 {
Paul Bakker27fdf462011-06-09 13:55:13 +00002746 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002747 break;
2748
2749 c = name->val.p[i];
2750 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2751 s[i] = '?';
2752 else s[i] = c;
2753 }
2754 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002755 ret = snprintf( p, n, "%s", s );
2756 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002757 name = name->next;
2758 }
2759
Paul Bakker23986e52011-04-24 08:57:21 +00002760 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002761}
2762
2763/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002764 * Store the serial in printable form into buf; no more
2765 * than size characters will be written
2766 */
2767int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2768{
Paul Bakker23986e52011-04-24 08:57:21 +00002769 int ret;
2770 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00002771 char *p;
2772
2773 p = buf;
2774 n = size;
2775
2776 nr = ( serial->len <= 32 )
Paul Bakker03c7c252011-11-25 12:37:37 +00002777 ? serial->len : 28;
Paul Bakkerdd476992011-01-16 21:34:59 +00002778
2779 for( i = 0; i < nr; i++ )
2780 {
Paul Bakker93048802011-12-05 14:38:06 +00002781 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002782 continue;
2783
Paul Bakkerdd476992011-01-16 21:34:59 +00002784 ret = snprintf( p, n, "%02X%s",
2785 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2786 SAFE_SNPRINTF();
2787 }
2788
Paul Bakker03c7c252011-11-25 12:37:37 +00002789 if( nr != serial->len )
2790 {
2791 ret = snprintf( p, n, "...." );
2792 SAFE_SNPRINTF();
2793 }
2794
Paul Bakker23986e52011-04-24 08:57:21 +00002795 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00002796}
2797
2798/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002799 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002800 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002801int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2802 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002803{
Paul Bakker23986e52011-04-24 08:57:21 +00002804 int ret;
2805 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002806 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00002807
2808 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002809 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002810
Paul Bakkerd98030e2009-05-02 15:13:40 +00002811 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002812 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002813 SAFE_SNPRINTF();
2814 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002815 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002816 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002817
Paul Bakkerdd476992011-01-16 21:34:59 +00002818 ret = x509parse_serial_gets( p, n, &crt->serial);
2819 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002820
Paul Bakkerd98030e2009-05-02 15:13:40 +00002821 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2822 SAFE_SNPRINTF();
2823 ret = x509parse_dn_gets( p, n, &crt->issuer );
2824 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002825
Paul Bakkerd98030e2009-05-02 15:13:40 +00002826 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2827 SAFE_SNPRINTF();
2828 ret = x509parse_dn_gets( p, n, &crt->subject );
2829 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002830
Paul Bakkerd98030e2009-05-02 15:13:40 +00002831 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002832 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2833 crt->valid_from.year, crt->valid_from.mon,
2834 crt->valid_from.day, crt->valid_from.hour,
2835 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002836 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002837
Paul Bakkerd98030e2009-05-02 15:13:40 +00002838 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002839 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2840 crt->valid_to.year, crt->valid_to.mon,
2841 crt->valid_to.day, crt->valid_to.hour,
2842 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002843 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002844
Paul Bakkerd98030e2009-05-02 15:13:40 +00002845 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2846 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002847
Paul Bakker27d66162010-03-17 06:56:01 +00002848 switch( crt->sig_alg )
Paul Bakker5121ce52009-01-03 21:22:43 +00002849 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002850 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2851 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2852 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2853 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2854 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2855 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2856 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2857 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2858 default: ret = snprintf( p, n, "???" ); break;
2859 }
2860 SAFE_SNPRINTF();
2861
2862 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
Paul Bakker5c2364c2012-10-01 14:41:15 +00002863 (int) crt->rsa.N.n * (int) sizeof( t_uint ) * 8 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002864 SAFE_SNPRINTF();
2865
Paul Bakker23986e52011-04-24 08:57:21 +00002866 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002867}
2868
Paul Bakker74111d32011-01-15 16:57:55 +00002869/*
2870 * Return an informational string describing the given OID
2871 */
2872const char *x509_oid_get_description( x509_buf *oid )
2873{
2874 if ( oid == NULL )
2875 return ( NULL );
2876
2877 else if( OID_CMP( OID_SERVER_AUTH, oid ) )
2878 return( STRING_SERVER_AUTH );
2879
2880 else if( OID_CMP( OID_CLIENT_AUTH, oid ) )
2881 return( STRING_CLIENT_AUTH );
2882
2883 else if( OID_CMP( OID_CODE_SIGNING, oid ) )
2884 return( STRING_CODE_SIGNING );
2885
2886 else if( OID_CMP( OID_EMAIL_PROTECTION, oid ) )
2887 return( STRING_EMAIL_PROTECTION );
2888
2889 else if( OID_CMP( OID_TIME_STAMPING, oid ) )
2890 return( STRING_TIME_STAMPING );
2891
2892 else if( OID_CMP( OID_OCSP_SIGNING, oid ) )
2893 return( STRING_OCSP_SIGNING );
2894
2895 return( NULL );
2896}
2897
2898/* Return the x.y.z.... style numeric string for the given OID */
2899int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2900{
Paul Bakker23986e52011-04-24 08:57:21 +00002901 int ret;
2902 size_t i, n;
Paul Bakker74111d32011-01-15 16:57:55 +00002903 unsigned int value;
2904 char *p;
2905
2906 p = buf;
2907 n = size;
2908
2909 /* First byte contains first two dots */
2910 if( oid->len > 0 )
2911 {
2912 ret = snprintf( p, n, "%d.%d", oid->p[0]/40, oid->p[0]%40 );
2913 SAFE_SNPRINTF();
2914 }
2915
2916 /* TODO: value can overflow in value. */
2917 value = 0;
Paul Bakker23986e52011-04-24 08:57:21 +00002918 for( i = 1; i < oid->len; i++ )
Paul Bakker74111d32011-01-15 16:57:55 +00002919 {
2920 value <<= 7;
2921 value += oid->p[i] & 0x7F;
2922
2923 if( !( oid->p[i] & 0x80 ) )
2924 {
2925 /* Last byte */
2926 ret = snprintf( p, n, ".%d", value );
2927 SAFE_SNPRINTF();
2928 value = 0;
2929 }
2930 }
2931
Paul Bakker23986e52011-04-24 08:57:21 +00002932 return( (int) ( size - n ) );
Paul Bakker74111d32011-01-15 16:57:55 +00002933}
2934
Paul Bakkerd98030e2009-05-02 15:13:40 +00002935/*
2936 * Return an informational string about the CRL.
2937 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002938int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2939 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002940{
Paul Bakker23986e52011-04-24 08:57:21 +00002941 int ret;
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002942 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002943 char *p;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002944 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002945
2946 p = buf;
2947 n = size;
2948
2949 ret = snprintf( p, n, "%sCRL version : %d",
2950 prefix, crl->version );
2951 SAFE_SNPRINTF();
2952
2953 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2954 SAFE_SNPRINTF();
2955 ret = x509parse_dn_gets( p, n, &crl->issuer );
2956 SAFE_SNPRINTF();
2957
2958 ret = snprintf( p, n, "\n%sthis update : " \
2959 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2960 crl->this_update.year, crl->this_update.mon,
2961 crl->this_update.day, crl->this_update.hour,
2962 crl->this_update.min, crl->this_update.sec );
2963 SAFE_SNPRINTF();
2964
2965 ret = snprintf( p, n, "\n%snext update : " \
2966 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2967 crl->next_update.year, crl->next_update.mon,
2968 crl->next_update.day, crl->next_update.hour,
2969 crl->next_update.min, crl->next_update.sec );
2970 SAFE_SNPRINTF();
2971
2972 entry = &crl->entry;
2973
2974 ret = snprintf( p, n, "\n%sRevoked certificates:",
2975 prefix );
2976 SAFE_SNPRINTF();
2977
Paul Bakker9be19372009-07-27 20:21:53 +00002978 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002979 {
2980 ret = snprintf( p, n, "\n%sserial number: ",
2981 prefix );
2982 SAFE_SNPRINTF();
2983
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002984 ret = x509parse_serial_gets( p, n, &entry->serial);
2985 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002986
Paul Bakkerd98030e2009-05-02 15:13:40 +00002987 ret = snprintf( p, n, " revocation date: " \
2988 "%04d-%02d-%02d %02d:%02d:%02d",
2989 entry->revocation_date.year, entry->revocation_date.mon,
2990 entry->revocation_date.day, entry->revocation_date.hour,
2991 entry->revocation_date.min, entry->revocation_date.sec );
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002992 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002993
2994 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002995 }
2996
Paul Bakkerd98030e2009-05-02 15:13:40 +00002997 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2998 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002999
Paul Bakker27d66162010-03-17 06:56:01 +00003000 switch( crl->sig_alg )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003001 {
3002 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
3003 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
3004 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
3005 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
3006 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
3007 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
3008 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
3009 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
3010 default: ret = snprintf( p, n, "???" ); break;
3011 }
3012 SAFE_SNPRINTF();
3013
Paul Bakker1e27bb22009-07-19 20:25:25 +00003014 ret = snprintf( p, n, "\n" );
3015 SAFE_SNPRINTF();
3016
Paul Bakker23986e52011-04-24 08:57:21 +00003017 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003018}
3019
3020/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00003021 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00003022 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003023int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00003024{
Paul Bakkercce9d772011-11-18 14:26:47 +00003025 int year, mon, day;
3026 int hour, min, sec;
3027
3028#if defined(_WIN32)
3029 SYSTEMTIME st;
3030
3031 GetLocalTime(&st);
3032
3033 year = st.wYear;
3034 mon = st.wMonth;
3035 day = st.wDay;
3036 hour = st.wHour;
3037 min = st.wMinute;
3038 sec = st.wSecond;
3039#else
Paul Bakker5121ce52009-01-03 21:22:43 +00003040 struct tm *lt;
3041 time_t tt;
3042
3043 tt = time( NULL );
3044 lt = localtime( &tt );
3045
Paul Bakkercce9d772011-11-18 14:26:47 +00003046 year = lt->tm_year + 1900;
3047 mon = lt->tm_mon + 1;
3048 day = lt->tm_mday;
3049 hour = lt->tm_hour;
3050 min = lt->tm_min;
3051 sec = lt->tm_sec;
3052#endif
3053
3054 if( year > to->year )
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 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003059 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003060
Paul Bakkercce9d772011-11-18 14:26:47 +00003061 if( year == to->year &&
3062 mon == to->mon &&
3063 day > to->day )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003064 return( 1 );
3065
Paul Bakkercce9d772011-11-18 14:26:47 +00003066 if( year == to->year &&
3067 mon == to->mon &&
3068 day == to->day &&
3069 hour > to->hour )
Paul Bakkerb6194992011-01-16 21:40:22 +00003070 return( 1 );
3071
Paul Bakkercce9d772011-11-18 14:26:47 +00003072 if( year == to->year &&
3073 mon == to->mon &&
3074 day == to->day &&
3075 hour == to->hour &&
3076 min > to->min )
Paul Bakkerb6194992011-01-16 21:40:22 +00003077 return( 1 );
3078
Paul Bakkercce9d772011-11-18 14:26:47 +00003079 if( year == to->year &&
3080 mon == to->mon &&
3081 day == to->day &&
3082 hour == to->hour &&
3083 min == to->min &&
3084 sec > to->sec )
Paul Bakkerb6194992011-01-16 21:40:22 +00003085 return( 1 );
3086
Paul Bakker40ea7de2009-05-03 10:18:48 +00003087 return( 0 );
3088}
3089
3090/*
3091 * Return 1 if the certificate is revoked, or 0 otherwise.
3092 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003093int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003094{
Paul Bakkerff60ee62010-03-16 21:09:09 +00003095 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00003096
3097 while( cur != NULL && cur->serial.len != 0 )
3098 {
Paul Bakkera056efc2011-01-16 21:38:35 +00003099 if( crt->serial.len == cur->serial.len &&
3100 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003101 {
3102 if( x509parse_time_expired( &cur->revocation_date ) )
3103 return( 1 );
3104 }
3105
3106 cur = cur->next;
3107 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003108
3109 return( 0 );
3110}
3111
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003112/*
3113 * Wrapper for x509 hashes.
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003114 */
Paul Bakker23986e52011-04-24 08:57:21 +00003115static void x509_hash( const unsigned char *in, size_t len, int alg,
Paul Bakker5121ce52009-01-03 21:22:43 +00003116 unsigned char *out )
3117{
3118 switch( alg )
3119 {
Paul Bakker40e46942009-01-03 21:51:57 +00003120#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003121 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003122#endif
Paul Bakker40e46942009-01-03 21:51:57 +00003123#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003124 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003125#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003126#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003127 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003128#endif
3129#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003130 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003131#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00003132#if defined(POLARSSL_SHA2_C)
3133 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
3134 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
3135#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00003136#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003137 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
3138 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
3139#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003140 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003141 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003142 break;
3143 }
3144}
3145
3146/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00003147 * Check that the given certificate is valid accoring to the CRL.
3148 */
3149static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
3150 x509_crl *crl_list)
3151{
3152 int flags = 0;
3153 int hash_id;
3154 unsigned char hash[64];
3155
Paul Bakker915275b2012-09-28 07:10:55 +00003156 if( ca == NULL )
3157 return( flags );
3158
Paul Bakker76fd75a2011-01-16 21:12:10 +00003159 /*
3160 * TODO: What happens if no CRL is present?
3161 * Suggestion: Revocation state should be unknown if no CRL is present.
3162 * For backwards compatibility this is not yet implemented.
3163 */
3164
Paul Bakker915275b2012-09-28 07:10:55 +00003165 while( crl_list != NULL )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003166 {
Paul Bakker915275b2012-09-28 07:10:55 +00003167 if( crl_list->version == 0 ||
3168 crl_list->issuer_raw.len != ca->subject_raw.len ||
Paul Bakker76fd75a2011-01-16 21:12:10 +00003169 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
3170 crl_list->issuer_raw.len ) != 0 )
3171 {
3172 crl_list = crl_list->next;
3173 continue;
3174 }
3175
3176 /*
3177 * Check if CRL is correctly signed by the trusted CA
3178 */
3179 hash_id = crl_list->sig_alg;
3180
3181 x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
3182
3183 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, hash_id,
3184 0, hash, crl_list->sig.p ) == 0 )
3185 {
3186 /*
3187 * CRL is not trusted
3188 */
3189 flags |= BADCRL_NOT_TRUSTED;
3190 break;
3191 }
3192
3193 /*
3194 * Check for validity of CRL (Do not drop out)
3195 */
3196 if( x509parse_time_expired( &crl_list->next_update ) )
3197 flags |= BADCRL_EXPIRED;
3198
3199 /*
3200 * Check if certificate is revoked
3201 */
3202 if( x509parse_revoked(crt, crl_list) )
3203 {
3204 flags |= BADCERT_REVOKED;
3205 break;
3206 }
3207
3208 crl_list = crl_list->next;
3209 }
3210 return flags;
3211}
3212
Paul Bakker57b12982012-02-11 17:38:38 +00003213int x509_wildcard_verify( const char *cn, x509_buf *name )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003214{
3215 size_t i;
3216 size_t cn_idx = 0;
3217
Paul Bakker57b12982012-02-11 17:38:38 +00003218 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003219 return( 0 );
3220
3221 for( i = 0; i < strlen( cn ); ++i )
3222 {
3223 if( cn[i] == '.' )
3224 {
3225 cn_idx = i;
3226 break;
3227 }
3228 }
3229
3230 if( cn_idx == 0 )
3231 return( 0 );
3232
Paul Bakker535e97d2012-08-23 10:49:55 +00003233 if( strlen( cn ) - cn_idx == name->len - 1 &&
3234 memcmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003235 {
3236 return( 1 );
3237 }
3238
3239 return( 0 );
3240}
3241
Paul Bakker915275b2012-09-28 07:10:55 +00003242static int x509parse_verify_top(
3243 x509_cert *child, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003244 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003245 int (*f_vrfy)(void *, x509_cert *, int, int *),
3246 void *p_vrfy )
3247{
3248 int hash_id, ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003249 int ca_flags = 0, check_path_cnt = path_cnt + 1;
Paul Bakker915275b2012-09-28 07:10:55 +00003250 unsigned char hash[64];
3251
3252 if( x509parse_time_expired( &child->valid_to ) )
3253 *flags |= BADCERT_EXPIRED;
3254
3255 /*
3256 * Child is the top of the chain. Check against the trust_ca list.
3257 */
3258 *flags |= BADCERT_NOT_TRUSTED;
3259
3260 while( trust_ca != NULL )
3261 {
3262 if( trust_ca->version == 0 ||
3263 child->issuer_raw.len != trust_ca->subject_raw.len ||
3264 memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
3265 child->issuer_raw.len ) != 0 )
3266 {
3267 trust_ca = trust_ca->next;
3268 continue;
3269 }
3270
Paul Bakker9a736322012-11-14 12:39:52 +00003271 /*
3272 * Reduce path_len to check against if top of the chain is
3273 * the same as the trusted CA
3274 */
3275 if( child->subject_raw.len == trust_ca->subject_raw.len &&
3276 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3277 child->issuer_raw.len ) == 0 )
3278 {
3279 check_path_cnt--;
3280 }
3281
Paul Bakker915275b2012-09-28 07:10:55 +00003282 if( trust_ca->max_pathlen > 0 &&
Paul Bakker9a736322012-11-14 12:39:52 +00003283 trust_ca->max_pathlen < check_path_cnt )
Paul Bakker915275b2012-09-28 07:10:55 +00003284 {
3285 trust_ca = trust_ca->next;
3286 continue;
3287 }
3288
3289 hash_id = child->sig_alg;
3290
3291 x509_hash( child->tbs.p, child->tbs.len, hash_id, hash );
3292
3293 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
3294 0, hash, child->sig.p ) != 0 )
3295 {
3296 trust_ca = trust_ca->next;
3297 continue;
3298 }
3299
3300 /*
3301 * Top of chain is signed by a trusted CA
3302 */
3303 *flags &= ~BADCERT_NOT_TRUSTED;
3304 break;
3305 }
3306
Paul Bakker9a736322012-11-14 12:39:52 +00003307 /*
Paul Bakker3497d8c2012-11-24 11:53:17 +01003308 * If top of chain is not the same as the trusted CA send a verify request
3309 * to the callback for any issues with validity and CRL presence for the
3310 * trusted CA certificate.
Paul Bakker9a736322012-11-14 12:39:52 +00003311 */
3312 if( trust_ca != NULL &&
3313 ( child->subject_raw.len != trust_ca->subject_raw.len ||
3314 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3315 child->issuer_raw.len ) != 0 ) )
Paul Bakker915275b2012-09-28 07:10:55 +00003316 {
3317 /* Check trusted CA's CRL for then chain's top crt */
3318 *flags |= x509parse_verifycrl( child, trust_ca, ca_crl );
3319
3320 if( x509parse_time_expired( &trust_ca->valid_to ) )
3321 ca_flags |= BADCERT_EXPIRED;
3322
Paul Bakker915275b2012-09-28 07:10:55 +00003323 if( NULL != f_vrfy )
3324 {
Paul Bakker9a736322012-11-14 12:39:52 +00003325 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003326 return( ret );
3327 }
3328 }
3329
3330 /* Call callback on top cert */
3331 if( NULL != f_vrfy )
3332 {
Paul Bakker9a736322012-11-14 12:39:52 +00003333 if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003334 return( ret );
3335 }
3336
Paul Bakker915275b2012-09-28 07:10:55 +00003337 *flags |= ca_flags;
3338
3339 return( 0 );
3340}
3341
3342static int x509parse_verify_child(
3343 x509_cert *child, x509_cert *parent, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003344 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003345 int (*f_vrfy)(void *, x509_cert *, int, int *),
3346 void *p_vrfy )
3347{
3348 int hash_id, ret;
3349 int parent_flags = 0;
3350 unsigned char hash[64];
3351 x509_cert *grandparent;
3352
3353 if( x509parse_time_expired( &child->valid_to ) )
3354 *flags |= BADCERT_EXPIRED;
3355
3356 hash_id = child->sig_alg;
3357
3358 x509_hash( child->tbs.p, child->tbs.len, hash_id, hash );
3359
3360 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, hash_id, 0, hash,
3361 child->sig.p ) != 0 )
3362 *flags |= BADCERT_NOT_TRUSTED;
3363
3364 /* Check trusted CA's CRL for the given crt */
3365 *flags |= x509parse_verifycrl(child, parent, ca_crl);
3366
3367 grandparent = parent->next;
3368
3369 while( grandparent != NULL )
3370 {
3371 if( grandparent->version == 0 ||
3372 grandparent->ca_istrue == 0 ||
3373 parent->issuer_raw.len != grandparent->subject_raw.len ||
3374 memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
3375 parent->issuer_raw.len ) != 0 )
3376 {
3377 grandparent = grandparent->next;
3378 continue;
3379 }
3380 break;
3381 }
3382
Paul Bakker915275b2012-09-28 07:10:55 +00003383 if( grandparent != NULL )
3384 {
3385 /*
3386 * Part of the chain
3387 */
Paul Bakker9a736322012-11-14 12:39:52 +00003388 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 +00003389 if( ret != 0 )
3390 return( ret );
3391 }
3392 else
3393 {
Paul Bakker9a736322012-11-14 12:39:52 +00003394 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 +00003395 if( ret != 0 )
3396 return( ret );
3397 }
3398
3399 /* child is verified to be a child of the parent, call verify callback */
3400 if( NULL != f_vrfy )
Paul Bakker9a736322012-11-14 12:39:52 +00003401 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003402 return( ret );
Paul Bakker915275b2012-09-28 07:10:55 +00003403
3404 *flags |= parent_flags;
3405
3406 return( 0 );
3407}
3408
Paul Bakker76fd75a2011-01-16 21:12:10 +00003409/*
Paul Bakker5121ce52009-01-03 21:22:43 +00003410 * Verify the certificate validity
3411 */
3412int x509parse_verify( x509_cert *crt,
3413 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00003414 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003415 const char *cn, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003416 int (*f_vrfy)(void *, x509_cert *, int, int *),
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003417 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00003418{
Paul Bakker23986e52011-04-24 08:57:21 +00003419 size_t cn_len;
Paul Bakker915275b2012-09-28 07:10:55 +00003420 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003421 int pathlen = 0;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003422 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00003423 x509_name *name;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003424 x509_sequence *cur = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003425
Paul Bakker40ea7de2009-05-03 10:18:48 +00003426 *flags = 0;
3427
Paul Bakker5121ce52009-01-03 21:22:43 +00003428 if( cn != NULL )
3429 {
3430 name = &crt->subject;
3431 cn_len = strlen( cn );
3432
Paul Bakker4d2c1242012-05-10 14:12:46 +00003433 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
Paul Bakker5121ce52009-01-03 21:22:43 +00003434 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00003435 cur = &crt->subject_alt_names;
3436
3437 while( cur != NULL )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003438 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003439 if( cur->buf.len == cn_len &&
3440 memcmp( cn, cur->buf.p, cn_len ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003441 break;
3442
Paul Bakker535e97d2012-08-23 10:49:55 +00003443 if( cur->buf.len > 2 &&
3444 memcmp( cur->buf.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003445 x509_wildcard_verify( cn, &cur->buf ) )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003446 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003447
Paul Bakker4d2c1242012-05-10 14:12:46 +00003448 cur = cur->next;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003449 }
3450
3451 if( cur == NULL )
3452 *flags |= BADCERT_CN_MISMATCH;
3453 }
Paul Bakker4d2c1242012-05-10 14:12:46 +00003454 else
3455 {
3456 while( name != NULL )
3457 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003458 if( name->oid.len == 3 &&
3459 memcmp( name->oid.p, OID_CN, 3 ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003460 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003461 if( name->val.len == cn_len &&
3462 memcmp( name->val.p, cn, cn_len ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003463 break;
3464
Paul Bakker535e97d2012-08-23 10:49:55 +00003465 if( name->val.len > 2 &&
3466 memcmp( name->val.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003467 x509_wildcard_verify( cn, &name->val ) )
3468 break;
3469 }
3470
3471 name = name->next;
3472 }
3473
3474 if( name == NULL )
3475 *flags |= BADCERT_CN_MISMATCH;
3476 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003477 }
3478
Paul Bakker5121ce52009-01-03 21:22:43 +00003479 /*
Paul Bakker915275b2012-09-28 07:10:55 +00003480 * Iterate upwards in the given cert chain, to find our crt parent.
3481 * Ignore any upper cert with CA != TRUE.
Paul Bakker5121ce52009-01-03 21:22:43 +00003482 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003483 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003484
Paul Bakker76fd75a2011-01-16 21:12:10 +00003485 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003486 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003487 if( parent->ca_istrue == 0 ||
3488 crt->issuer_raw.len != parent->subject_raw.len ||
3489 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00003490 crt->issuer_raw.len ) != 0 )
3491 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003492 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003493 continue;
3494 }
Paul Bakker915275b2012-09-28 07:10:55 +00003495 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003496 }
3497
Paul Bakker915275b2012-09-28 07:10:55 +00003498 if( parent != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003499 {
Paul Bakker915275b2012-09-28 07:10:55 +00003500 /*
3501 * Part of the chain
3502 */
Paul Bakker9a736322012-11-14 12:39:52 +00003503 ret = x509parse_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003504 if( ret != 0 )
3505 return( ret );
3506 }
3507 else
Paul Bakker74111d32011-01-15 16:57:55 +00003508 {
Paul Bakker9a736322012-11-14 12:39:52 +00003509 ret = x509parse_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003510 if( ret != 0 )
3511 return( ret );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003512 }
Paul Bakker915275b2012-09-28 07:10:55 +00003513
3514 if( *flags != 0 )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003515 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003516
Paul Bakker5121ce52009-01-03 21:22:43 +00003517 return( 0 );
3518}
3519
3520/*
3521 * Unallocate all certificate data
3522 */
3523void x509_free( x509_cert *crt )
3524{
3525 x509_cert *cert_cur = crt;
3526 x509_cert *cert_prv;
3527 x509_name *name_cur;
3528 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00003529 x509_sequence *seq_cur;
3530 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00003531
3532 if( crt == NULL )
3533 return;
3534
3535 do
3536 {
3537 rsa_free( &cert_cur->rsa );
3538
3539 name_cur = cert_cur->issuer.next;
3540 while( name_cur != NULL )
3541 {
3542 name_prv = name_cur;
3543 name_cur = name_cur->next;
3544 memset( name_prv, 0, sizeof( x509_name ) );
3545 free( name_prv );
3546 }
3547
3548 name_cur = cert_cur->subject.next;
3549 while( name_cur != NULL )
3550 {
3551 name_prv = name_cur;
3552 name_cur = name_cur->next;
3553 memset( name_prv, 0, sizeof( x509_name ) );
3554 free( name_prv );
3555 }
3556
Paul Bakker74111d32011-01-15 16:57:55 +00003557 seq_cur = cert_cur->ext_key_usage.next;
3558 while( seq_cur != NULL )
3559 {
3560 seq_prv = seq_cur;
3561 seq_cur = seq_cur->next;
3562 memset( seq_prv, 0, sizeof( x509_sequence ) );
3563 free( seq_prv );
3564 }
3565
Paul Bakker8afa70d2012-02-11 18:42:45 +00003566 seq_cur = cert_cur->subject_alt_names.next;
3567 while( seq_cur != NULL )
3568 {
3569 seq_prv = seq_cur;
3570 seq_cur = seq_cur->next;
3571 memset( seq_prv, 0, sizeof( x509_sequence ) );
3572 free( seq_prv );
3573 }
3574
Paul Bakker5121ce52009-01-03 21:22:43 +00003575 if( cert_cur->raw.p != NULL )
3576 {
3577 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
3578 free( cert_cur->raw.p );
3579 }
3580
3581 cert_cur = cert_cur->next;
3582 }
3583 while( cert_cur != NULL );
3584
3585 cert_cur = crt;
3586 do
3587 {
3588 cert_prv = cert_cur;
3589 cert_cur = cert_cur->next;
3590
3591 memset( cert_prv, 0, sizeof( x509_cert ) );
3592 if( cert_prv != crt )
3593 free( cert_prv );
3594 }
3595 while( cert_cur != NULL );
3596}
3597
Paul Bakkerd98030e2009-05-02 15:13:40 +00003598/*
3599 * Unallocate all CRL data
3600 */
3601void x509_crl_free( x509_crl *crl )
3602{
3603 x509_crl *crl_cur = crl;
3604 x509_crl *crl_prv;
3605 x509_name *name_cur;
3606 x509_name *name_prv;
3607 x509_crl_entry *entry_cur;
3608 x509_crl_entry *entry_prv;
3609
3610 if( crl == NULL )
3611 return;
3612
3613 do
3614 {
3615 name_cur = crl_cur->issuer.next;
3616 while( name_cur != NULL )
3617 {
3618 name_prv = name_cur;
3619 name_cur = name_cur->next;
3620 memset( name_prv, 0, sizeof( x509_name ) );
3621 free( name_prv );
3622 }
3623
3624 entry_cur = crl_cur->entry.next;
3625 while( entry_cur != NULL )
3626 {
3627 entry_prv = entry_cur;
3628 entry_cur = entry_cur->next;
3629 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
3630 free( entry_prv );
3631 }
3632
3633 if( crl_cur->raw.p != NULL )
3634 {
3635 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
3636 free( crl_cur->raw.p );
3637 }
3638
3639 crl_cur = crl_cur->next;
3640 }
3641 while( crl_cur != NULL );
3642
3643 crl_cur = crl;
3644 do
3645 {
3646 crl_prv = crl_cur;
3647 crl_cur = crl_cur->next;
3648
3649 memset( crl_prv, 0, sizeof( x509_crl ) );
3650 if( crl_prv != crl )
3651 free( crl_prv );
3652 }
3653 while( crl_cur != NULL );
3654}
3655
Paul Bakker40e46942009-01-03 21:51:57 +00003656#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00003657
Paul Bakker40e46942009-01-03 21:51:57 +00003658#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00003659
3660/*
3661 * Checkup routine
3662 */
3663int x509_self_test( int verbose )
3664{
Paul Bakker5690efc2011-05-26 13:16:06 +00003665#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00003666 int ret;
3667 int flags;
3668 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00003669 x509_cert cacert;
3670 x509_cert clicert;
3671 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00003672#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003673 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00003674#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003675
3676 if( verbose != 0 )
3677 printf( " X.509 certificate load: " );
3678
3679 memset( &clicert, 0, sizeof( x509_cert ) );
3680
Paul Bakkereae09db2013-06-06 12:35:54 +02003681 ret = x509parse_crt( &clicert, (const unsigned char *) test_cli_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003682 strlen( test_cli_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003683 if( ret != 0 )
3684 {
3685 if( verbose != 0 )
3686 printf( "failed\n" );
3687
3688 return( ret );
3689 }
3690
3691 memset( &cacert, 0, sizeof( x509_cert ) );
3692
Paul Bakkereae09db2013-06-06 12:35:54 +02003693 ret = x509parse_crt( &cacert, (const unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003694 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003695 if( ret != 0 )
3696 {
3697 if( verbose != 0 )
3698 printf( "failed\n" );
3699
3700 return( ret );
3701 }
3702
3703 if( verbose != 0 )
3704 printf( "passed\n X.509 private key load: " );
3705
3706 i = strlen( test_ca_key );
3707 j = strlen( test_ca_pwd );
3708
Paul Bakker66b78b22011-03-25 14:22:50 +00003709 rsa_init( &rsa, RSA_PKCS_V15, 0 );
3710
Paul Bakker5121ce52009-01-03 21:22:43 +00003711 if( ( ret = x509parse_key( &rsa,
Paul Bakkereae09db2013-06-06 12:35:54 +02003712 (const unsigned char *) test_ca_key, i,
3713 (const unsigned char *) test_ca_pwd, j ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003714 {
3715 if( verbose != 0 )
3716 printf( "failed\n" );
3717
3718 return( ret );
3719 }
3720
3721 if( verbose != 0 )
3722 printf( "passed\n X.509 signature verify: ");
3723
Paul Bakker23986e52011-04-24 08:57:21 +00003724 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003725 if( ret != 0 )
3726 {
Paul Bakker23986e52011-04-24 08:57:21 +00003727 printf("%02x", flags);
Paul Bakker5121ce52009-01-03 21:22:43 +00003728 if( verbose != 0 )
3729 printf( "failed\n" );
3730
3731 return( ret );
3732 }
3733
Paul Bakker5690efc2011-05-26 13:16:06 +00003734#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003735 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003736 printf( "passed\n X.509 DHM parameter load: " );
3737
3738 i = strlen( test_dhm_params );
3739 j = strlen( test_ca_pwd );
3740
Paul Bakkereae09db2013-06-06 12:35:54 +02003741 if( ( ret = x509parse_dhm( &dhm, (const unsigned char *) test_dhm_params, i ) ) != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003742 {
3743 if( verbose != 0 )
3744 printf( "failed\n" );
3745
3746 return( ret );
3747 }
3748
3749 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003750 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00003751#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003752
3753 x509_free( &cacert );
3754 x509_free( &clicert );
3755 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00003756#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003757 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00003758#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003759
3760 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003761#else
3762 ((void) verbose);
3763 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3764#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003765}
3766
3767#endif
3768
3769#endif