blob: 0ec5e6802bd9f27aa6b6b87efd642150eecdfdc4 [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 Bakkerc70b9822013-04-07 22:00:46 +020043#include "polarssl/oid.h"
Paul Bakker96743fc2011-02-12 14:30:57 +000044#include "polarssl/pem.h"
Paul Bakker40e46942009-01-03 21:51:57 +000045#include "polarssl/des.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010046#if defined(POLARSSL_MD2_C)
Paul Bakker40e46942009-01-03 21:51:57 +000047#include "polarssl/md2.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010048#endif
49#if defined(POLARSSL_MD4_C)
Paul Bakker40e46942009-01-03 21:51:57 +000050#include "polarssl/md4.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010051#endif
52#if defined(POLARSSL_MD5_C)
Paul Bakker40e46942009-01-03 21:51:57 +000053#include "polarssl/md5.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010054#endif
55#if defined(POLARSSL_SHA1_C)
Paul Bakker40e46942009-01-03 21:51:57 +000056#include "polarssl/sha1.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010057#endif
58#if defined(POLARSSL_SHA2_C)
Paul Bakker026c03b2009-03-28 17:53:03 +000059#include "polarssl/sha2.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010060#endif
61#if defined(POLARSSL_SHA4_C)
Paul Bakker026c03b2009-03-28 17:53:03 +000062#include "polarssl/sha4.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010063#endif
Paul Bakker1b57b062011-01-06 15:48:19 +000064#include "polarssl/dhm.h"
Paul Bakkerf1f21fe2013-06-24 19:17:19 +020065#include "polarssl/pkcs12.h"
Paul Bakker28144de2013-06-24 19:28:55 +020066#if defined(POLARSSL_PKCS5_C)
67#include "polarssl/pkcs5.h"
68#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000069
70#include <string.h>
71#include <stdlib.h>
Paul Bakker4f229e52011-12-04 22:11:35 +000072#if defined(_WIN32)
Paul Bakkercce9d772011-11-18 14:26:47 +000073#include <windows.h>
74#else
Paul Bakker5121ce52009-01-03 21:22:43 +000075#include <time.h>
Paul Bakkercce9d772011-11-18 14:26:47 +000076#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000077
Paul Bakker335db3f2011-04-25 15:28:35 +000078#if defined(POLARSSL_FS_IO)
79#include <stdio.h>
Paul Bakker4a2bd0d2012-11-02 11:06:08 +000080#if !defined(_WIN32)
Paul Bakker8d914582012-06-04 12:46:42 +000081#include <sys/types.h>
Paul Bakker2c8cdd22013-06-24 19:22:42 +020082#include <sys/stat.h>
Paul Bakker8d914582012-06-04 12:46:42 +000083#include <dirent.h>
84#endif
Paul Bakker335db3f2011-04-25 15:28:35 +000085#endif
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 Bakkerc70b9822013-04-07 22:00:46 +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;
Paul Bakkerc70b9822013-04-07 22:00:46 +0200450 pk_type_t pk_alg = POLARSSL_PK_NONE;
Paul Bakker5121ce52009-01-03 21:22:43 +0000451
452 if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 )
453 return( ret );
454
455 /*
456 * only RSA public keys handled at this time
457 */
Paul Bakkerc70b9822013-04-07 22:00:46 +0200458 if( oid_get_pk_alg( pk_alg_oid, &pk_alg ) != 0 )
Paul Bakkered56b222011-07-13 11:26:43 +0000459 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000460
461 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000462 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000463
464 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000465 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000466 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000467
468 end2 = *p + len;
469
470 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000471 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000472
473 /*
474 * RSAPublicKey ::= SEQUENCE {
475 * modulus INTEGER, -- n
476 * publicExponent INTEGER -- e
477 * }
478 */
479 if( ( ret = asn1_get_tag( p, end2, &len,
480 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000481 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000482
483 if( *p + len != end2 )
Paul Bakker9d781402011-05-09 16:17:09 +0000484 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000485 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000486
487 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
488 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000489 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000490
491 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000492 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000493 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000494
495 return( 0 );
496}
497
498static int x509_get_sig( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000499 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000500 x509_buf *sig )
501{
Paul Bakker23986e52011-04-24 08:57:21 +0000502 int ret;
503 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000504
Paul Bakker8afa70d2012-02-11 18:42:45 +0000505 if( ( end - *p ) < 1 )
506 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE +
507 POLARSSL_ERR_ASN1_OUT_OF_DATA );
508
Paul Bakker5121ce52009-01-03 21:22:43 +0000509 sig->tag = **p;
510
511 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000512 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000513
Paul Bakker74111d32011-01-15 16:57:55 +0000514
Paul Bakker5121ce52009-01-03 21:22:43 +0000515 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000516 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000517
518 sig->len = len;
519 sig->p = *p;
520
521 *p += len;
522
523 return( 0 );
524}
525
526/*
527 * X.509 v2/v3 unique identifier (not parsed)
528 */
529static int x509_get_uid( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000530 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000531 x509_buf *uid, int n )
532{
533 int ret;
534
535 if( *p == end )
536 return( 0 );
537
538 uid->tag = **p;
539
540 if( ( ret = asn1_get_tag( p, end, &uid->len,
541 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
542 {
Paul Bakker40e46942009-01-03 21:51:57 +0000543 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000544 return( 0 );
545
546 return( ret );
547 }
548
549 uid->p = *p;
550 *p += uid->len;
551
552 return( 0 );
553}
554
555/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000556 * X.509 Extensions (No parsing of extensions, pointer should
557 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000558 */
559static int x509_get_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000560 const unsigned char *end,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000561 x509_buf *ext, int tag )
Paul Bakker5121ce52009-01-03 21:22:43 +0000562{
Paul Bakker23986e52011-04-24 08:57:21 +0000563 int ret;
564 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000565
566 if( *p == end )
567 return( 0 );
568
569 ext->tag = **p;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000570
Paul Bakker5121ce52009-01-03 21:22:43 +0000571 if( ( ret = asn1_get_tag( p, end, &ext->len,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000572 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000573 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000574
575 ext->p = *p;
576 end = *p + ext->len;
577
578 /*
579 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
580 *
581 * Extension ::= SEQUENCE {
582 * extnID OBJECT IDENTIFIER,
583 * critical BOOLEAN DEFAULT FALSE,
584 * extnValue OCTET STRING }
585 */
586 if( ( ret = asn1_get_tag( p, end, &len,
587 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000588 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000589
590 if( end != *p + len )
Paul Bakker9d781402011-05-09 16:17:09 +0000591 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +0000592 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000593
Paul Bakkerd98030e2009-05-02 15:13:40 +0000594 return( 0 );
595}
596
597/*
598 * X.509 CRL v2 extensions (no extensions parsed yet.)
599 */
600static int x509_get_crl_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000601 const unsigned char *end,
602 x509_buf *ext )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000603{
Paul Bakker23986e52011-04-24 08:57:21 +0000604 int ret;
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000605 size_t len = 0;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000606
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000607 /* Get explicit tag */
608 if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000609 {
610 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
611 return( 0 );
612
613 return( ret );
614 }
615
616 while( *p < end )
617 {
618 if( ( ret = asn1_get_tag( p, end, &len,
619 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000620 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000621
622 *p += len;
623 }
624
625 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000626 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerd98030e2009-05-02 15:13:40 +0000627 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
628
629 return( 0 );
630}
631
Paul Bakkerb5a11ab2011-10-12 09:58:41 +0000632/*
633 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
634 */
635static int x509_get_crl_entry_ext( unsigned char **p,
636 const unsigned char *end,
637 x509_buf *ext )
638{
639 int ret;
640 size_t len = 0;
641
642 /* OPTIONAL */
643 if (end <= *p)
644 return( 0 );
645
646 ext->tag = **p;
647 ext->p = *p;
648
649 /*
650 * Get CRL-entry extension sequence header
651 * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
652 */
653 if( ( ret = asn1_get_tag( p, end, &ext->len,
654 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
655 {
656 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
657 {
658 ext->p = NULL;
659 return( 0 );
660 }
661 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
662 }
663
664 end = *p + ext->len;
665
666 if( end != *p + ext->len )
667 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
668 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
669
670 while( *p < end )
671 {
672 if( ( ret = asn1_get_tag( p, end, &len,
673 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
674 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
675
676 *p += len;
677 }
678
679 if( *p != end )
680 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
681 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
682
683 return( 0 );
684}
685
Paul Bakker74111d32011-01-15 16:57:55 +0000686static int x509_get_basic_constraints( unsigned char **p,
687 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000688 int *ca_istrue,
689 int *max_pathlen )
690{
Paul Bakker23986e52011-04-24 08:57:21 +0000691 int ret;
692 size_t len;
Paul Bakker74111d32011-01-15 16:57:55 +0000693
694 /*
695 * BasicConstraints ::= SEQUENCE {
696 * cA BOOLEAN DEFAULT FALSE,
697 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
698 */
Paul Bakker3cccddb2011-01-16 21:46:31 +0000699 *ca_istrue = 0; /* DEFAULT FALSE */
Paul Bakker74111d32011-01-15 16:57:55 +0000700 *max_pathlen = 0; /* endless */
701
702 if( ( ret = asn1_get_tag( p, end, &len,
703 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000704 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000705
706 if( *p == end )
707 return 0;
708
Paul Bakker3cccddb2011-01-16 21:46:31 +0000709 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000710 {
711 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker3cccddb2011-01-16 21:46:31 +0000712 ret = asn1_get_int( p, end, ca_istrue );
Paul Bakker74111d32011-01-15 16:57:55 +0000713
714 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000715 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000716
Paul Bakker3cccddb2011-01-16 21:46:31 +0000717 if( *ca_istrue != 0 )
718 *ca_istrue = 1;
Paul Bakker74111d32011-01-15 16:57:55 +0000719 }
720
721 if( *p == end )
722 return 0;
723
724 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000725 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000726
727 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000728 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000729 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
730
731 (*max_pathlen)++;
732
Paul Bakker74111d32011-01-15 16:57:55 +0000733 return 0;
734}
735
736static int x509_get_ns_cert_type( unsigned char **p,
737 const unsigned char *end,
738 unsigned char *ns_cert_type)
739{
740 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000741 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000742
743 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000744 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000745
746 if( bs.len != 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000747 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000748 POLARSSL_ERR_ASN1_INVALID_LENGTH );
749
750 /* Get actual bitstring */
751 *ns_cert_type = *bs.p;
752 return 0;
753}
754
755static int x509_get_key_usage( unsigned char **p,
756 const unsigned char *end,
757 unsigned char *key_usage)
758{
759 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000760 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000761
762 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000763 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000764
Paul Bakker94a67962012-08-23 13:03:52 +0000765 if( bs.len < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000766 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000767 POLARSSL_ERR_ASN1_INVALID_LENGTH );
768
769 /* Get actual bitstring */
770 *key_usage = *bs.p;
771 return 0;
772}
773
Paul Bakkerd98030e2009-05-02 15:13:40 +0000774/*
Paul Bakker74111d32011-01-15 16:57:55 +0000775 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
776 *
777 * KeyPurposeId ::= OBJECT IDENTIFIER
778 */
779static int x509_get_ext_key_usage( unsigned char **p,
780 const unsigned char *end,
781 x509_sequence *ext_key_usage)
782{
783 int ret;
784
785 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000786 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000787
788 /* Sequence length must be >= 1 */
789 if( ext_key_usage->buf.p == NULL )
Paul Bakker9d781402011-05-09 16:17:09 +0000790 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000791 POLARSSL_ERR_ASN1_INVALID_LENGTH );
792
793 return 0;
794}
795
796/*
Paul Bakkera8cd2392012-02-11 16:09:32 +0000797 * SubjectAltName ::= GeneralNames
798 *
799 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
800 *
801 * GeneralName ::= CHOICE {
802 * otherName [0] OtherName,
803 * rfc822Name [1] IA5String,
804 * dNSName [2] IA5String,
805 * x400Address [3] ORAddress,
806 * directoryName [4] Name,
807 * ediPartyName [5] EDIPartyName,
808 * uniformResourceIdentifier [6] IA5String,
809 * iPAddress [7] OCTET STRING,
810 * registeredID [8] OBJECT IDENTIFIER }
811 *
812 * OtherName ::= SEQUENCE {
813 * type-id OBJECT IDENTIFIER,
814 * value [0] EXPLICIT ANY DEFINED BY type-id }
815 *
816 * EDIPartyName ::= SEQUENCE {
817 * nameAssigner [0] DirectoryString OPTIONAL,
818 * partyName [1] DirectoryString }
819 *
820 * NOTE: PolarSSL only parses and uses dNSName at this point.
821 */
822static int x509_get_subject_alt_name( unsigned char **p,
823 const unsigned char *end,
824 x509_sequence *subject_alt_name )
825{
826 int ret;
827 size_t len, tag_len;
828 asn1_buf *buf;
829 unsigned char tag;
830 asn1_sequence *cur = subject_alt_name;
831
832 /* Get main sequence tag */
833 if( ( ret = asn1_get_tag( p, end, &len,
834 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
835 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
836
837 if( *p + len != end )
838 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
839 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
840
841 while( *p < end )
842 {
843 if( ( end - *p ) < 1 )
844 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
845 POLARSSL_ERR_ASN1_OUT_OF_DATA );
846
847 tag = **p;
848 (*p)++;
849 if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 )
850 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
851
852 if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC )
853 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
854 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
855
856 if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) )
857 {
858 *p += tag_len;
859 continue;
860 }
861
862 buf = &(cur->buf);
863 buf->tag = tag;
864 buf->p = *p;
865 buf->len = tag_len;
866 *p += buf->len;
867
868 /* Allocate and assign next pointer */
869 if (*p < end)
870 {
871 cur->next = (asn1_sequence *) malloc(
872 sizeof( asn1_sequence ) );
873
874 if( cur->next == NULL )
875 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
876 POLARSSL_ERR_ASN1_MALLOC_FAILED );
877
Paul Bakker535e97d2012-08-23 10:49:55 +0000878 memset( cur->next, 0, sizeof( asn1_sequence ) );
Paul Bakkera8cd2392012-02-11 16:09:32 +0000879 cur = cur->next;
880 }
881 }
882
883 /* Set final sequence entry's next pointer to NULL */
884 cur->next = NULL;
885
886 if( *p != end )
887 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
888 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
889
890 return( 0 );
891}
892
893/*
Paul Bakker74111d32011-01-15 16:57:55 +0000894 * X.509 v3 extensions
895 *
896 * TODO: Perform all of the basic constraints tests required by the RFC
897 * TODO: Set values for undetected extensions to a sane default?
898 *
Paul Bakkerd98030e2009-05-02 15:13:40 +0000899 */
900static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000901 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000902 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000903{
Paul Bakker23986e52011-04-24 08:57:21 +0000904 int ret;
905 size_t len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000906 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000907
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000908 if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000909 {
910 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
911 return( 0 );
912
913 return( ret );
914 }
915
Paul Bakker5121ce52009-01-03 21:22:43 +0000916 while( *p < end )
917 {
Paul Bakker74111d32011-01-15 16:57:55 +0000918 /*
919 * Extension ::= SEQUENCE {
920 * extnID OBJECT IDENTIFIER,
921 * critical BOOLEAN DEFAULT FALSE,
922 * extnValue OCTET STRING }
923 */
924 x509_buf extn_oid = {0, 0, NULL};
925 int is_critical = 0; /* DEFAULT FALSE */
Paul Bakkerc70b9822013-04-07 22:00:46 +0200926 int ext_type = 0;
Paul Bakker74111d32011-01-15 16:57:55 +0000927
Paul Bakker5121ce52009-01-03 21:22:43 +0000928 if( ( ret = asn1_get_tag( p, end, &len,
929 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000930 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000931
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000932 end_ext_data = *p + len;
933
Paul Bakker74111d32011-01-15 16:57:55 +0000934 /* Get extension ID */
935 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000936
Paul Bakker74111d32011-01-15 16:57:55 +0000937 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000938 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000939
Paul Bakker74111d32011-01-15 16:57:55 +0000940 extn_oid.p = *p;
941 *p += extn_oid.len;
942
943 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000944 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000945 POLARSSL_ERR_ASN1_OUT_OF_DATA );
946
947 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000948 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000949 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
Paul Bakker9d781402011-05-09 16:17:09 +0000950 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000951
Paul Bakker74111d32011-01-15 16:57:55 +0000952 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000953 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000954 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000955 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000956
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000957 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000958
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000959 if( end_ext_octet != end_ext_data )
Paul Bakker9d781402011-05-09 16:17:09 +0000960 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000961 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000962
Paul Bakker74111d32011-01-15 16:57:55 +0000963 /*
964 * Detect supported extensions
965 */
Paul Bakkerc70b9822013-04-07 22:00:46 +0200966 ret = oid_get_x509_ext_type( &extn_oid, &ext_type );
967
968 if( ret != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000969 {
970 /* No parser found, skip extension */
971 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +0000972
Paul Bakker5c721f92011-07-27 16:51:09 +0000973#if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
Paul Bakker74111d32011-01-15 16:57:55 +0000974 if( is_critical )
975 {
976 /* Data is marked as critical: fail */
Paul Bakker9d781402011-05-09 16:17:09 +0000977 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000978 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
979 }
Paul Bakker5c721f92011-07-27 16:51:09 +0000980#endif
Paul Bakkerc70b9822013-04-07 22:00:46 +0200981 continue;
982 }
983
984 crt->ext_types |= ext_type;
985
986 switch( ext_type )
987 {
988 case EXT_BASIC_CONSTRAINTS:
989 /* Parse basic constraints */
990 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
991 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
992 return ( ret );
993 break;
994
995 case EXT_KEY_USAGE:
996 /* Parse key usage */
997 if( ( ret = x509_get_key_usage( p, end_ext_octet,
998 &crt->key_usage ) ) != 0 )
999 return ( ret );
1000 break;
1001
1002 case EXT_EXTENDED_KEY_USAGE:
1003 /* Parse extended key usage */
1004 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
1005 &crt->ext_key_usage ) ) != 0 )
1006 return ( ret );
1007 break;
1008
1009 case EXT_SUBJECT_ALT_NAME:
1010 /* Parse subject alt name */
1011 if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
1012 &crt->subject_alt_names ) ) != 0 )
1013 return ( ret );
1014 break;
1015
1016 case EXT_NS_CERT_TYPE:
1017 /* Parse netscape certificate type */
1018 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
1019 &crt->ns_cert_type ) ) != 0 )
1020 return ( ret );
1021 break;
1022
1023 default:
1024 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
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 Bakkerc70b9822013-04-07 22:00:46 +02001100static int x509_get_sig_alg( const x509_buf *sig_oid, md_type_t *md_alg,
1101 pk_type_t *pk_alg )
Paul Bakker27d66162010-03-17 06:56:01 +00001102{
Paul Bakkerc70b9822013-04-07 22:00:46 +02001103 int ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg );
Paul Bakker27d66162010-03-17 06:56:01 +00001104
Paul Bakkerc70b9822013-04-07 22:00:46 +02001105 if( ret != 0 )
1106 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG + ret );
Paul Bakker27d66162010-03-17 06:56:01 +00001107
Paul Bakkerc70b9822013-04-07 22:00:46 +02001108 return( 0 );
Paul Bakker27d66162010-03-17 06:56:01 +00001109}
1110
Paul Bakkerd98030e2009-05-02 15:13:40 +00001111/*
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001112 * Parse and fill a single X.509 certificate in DER format
Paul Bakker5121ce52009-01-03 21:22:43 +00001113 */
Paul Bakker42c65812013-06-24 19:21:59 +02001114int x509parse_crt_der_core( x509_cert *crt, const unsigned char *buf,
1115 size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001116{
Paul Bakker23986e52011-04-24 08:57:21 +00001117 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001118 size_t len;
Paul Bakkerb00ca422012-09-25 12:10:00 +00001119 unsigned char *p, *end, *crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001120
Paul Bakker320a4b52009-03-28 18:52:39 +00001121 /*
1122 * Check for valid input
1123 */
1124 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001125 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker320a4b52009-03-28 18:52:39 +00001126
Paul Bakker96743fc2011-02-12 14:30:57 +00001127 p = (unsigned char *) malloc( len = buflen );
1128
1129 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001130 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001131
1132 memcpy( p, buf, buflen );
1133
1134 buflen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001135
1136 crt->raw.p = p;
1137 crt->raw.len = len;
1138 end = p + len;
1139
1140 /*
1141 * Certificate ::= SEQUENCE {
1142 * tbsCertificate TBSCertificate,
1143 * signatureAlgorithm AlgorithmIdentifier,
1144 * signatureValue BIT STRING }
1145 */
1146 if( ( ret = asn1_get_tag( &p, end, &len,
1147 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1148 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001149 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001150 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001151 }
1152
Paul Bakkerb00ca422012-09-25 12:10:00 +00001153 if( len > (size_t) ( end - p ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001154 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001155 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001156 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001157 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001158 }
Paul Bakkerb00ca422012-09-25 12:10:00 +00001159 crt_end = p + len;
Paul Bakker42c65812013-06-24 19:21:59 +02001160
Paul Bakker5121ce52009-01-03 21:22:43 +00001161 /*
1162 * TBSCertificate ::= SEQUENCE {
1163 */
1164 crt->tbs.p = p;
1165
1166 if( ( ret = asn1_get_tag( &p, end, &len,
1167 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1168 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001169 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001170 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001171 }
1172
1173 end = p + len;
1174 crt->tbs.len = end - crt->tbs.p;
1175
1176 /*
1177 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1178 *
1179 * CertificateSerialNumber ::= INTEGER
1180 *
1181 * signature AlgorithmIdentifier
1182 */
1183 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1184 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1185 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
1186 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001187 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001188 return( ret );
1189 }
1190
1191 crt->version++;
1192
1193 if( crt->version > 3 )
1194 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001195 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001196 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001197 }
1198
Paul Bakkerc70b9822013-04-07 22:00:46 +02001199 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_md,
1200 &crt->sig_pk ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001201 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001202 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001203 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001204 }
1205
1206 /*
1207 * issuer Name
1208 */
1209 crt->issuer_raw.p = p;
1210
1211 if( ( ret = asn1_get_tag( &p, end, &len,
1212 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1213 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001214 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001215 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001216 }
1217
1218 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1219 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001220 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001221 return( ret );
1222 }
1223
1224 crt->issuer_raw.len = p - crt->issuer_raw.p;
1225
1226 /*
1227 * Validity ::= SEQUENCE {
1228 * notBefore Time,
1229 * notAfter Time }
1230 *
1231 */
1232 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1233 &crt->valid_to ) ) != 0 )
1234 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001235 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001236 return( ret );
1237 }
1238
1239 /*
1240 * subject Name
1241 */
1242 crt->subject_raw.p = p;
1243
1244 if( ( ret = asn1_get_tag( &p, end, &len,
1245 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1246 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001247 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001248 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001249 }
1250
Paul Bakkercefb3962012-06-27 11:51:09 +00001251 if( len && ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001252 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001253 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001254 return( ret );
1255 }
1256
1257 crt->subject_raw.len = p - crt->subject_raw.p;
1258
1259 /*
1260 * SubjectPublicKeyInfo ::= SEQUENCE
1261 * algorithm AlgorithmIdentifier,
1262 * subjectPublicKey BIT STRING }
1263 */
1264 if( ( ret = asn1_get_tag( &p, end, &len,
1265 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1266 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001267 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001268 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001269 }
1270
1271 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1272 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1273 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001274 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001275 return( ret );
1276 }
1277
1278 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1279 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001280 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001281 return( ret );
1282 }
1283
1284 crt->rsa.len = mpi_size( &crt->rsa.N );
1285
1286 /*
1287 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1288 * -- If present, version shall be v2 or v3
1289 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1290 * -- If present, version shall be v2 or v3
1291 * extensions [3] EXPLICIT Extensions OPTIONAL
1292 * -- If present, version shall be v3
1293 */
1294 if( crt->version == 2 || crt->version == 3 )
1295 {
1296 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1297 if( ret != 0 )
1298 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001299 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001300 return( ret );
1301 }
1302 }
1303
1304 if( crt->version == 2 || crt->version == 3 )
1305 {
1306 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1307 if( ret != 0 )
1308 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001309 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001310 return( ret );
1311 }
1312 }
1313
1314 if( crt->version == 3 )
1315 {
Paul Bakker74111d32011-01-15 16:57:55 +00001316 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001317 if( ret != 0 )
1318 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001319 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001320 return( ret );
1321 }
1322 }
1323
1324 if( p != end )
1325 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001326 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001327 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001328 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001329 }
1330
Paul Bakkerb00ca422012-09-25 12:10:00 +00001331 end = crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001332
1333 /*
1334 * signatureAlgorithm AlgorithmIdentifier,
1335 * signatureValue BIT STRING
1336 */
1337 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1338 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001339 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001340 return( ret );
1341 }
1342
Paul Bakker535e97d2012-08-23 10:49:55 +00001343 if( crt->sig_oid1.len != crt->sig_oid2.len ||
1344 memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001345 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001346 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001347 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001348 }
1349
1350 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1351 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001352 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001353 return( ret );
1354 }
1355
1356 if( p != end )
1357 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001358 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001359 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001360 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001361 }
1362
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001363 return( 0 );
1364}
1365
1366/*
Paul Bakker42c65812013-06-24 19:21:59 +02001367 * Parse one X.509 certificate in DER format from a buffer and add them to a
1368 * chained list
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001369 */
Paul Bakker42c65812013-06-24 19:21:59 +02001370int x509parse_crt_der( x509_cert *chain, const unsigned char *buf, size_t buflen )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001371{
Paul Bakker42c65812013-06-24 19:21:59 +02001372 int ret;
1373 x509_cert *crt = chain, *prev = NULL;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001374
1375 /*
1376 * Check for valid input
1377 */
1378 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001379 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001380
1381 while( crt->version != 0 && crt->next != NULL )
1382 {
1383 prev = crt;
1384 crt = crt->next;
1385 }
1386
1387 /*
1388 * Add new certificate on the end of the chain if needed.
1389 */
1390 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001391 {
1392 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1393
Paul Bakker7d06ad22009-05-02 15:53:56 +00001394 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001395 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker320a4b52009-03-28 18:52:39 +00001396
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001397 prev = crt;
Paul Bakker7d06ad22009-05-02 15:53:56 +00001398 crt = crt->next;
1399 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001400 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001401
Paul Bakker42c65812013-06-24 19:21:59 +02001402 if( ( ret = x509parse_crt_der_core( crt, buf, buflen ) ) != 0 )
1403 {
1404 if( prev )
1405 prev->next = NULL;
1406
1407 if( crt != chain )
1408 free( crt );
1409
1410 return( ret );
1411 }
1412
1413 return( 0 );
1414}
1415
1416/*
1417 * Parse one or more PEM certificates from a buffer and add them to the chained list
1418 */
1419int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
1420{
1421 int ret, success = 0, first_error = 0, total_failed = 0;
1422 int buf_format = X509_FORMAT_DER;
1423
1424 /*
1425 * Check for valid input
1426 */
1427 if( chain == NULL || buf == NULL )
1428 return( POLARSSL_ERR_X509_INVALID_INPUT );
1429
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001430 /*
1431 * Determine buffer content. Buffer contains either one DER certificate or
1432 * one or more PEM certificates.
1433 */
1434#if defined(POLARSSL_PEM_C)
Paul Bakker3c2122f2013-06-24 19:03:14 +02001435 if( strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001436 buf_format = X509_FORMAT_PEM;
1437#endif
1438
1439 if( buf_format == X509_FORMAT_DER )
Paul Bakker42c65812013-06-24 19:21:59 +02001440 return x509parse_crt_der( chain, buf, buflen );
1441
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001442#if defined(POLARSSL_PEM_C)
1443 if( buf_format == X509_FORMAT_PEM )
1444 {
1445 pem_context pem;
1446
1447 while( buflen > 0 )
1448 {
1449 size_t use_len;
1450 pem_init( &pem );
1451
1452 ret = pem_read_buffer( &pem,
1453 "-----BEGIN CERTIFICATE-----",
1454 "-----END CERTIFICATE-----",
1455 buf, NULL, 0, &use_len );
1456
1457 if( ret == 0 )
1458 {
1459 /*
1460 * Was PEM encoded
1461 */
1462 buflen -= use_len;
1463 buf += use_len;
1464 }
Paul Bakker5ed3b342013-06-24 19:05:46 +02001465 else if( ret == POLARSSL_ERR_PEM_BAD_INPUT_DATA )
1466 {
1467 return( ret );
1468 }
Paul Bakker00b28602013-06-24 13:02:41 +02001469 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001470 {
1471 pem_free( &pem );
1472
Paul Bakker5ed3b342013-06-24 19:05:46 +02001473 /*
1474 * PEM header and footer were found
1475 */
1476 buflen -= use_len;
1477 buf += use_len;
1478
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001479 if( first_error == 0 )
1480 first_error = ret;
1481
1482 continue;
1483 }
1484 else
1485 break;
1486
Paul Bakker42c65812013-06-24 19:21:59 +02001487 ret = x509parse_crt_der( chain, pem.buf, pem.buflen );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001488
1489 pem_free( &pem );
1490
1491 if( ret != 0 )
1492 {
1493 /*
Paul Bakker42c65812013-06-24 19:21:59 +02001494 * Quit parsing on a memory error
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001495 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001496 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001497 return( ret );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001498
1499 if( first_error == 0 )
1500 first_error = ret;
1501
Paul Bakker42c65812013-06-24 19:21:59 +02001502 total_failed++;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001503 continue;
1504 }
1505
1506 success = 1;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001507 }
1508 }
1509#endif
1510
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001511 if( success )
Paul Bakker69e095c2011-12-10 21:55:01 +00001512 return( total_failed );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001513 else if( first_error )
1514 return( first_error );
1515 else
1516 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001517}
1518
1519/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001520 * Parse one or more CRLs and add them to the chained list
1521 */
Paul Bakker23986e52011-04-24 08:57:21 +00001522int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001523{
Paul Bakker23986e52011-04-24 08:57:21 +00001524 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001525 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001526 unsigned char *p, *end;
1527 x509_crl *crl;
Paul Bakker96743fc2011-02-12 14:30:57 +00001528#if defined(POLARSSL_PEM_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00001529 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001530 pem_context pem;
1531#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001532
1533 crl = chain;
1534
1535 /*
1536 * Check for valid input
1537 */
1538 if( crl == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001539 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001540
1541 while( crl->version != 0 && crl->next != NULL )
1542 crl = crl->next;
1543
1544 /*
1545 * Add new CRL on the end of the chain if needed.
1546 */
1547 if ( crl->version != 0 && crl->next == NULL)
1548 {
1549 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1550
Paul Bakker7d06ad22009-05-02 15:53:56 +00001551 if( crl->next == NULL )
1552 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001553 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001554 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001555 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001556
Paul Bakker7d06ad22009-05-02 15:53:56 +00001557 crl = crl->next;
1558 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001559 }
1560
Paul Bakker96743fc2011-02-12 14:30:57 +00001561#if defined(POLARSSL_PEM_C)
1562 pem_init( &pem );
1563 ret = pem_read_buffer( &pem,
1564 "-----BEGIN X509 CRL-----",
1565 "-----END X509 CRL-----",
1566 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001567
Paul Bakker96743fc2011-02-12 14:30:57 +00001568 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001569 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001570 /*
1571 * Was PEM encoded
1572 */
1573 buflen -= use_len;
1574 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001575
1576 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001577 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001578 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001579 p = pem.buf;
1580 pem.buf = NULL;
1581 len = pem.buflen;
1582 pem_free( &pem );
1583 }
Paul Bakker00b28602013-06-24 13:02:41 +02001584 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker96743fc2011-02-12 14:30:57 +00001585 {
1586 pem_free( &pem );
1587 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001588 }
1589 else
1590 {
1591 /*
1592 * nope, copy the raw DER data
1593 */
1594 p = (unsigned char *) malloc( len = buflen );
1595
1596 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001597 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001598
1599 memcpy( p, buf, buflen );
1600
1601 buflen = 0;
1602 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001603#else
1604 p = (unsigned char *) malloc( len = buflen );
1605
1606 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001607 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001608
1609 memcpy( p, buf, buflen );
1610
1611 buflen = 0;
1612#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001613
1614 crl->raw.p = p;
1615 crl->raw.len = len;
1616 end = p + len;
1617
1618 /*
1619 * CertificateList ::= SEQUENCE {
1620 * tbsCertList TBSCertList,
1621 * signatureAlgorithm AlgorithmIdentifier,
1622 * signatureValue BIT STRING }
1623 */
1624 if( ( ret = asn1_get_tag( &p, end, &len,
1625 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1626 {
1627 x509_crl_free( crl );
1628 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1629 }
1630
Paul Bakker23986e52011-04-24 08:57:21 +00001631 if( len != (size_t) ( end - p ) )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001632 {
1633 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001634 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001635 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1636 }
1637
1638 /*
1639 * TBSCertList ::= SEQUENCE {
1640 */
1641 crl->tbs.p = p;
1642
1643 if( ( ret = asn1_get_tag( &p, end, &len,
1644 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1645 {
1646 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001647 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001648 }
1649
1650 end = p + len;
1651 crl->tbs.len = end - crl->tbs.p;
1652
1653 /*
1654 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1655 * -- if present, MUST be v2
1656 *
1657 * signature AlgorithmIdentifier
1658 */
Paul Bakker3329d1f2011-10-12 09:55:01 +00001659 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
Paul Bakkerd98030e2009-05-02 15:13:40 +00001660 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1661 {
1662 x509_crl_free( crl );
1663 return( ret );
1664 }
1665
1666 crl->version++;
1667
1668 if( crl->version > 2 )
1669 {
1670 x509_crl_free( crl );
1671 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1672 }
1673
Paul Bakkerc70b9822013-04-07 22:00:46 +02001674 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_md,
1675 &crl->sig_pk ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001676 {
1677 x509_crl_free( crl );
1678 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1679 }
1680
1681 /*
1682 * issuer Name
1683 */
1684 crl->issuer_raw.p = p;
1685
1686 if( ( ret = asn1_get_tag( &p, end, &len,
1687 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1688 {
1689 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001690 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001691 }
1692
1693 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1694 {
1695 x509_crl_free( crl );
1696 return( ret );
1697 }
1698
1699 crl->issuer_raw.len = p - crl->issuer_raw.p;
1700
1701 /*
1702 * thisUpdate Time
1703 * nextUpdate Time OPTIONAL
1704 */
Paul Bakker91200182010-02-18 21:26:15 +00001705 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001706 {
1707 x509_crl_free( crl );
1708 return( ret );
1709 }
1710
Paul Bakker91200182010-02-18 21:26:15 +00001711 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001712 {
Paul Bakker9d781402011-05-09 16:17:09 +00001713 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001714 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker9d781402011-05-09 16:17:09 +00001715 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001716 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001717 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001718 x509_crl_free( crl );
1719 return( ret );
1720 }
1721 }
1722
1723 /*
1724 * revokedCertificates SEQUENCE OF SEQUENCE {
1725 * userCertificate CertificateSerialNumber,
1726 * revocationDate Time,
1727 * crlEntryExtensions Extensions OPTIONAL
1728 * -- if present, MUST be v2
1729 * } OPTIONAL
1730 */
1731 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1732 {
1733 x509_crl_free( crl );
1734 return( ret );
1735 }
1736
1737 /*
1738 * crlExtensions EXPLICIT Extensions OPTIONAL
1739 * -- if present, MUST be v2
1740 */
1741 if( crl->version == 2 )
1742 {
1743 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1744
1745 if( ret != 0 )
1746 {
1747 x509_crl_free( crl );
1748 return( ret );
1749 }
1750 }
1751
1752 if( p != end )
1753 {
1754 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001755 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001756 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1757 }
1758
1759 end = crl->raw.p + crl->raw.len;
1760
1761 /*
1762 * signatureAlgorithm AlgorithmIdentifier,
1763 * signatureValue BIT STRING
1764 */
1765 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1766 {
1767 x509_crl_free( crl );
1768 return( ret );
1769 }
1770
Paul Bakker535e97d2012-08-23 10:49:55 +00001771 if( crl->sig_oid1.len != crl->sig_oid2.len ||
1772 memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001773 {
1774 x509_crl_free( crl );
1775 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1776 }
1777
1778 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1779 {
1780 x509_crl_free( crl );
1781 return( ret );
1782 }
1783
1784 if( p != end )
1785 {
1786 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001787 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001788 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1789 }
1790
1791 if( buflen > 0 )
1792 {
1793 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1794
Paul Bakker7d06ad22009-05-02 15:53:56 +00001795 if( crl->next == NULL )
1796 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001797 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001798 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001799 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001800
Paul Bakker7d06ad22009-05-02 15:53:56 +00001801 crl = crl->next;
1802 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001803
1804 return( x509parse_crl( crl, buf, buflen ) );
1805 }
1806
1807 return( 0 );
1808}
1809
Paul Bakker335db3f2011-04-25 15:28:35 +00001810#if defined(POLARSSL_FS_IO)
Paul Bakkerd98030e2009-05-02 15:13:40 +00001811/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001812 * Load all data from a file into a given buffer.
1813 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001814int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001815{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001816 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001817
Paul Bakkerd98030e2009-05-02 15:13:40 +00001818 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001819 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001820
Paul Bakkerd98030e2009-05-02 15:13:40 +00001821 fseek( f, 0, SEEK_END );
1822 *n = (size_t) ftell( f );
1823 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001824
Paul Bakkerd98030e2009-05-02 15:13:40 +00001825 if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
Paul Bakkerf6a19bd2013-05-14 13:26:51 +02001826 {
1827 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +00001828 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerf6a19bd2013-05-14 13:26:51 +02001829 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001830
Paul Bakkerd98030e2009-05-02 15:13:40 +00001831 if( fread( *buf, 1, *n, f ) != *n )
1832 {
1833 fclose( f );
1834 free( *buf );
Paul Bakker69e095c2011-12-10 21:55:01 +00001835 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001836 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001837
Paul Bakkerd98030e2009-05-02 15:13:40 +00001838 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001839
Paul Bakkerd98030e2009-05-02 15:13:40 +00001840 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001841
Paul Bakkerd98030e2009-05-02 15:13:40 +00001842 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001843}
1844
1845/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001846 * Load one or more certificates and add them to the chained list
1847 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001848int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001849{
1850 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001851 size_t n;
1852 unsigned char *buf;
1853
Paul Bakker69e095c2011-12-10 21:55:01 +00001854 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1855 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001856
Paul Bakker69e095c2011-12-10 21:55:01 +00001857 ret = x509parse_crt( chain, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001858
1859 memset( buf, 0, n + 1 );
1860 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001861
1862 return( ret );
1863}
1864
Paul Bakker8d914582012-06-04 12:46:42 +00001865int x509parse_crtpath( x509_cert *chain, const char *path )
1866{
1867 int ret = 0;
1868#if defined(_WIN32)
Paul Bakker3338b792012-10-01 21:13:10 +00001869 int w_ret;
1870 WCHAR szDir[MAX_PATH];
1871 char filename[MAX_PATH];
1872 char *p;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001873 int len = strlen( path );
Paul Bakker3338b792012-10-01 21:13:10 +00001874
Paul Bakker97872ac2012-11-02 12:53:26 +00001875 WIN32_FIND_DATAW file_data;
Paul Bakker8d914582012-06-04 12:46:42 +00001876 HANDLE hFind;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001877
1878 if( len > MAX_PATH - 3 )
1879 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker8d914582012-06-04 12:46:42 +00001880
Paul Bakker3338b792012-10-01 21:13:10 +00001881 memset( szDir, 0, sizeof(szDir) );
1882 memset( filename, 0, MAX_PATH );
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001883 memcpy( filename, path, len );
1884 filename[len++] = '\\';
1885 p = filename + len;
1886 filename[len++] = '*';
Paul Bakker3338b792012-10-01 21:13:10 +00001887
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001888 w_ret = MultiByteToWideChar( CP_ACP, 0, path, len, szDir, MAX_PATH - 3 );
Paul Bakker8d914582012-06-04 12:46:42 +00001889
Paul Bakker97872ac2012-11-02 12:53:26 +00001890 hFind = FindFirstFileW( szDir, &file_data );
Paul Bakker8d914582012-06-04 12:46:42 +00001891 if (hFind == INVALID_HANDLE_VALUE)
1892 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1893
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001894 len = MAX_PATH - len;
Paul Bakker8d914582012-06-04 12:46:42 +00001895 do
1896 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001897 memset( p, 0, len );
Paul Bakker3338b792012-10-01 21:13:10 +00001898
Paul Bakkere4791f32012-06-04 21:29:15 +00001899 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
Paul Bakker8d914582012-06-04 12:46:42 +00001900 continue;
1901
Paul Bakker3338b792012-10-01 21:13:10 +00001902 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
1903 lstrlenW(file_data.cFileName),
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001904 p, len - 1,
1905 NULL, NULL );
Paul Bakker8d914582012-06-04 12:46:42 +00001906
Paul Bakker3338b792012-10-01 21:13:10 +00001907 w_ret = x509parse_crtfile( chain, filename );
1908 if( w_ret < 0 )
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001909 ret++;
1910 else
1911 ret += w_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001912 }
Paul Bakker97872ac2012-11-02 12:53:26 +00001913 while( FindNextFileW( hFind, &file_data ) != 0 );
Paul Bakker8d914582012-06-04 12:46:42 +00001914
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001915 if (GetLastError() != ERROR_NO_MORE_FILES)
1916 ret = POLARSSL_ERR_X509_FILE_IO_ERROR;
Paul Bakker8d914582012-06-04 12:46:42 +00001917
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001918cleanup:
Paul Bakker8d914582012-06-04 12:46:42 +00001919 FindClose( hFind );
1920#else
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001921 int t_ret, i;
1922 struct stat sb;
1923 struct dirent entry, *result = NULL;
Paul Bakker8d914582012-06-04 12:46:42 +00001924 char entry_name[255];
1925 DIR *dir = opendir( path );
1926
1927 if( dir == NULL)
1928 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1929
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001930 while( ( t_ret = readdir_r( dir, &entry, &result ) ) == 0 )
Paul Bakker8d914582012-06-04 12:46:42 +00001931 {
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001932 if( result == NULL )
1933 break;
1934
1935 snprintf( entry_name, sizeof(entry_name), "%s/%s", path, entry.d_name );
1936
1937 i = stat( entry_name, &sb );
1938
1939 if( i == -1 )
1940 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1941
1942 if( !S_ISREG( sb.st_mode ) )
Paul Bakker8d914582012-06-04 12:46:42 +00001943 continue;
1944
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001945 // Ignore parse errors
1946 //
Paul Bakker8d914582012-06-04 12:46:42 +00001947 t_ret = x509parse_crtfile( chain, entry_name );
1948 if( t_ret < 0 )
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001949 ret++;
1950 else
1951 ret += t_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001952 }
1953 closedir( dir );
1954#endif
1955
1956 return( ret );
1957}
1958
Paul Bakkerd98030e2009-05-02 15:13:40 +00001959/*
1960 * Load one or more CRLs and add them to the chained list
1961 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001962int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001963{
1964 int ret;
1965 size_t n;
1966 unsigned char *buf;
1967
Paul Bakker69e095c2011-12-10 21:55:01 +00001968 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1969 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001970
Paul Bakker27fdf462011-06-09 13:55:13 +00001971 ret = x509parse_crl( chain, buf, n );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001972
1973 memset( buf, 0, n + 1 );
1974 free( buf );
1975
1976 return( ret );
1977}
1978
Paul Bakker5121ce52009-01-03 21:22:43 +00001979/*
Paul Bakker335db3f2011-04-25 15:28:35 +00001980 * Load and parse a private RSA key
1981 */
1982int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
1983{
1984 int ret;
1985 size_t n;
1986 unsigned char *buf;
1987
Paul Bakker69e095c2011-12-10 21:55:01 +00001988 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1989 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00001990
1991 if( pwd == NULL )
Paul Bakker27fdf462011-06-09 13:55:13 +00001992 ret = x509parse_key( rsa, buf, n, NULL, 0 );
Paul Bakker335db3f2011-04-25 15:28:35 +00001993 else
Paul Bakker27fdf462011-06-09 13:55:13 +00001994 ret = x509parse_key( rsa, buf, n,
Paul Bakker335db3f2011-04-25 15:28:35 +00001995 (unsigned char *) pwd, strlen( pwd ) );
1996
1997 memset( buf, 0, n + 1 );
1998 free( buf );
1999
2000 return( ret );
2001}
2002
2003/*
2004 * Load and parse a public RSA key
2005 */
2006int x509parse_public_keyfile( rsa_context *rsa, const char *path )
2007{
2008 int ret;
2009 size_t n;
2010 unsigned char *buf;
2011
Paul Bakker69e095c2011-12-10 21:55:01 +00002012 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2013 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002014
Paul Bakker27fdf462011-06-09 13:55:13 +00002015 ret = x509parse_public_key( rsa, buf, n );
Paul Bakker335db3f2011-04-25 15:28:35 +00002016
2017 memset( buf, 0, n + 1 );
2018 free( buf );
2019
2020 return( ret );
2021}
2022#endif /* POLARSSL_FS_IO */
2023
2024/*
Paul Bakkere2f50402013-06-24 19:00:59 +02002025 * Parse a PKCS#1 encoded private RSA key
Paul Bakker5121ce52009-01-03 21:22:43 +00002026 */
Paul Bakkere2f50402013-06-24 19:00:59 +02002027static int x509parse_key_pkcs1_der( rsa_context *rsa,
2028 const unsigned char *key,
2029 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +00002030{
Paul Bakker23986e52011-04-24 08:57:21 +00002031 int ret;
2032 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00002033 unsigned char *p, *end;
Paul Bakkered56b222011-07-13 11:26:43 +00002034
Paul Bakker96743fc2011-02-12 14:30:57 +00002035 p = (unsigned char *) key;
Paul Bakker96743fc2011-02-12 14:30:57 +00002036 end = p + keylen;
2037
Paul Bakker5121ce52009-01-03 21:22:43 +00002038 /*
Paul Bakkere2f50402013-06-24 19:00:59 +02002039 * This function parses the RSAPrivateKey (PKCS#1)
Paul Bakkered56b222011-07-13 11:26:43 +00002040 *
Paul Bakker5121ce52009-01-03 21:22:43 +00002041 * RSAPrivateKey ::= SEQUENCE {
2042 * version Version,
2043 * modulus INTEGER, -- n
2044 * publicExponent INTEGER, -- e
2045 * privateExponent INTEGER, -- d
2046 * prime1 INTEGER, -- p
2047 * prime2 INTEGER, -- q
2048 * exponent1 INTEGER, -- d mod (p-1)
2049 * exponent2 INTEGER, -- d mod (q-1)
2050 * coefficient INTEGER, -- (inverse of q) mod p
2051 * otherPrimeInfos OtherPrimeInfos OPTIONAL
2052 * }
2053 */
2054 if( ( ret = asn1_get_tag( &p, end, &len,
2055 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2056 {
Paul Bakker9d781402011-05-09 16:17:09 +00002057 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002058 }
2059
2060 end = p + len;
2061
2062 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2063 {
Paul Bakker9d781402011-05-09 16:17:09 +00002064 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002065 }
2066
2067 if( rsa->ver != 0 )
2068 {
Paul Bakker9d781402011-05-09 16:17:09 +00002069 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002070 }
2071
2072 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
2073 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
2074 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
2075 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
2076 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
2077 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
2078 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
2079 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
2080 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002081 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002082 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002083 }
2084
2085 rsa->len = mpi_size( &rsa->N );
2086
2087 if( p != end )
2088 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002089 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002090 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00002091 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002092 }
2093
2094 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2095 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002096 rsa_free( rsa );
2097 return( ret );
2098 }
2099
Paul Bakkere2f50402013-06-24 19:00:59 +02002100 return( 0 );
2101}
2102
2103/*
2104 * Parse an unencrypted PKCS#8 encoded private RSA key
2105 */
2106static int x509parse_key_pkcs8_unencrypted_der(
2107 rsa_context *rsa,
2108 const unsigned char *key,
2109 size_t keylen )
2110{
2111 int ret;
2112 size_t len;
2113 unsigned char *p, *end;
2114 x509_buf pk_alg_oid;
2115 pk_type_t pk_alg = POLARSSL_PK_NONE;
2116
2117 p = (unsigned char *) key;
2118 end = p + keylen;
2119
2120 /*
2121 * This function parses the PrivatKeyInfo object (PKCS#8)
2122 *
2123 * PrivateKeyInfo ::= SEQUENCE {
2124 * version Version,
2125 * algorithm AlgorithmIdentifier,
2126 * PrivateKey BIT STRING
2127 * }
2128 *
2129 * AlgorithmIdentifier ::= SEQUENCE {
2130 * algorithm OBJECT IDENTIFIER,
2131 * parameters ANY DEFINED BY algorithm OPTIONAL
2132 * }
2133 *
2134 * The PrivateKey BIT STRING is a PKCS#1 RSAPrivateKey
2135 */
2136 if( ( ret = asn1_get_tag( &p, end, &len,
2137 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2138 {
2139 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2140 }
2141
2142 end = p + len;
2143
2144 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2145 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2146
2147 if( rsa->ver != 0 )
2148 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2149
2150 if( ( ret = x509_get_alg( &p, end, &pk_alg_oid ) ) != 0 )
2151 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2152
2153 /*
2154 * only RSA keys handled at this time
2155 */
2156 if( oid_get_pk_alg( &pk_alg_oid, &pk_alg ) != 0 )
2157 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
2158
2159 /*
2160 * Get the OCTET STRING and parse the PKCS#1 format inside
2161 */
2162 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2163 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2164
2165 if( ( end - p ) < 1 )
2166 {
2167 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
2168 POLARSSL_ERR_ASN1_OUT_OF_DATA );
2169 }
2170
2171 end = p + len;
2172
2173 if( ( ret = x509parse_key_pkcs1_der( rsa, p, end - p ) ) != 0 )
2174 return( ret );
2175
2176 return( 0 );
2177}
2178
2179/*
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002180 * Parse an unencrypted PKCS#8 encoded private RSA key
2181 */
2182static int x509parse_key_pkcs8_encrypted_der(
2183 rsa_context *rsa,
2184 const unsigned char *key,
2185 size_t keylen,
2186 const unsigned char *pwd,
2187 size_t pwdlen )
2188{
2189 int ret;
2190 size_t len;
2191 unsigned char *p, *end, *end2;
2192 x509_buf pbe_alg_oid, pbe_params;
2193 unsigned char buf[2048];
2194
2195 memset(buf, 0, 2048);
2196
2197 p = (unsigned char *) key;
2198 end = p + keylen;
2199
Paul Bakker28144de2013-06-24 19:28:55 +02002200 if( pwdlen == 0 )
2201 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
2202
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002203 /*
2204 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
2205 *
2206 * EncryptedPrivateKeyInfo ::= SEQUENCE {
2207 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
2208 * encryptedData EncryptedData
2209 * }
2210 *
2211 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
2212 *
2213 * EncryptedData ::= OCTET STRING
2214 *
2215 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
2216 */
2217 if( ( ret = asn1_get_tag( &p, end, &len,
2218 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2219 {
2220 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2221 }
2222
2223 end = p + len;
2224
2225 if( ( ret = asn1_get_tag( &p, end, &len,
2226 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2227 {
2228 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2229 }
2230
2231 end2 = p + len;
2232
2233 if( ( ret = asn1_get_tag( &p, end, &pbe_alg_oid.len, ASN1_OID ) ) != 0 )
2234 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2235
2236 pbe_alg_oid.p = p;
2237 p += pbe_alg_oid.len;
2238
2239 /*
2240 * Store the algorithm parameters
2241 */
2242 pbe_params.p = p;
2243 pbe_params.len = end2 - p;
2244 p += pbe_params.len;
2245
2246 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2247 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2248
2249 // buf has been sized to 2048 bytes
2250 if( len > 2048 )
2251 return( POLARSSL_ERR_X509_INVALID_INPUT );
2252
2253 /*
2254 * Decrypt EncryptedData with appropriate PDE
2255 */
2256 if( OID_CMP( OID_PKCS12_PBE_SHA1_DES3_EDE_CBC, &pbe_alg_oid ) )
2257 {
2258 if( ( ret = pkcs12_pbe_sha1_des3_ede_cbc( &pbe_params,
2259 PKCS12_PBE_DECRYPT,
2260 pwd, pwdlen,
2261 p, len, buf ) ) != 0 )
2262 {
2263 return( ret );
2264 }
2265 }
2266 else if( OID_CMP( OID_PKCS12_PBE_SHA1_DES2_EDE_CBC, &pbe_alg_oid ) )
2267 {
2268 if( ( ret = pkcs12_pbe_sha1_des2_ede_cbc( &pbe_params,
2269 PKCS12_PBE_DECRYPT,
2270 pwd, pwdlen,
2271 p, len, buf ) ) != 0 )
2272 {
2273 return( ret );
2274 }
2275 }
2276 else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) )
2277 {
2278 if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params,
2279 PKCS12_PBE_DECRYPT,
2280 pwd, pwdlen,
2281 p, len, buf ) ) != 0 )
2282 {
2283 return( ret );
2284 }
2285 }
Paul Bakker28144de2013-06-24 19:28:55 +02002286#if defined(POLARSSL_PKCS5_C)
2287 else if( OID_CMP( OID_PKCS5_PBES2, &pbe_alg_oid ) )
2288 {
2289 if( ( ret = pkcs5_pbes2( &pbe_params, PKCS5_DECRYPT, pwd, pwdlen,
2290 p, len, buf ) ) != 0 )
2291 {
2292 if( ret == POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH )
2293 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2294
2295 return( ret );
2296 }
2297 }
2298#endif /* POLARSSL_PKCS5_C */
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002299 else
2300 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
2301
2302 return x509parse_key_pkcs8_unencrypted_der( rsa, buf, len );
2303}
2304
2305/*
Paul Bakkere2f50402013-06-24 19:00:59 +02002306 * Parse a private RSA key
2307 */
2308int x509parse_key( rsa_context *rsa, const unsigned char *key, size_t keylen,
2309 const unsigned char *pwd, size_t pwdlen )
2310{
2311 int ret;
2312
Paul Bakker96743fc2011-02-12 14:30:57 +00002313#if defined(POLARSSL_PEM_C)
Paul Bakkere2f50402013-06-24 19:00:59 +02002314 size_t len;
2315 pem_context pem;
2316
2317 pem_init( &pem );
2318 ret = pem_read_buffer( &pem,
2319 "-----BEGIN RSA PRIVATE KEY-----",
2320 "-----END RSA PRIVATE KEY-----",
2321 key, pwd, pwdlen, &len );
2322 if( ret == 0 )
2323 {
2324 if( ( ret = x509parse_key_pkcs1_der( rsa, pem.buf, pem.buflen ) ) != 0 )
2325 {
2326 rsa_free( rsa );
2327 }
2328
2329 pem_free( &pem );
2330 return( ret );
2331 }
Paul Bakkera4232a72013-06-24 19:32:25 +02002332 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
2333 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2334 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
2335 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
Paul Bakkere2f50402013-06-24 19:00:59 +02002336 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkere2f50402013-06-24 19:00:59 +02002337 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002338
2339 ret = pem_read_buffer( &pem,
2340 "-----BEGIN PRIVATE KEY-----",
2341 "-----END PRIVATE KEY-----",
2342 key, NULL, 0, &len );
2343 if( ret == 0 )
2344 {
2345 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa,
2346 pem.buf, pem.buflen ) ) != 0 )
2347 {
2348 rsa_free( rsa );
2349 }
2350
2351 pem_free( &pem );
2352 return( ret );
2353 }
2354 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkere2f50402013-06-24 19:00:59 +02002355 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002356
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002357 ret = pem_read_buffer( &pem,
2358 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
2359 "-----END ENCRYPTED PRIVATE KEY-----",
2360 key, NULL, 0, &len );
2361 if( ret == 0 )
2362 {
2363 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa,
2364 pem.buf, pem.buflen,
2365 pwd, pwdlen ) ) != 0 )
2366 {
2367 rsa_free( rsa );
2368 }
2369
2370 pem_free( &pem );
2371 return( ret );
2372 }
2373 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002374 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002375#else
2376 ((void) pwd);
2377 ((void) pwdlen);
2378#endif /* POLARSSL_PEM_C */
2379
2380 // At this point we only know it's not a PEM formatted key. Could be any
2381 // of the known DER encoded private key formats
2382 //
2383 // We try the different DER format parsers to see if one passes without
2384 // error
2385 //
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002386 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa, key, keylen,
2387 pwd, pwdlen ) ) == 0 )
Paul Bakkere2f50402013-06-24 19:00:59 +02002388 {
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002389 return( 0 );
Paul Bakkere2f50402013-06-24 19:00:59 +02002390 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002391
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002392 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002393
2394 if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH )
2395 {
2396 return( ret );
2397 }
2398
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002399 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa, key, keylen ) ) == 0 )
2400 return( 0 );
2401
2402 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002403
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002404 if( ( ret = x509parse_key_pkcs1_der( rsa, key, keylen ) ) == 0 )
2405 return( 0 );
2406
2407 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002408
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002409 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 Bakker00b28602013-06-24 13:02:41 +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 Bakker00b28602013-06-24 13:02:41 +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 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02002624static int compat_snprintf(char *str, size_t size, const char *format, ...)
Paul Bakkerd98030e2009-05-02 15:13:40 +00002625{
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 Bakkerc70b9822013-04-07 22:00:46 +02002671 const char *short_name = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00002672 char s[128], *p;
2673
2674 memset( s, 0, sizeof( s ) );
2675
2676 name = dn;
2677 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002678 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002679
2680 while( name != NULL )
2681 {
Paul Bakkercefb3962012-06-27 11:51:09 +00002682 if( !name->oid.p )
2683 {
2684 name = name->next;
2685 continue;
2686 }
2687
Paul Bakker74111d32011-01-15 16:57:55 +00002688 if( name != dn )
2689 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002690 ret = snprintf( p, n, ", " );
2691 SAFE_SNPRINTF();
2692 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002693
Paul Bakkerc70b9822013-04-07 22:00:46 +02002694 ret = oid_get_attr_short_name( &name->oid, &short_name );
Paul Bakker5121ce52009-01-03 21:22:43 +00002695
Paul Bakkerc70b9822013-04-07 22:00:46 +02002696 if( ret == 0 )
2697 ret = snprintf( p, n, "%s=", short_name );
Paul Bakker5121ce52009-01-03 21:22:43 +00002698 else
Paul Bakkerd98030e2009-05-02 15:13:40 +00002699 ret = snprintf( p, n, "\?\?=" );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002700 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002701
2702 for( i = 0; i < name->val.len; i++ )
2703 {
Paul Bakker27fdf462011-06-09 13:55:13 +00002704 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002705 break;
2706
2707 c = name->val.p[i];
2708 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2709 s[i] = '?';
2710 else s[i] = c;
2711 }
2712 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002713 ret = snprintf( p, n, "%s", s );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002714 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002715 name = name->next;
2716 }
2717
Paul Bakker23986e52011-04-24 08:57:21 +00002718 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002719}
2720
2721/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002722 * Store the serial in printable form into buf; no more
2723 * than size characters will be written
2724 */
2725int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2726{
Paul Bakker23986e52011-04-24 08:57:21 +00002727 int ret;
2728 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00002729 char *p;
2730
2731 p = buf;
2732 n = size;
2733
2734 nr = ( serial->len <= 32 )
Paul Bakker03c7c252011-11-25 12:37:37 +00002735 ? serial->len : 28;
Paul Bakkerdd476992011-01-16 21:34:59 +00002736
2737 for( i = 0; i < nr; i++ )
2738 {
Paul Bakker93048802011-12-05 14:38:06 +00002739 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002740 continue;
2741
Paul Bakkerdd476992011-01-16 21:34:59 +00002742 ret = snprintf( p, n, "%02X%s",
2743 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2744 SAFE_SNPRINTF();
2745 }
2746
Paul Bakker03c7c252011-11-25 12:37:37 +00002747 if( nr != serial->len )
2748 {
2749 ret = snprintf( p, n, "...." );
2750 SAFE_SNPRINTF();
2751 }
2752
Paul Bakker23986e52011-04-24 08:57:21 +00002753 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00002754}
2755
2756/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002757 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002758 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002759int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2760 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002761{
Paul Bakker23986e52011-04-24 08:57:21 +00002762 int ret;
2763 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002764 char *p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002765 const char *desc = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00002766
2767 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002768 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002769
Paul Bakkerd98030e2009-05-02 15:13:40 +00002770 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002771 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002772 SAFE_SNPRINTF();
2773 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002774 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002775 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002776
Paul Bakkerdd476992011-01-16 21:34:59 +00002777 ret = x509parse_serial_gets( p, n, &crt->serial);
2778 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002779
Paul Bakkerd98030e2009-05-02 15:13:40 +00002780 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2781 SAFE_SNPRINTF();
2782 ret = x509parse_dn_gets( p, n, &crt->issuer );
2783 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002784
Paul Bakkerd98030e2009-05-02 15:13:40 +00002785 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2786 SAFE_SNPRINTF();
2787 ret = x509parse_dn_gets( p, n, &crt->subject );
2788 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002789
Paul Bakkerd98030e2009-05-02 15:13:40 +00002790 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002791 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2792 crt->valid_from.year, crt->valid_from.mon,
2793 crt->valid_from.day, crt->valid_from.hour,
2794 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002795 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002796
Paul Bakkerd98030e2009-05-02 15:13:40 +00002797 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002798 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2799 crt->valid_to.year, crt->valid_to.mon,
2800 crt->valid_to.day, crt->valid_to.hour,
2801 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002802 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002803
Paul Bakkerc70b9822013-04-07 22:00:46 +02002804 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002805 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002806
Paul Bakkerc70b9822013-04-07 22:00:46 +02002807 ret = oid_get_sig_alg_desc( &crt->sig_oid1, &desc );
2808 if( ret != 0 )
2809 ret = snprintf( p, n, "???" );
2810 else
2811 ret = snprintf( p, n, desc );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002812 SAFE_SNPRINTF();
2813
2814 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
Paul Bakker5c2364c2012-10-01 14:41:15 +00002815 (int) crt->rsa.N.n * (int) sizeof( t_uint ) * 8 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002816 SAFE_SNPRINTF();
2817
Paul Bakker23986e52011-04-24 08:57:21 +00002818 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002819}
2820
Paul Bakker74111d32011-01-15 16:57:55 +00002821/*
2822 * Return an informational string describing the given OID
2823 */
2824const char *x509_oid_get_description( x509_buf *oid )
2825{
Paul Bakkerc70b9822013-04-07 22:00:46 +02002826 const char *desc = NULL;
2827 int ret;
Paul Bakker74111d32011-01-15 16:57:55 +00002828
Paul Bakkerc70b9822013-04-07 22:00:46 +02002829 ret = oid_get_extended_key_usage( oid, &desc );
Paul Bakker74111d32011-01-15 16:57:55 +00002830
Paul Bakkerc70b9822013-04-07 22:00:46 +02002831 if( ret != 0 )
2832 return( NULL );
Paul Bakker74111d32011-01-15 16:57:55 +00002833
Paul Bakkerc70b9822013-04-07 22:00:46 +02002834 return( desc );
Paul Bakker74111d32011-01-15 16:57:55 +00002835}
2836
2837/* Return the x.y.z.... style numeric string for the given OID */
2838int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2839{
Paul Bakkerc70b9822013-04-07 22:00:46 +02002840 return oid_get_numeric_string( buf, size, oid );
Paul Bakker74111d32011-01-15 16:57:55 +00002841}
2842
Paul Bakkerd98030e2009-05-02 15:13:40 +00002843/*
2844 * Return an informational string about the CRL.
2845 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002846int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2847 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002848{
Paul Bakker23986e52011-04-24 08:57:21 +00002849 int ret;
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002850 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002851 char *p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002852 const char *desc;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002853 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002854
2855 p = buf;
2856 n = size;
2857
2858 ret = snprintf( p, n, "%sCRL version : %d",
2859 prefix, crl->version );
2860 SAFE_SNPRINTF();
2861
2862 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2863 SAFE_SNPRINTF();
2864 ret = x509parse_dn_gets( p, n, &crl->issuer );
2865 SAFE_SNPRINTF();
2866
2867 ret = snprintf( p, n, "\n%sthis update : " \
2868 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2869 crl->this_update.year, crl->this_update.mon,
2870 crl->this_update.day, crl->this_update.hour,
2871 crl->this_update.min, crl->this_update.sec );
2872 SAFE_SNPRINTF();
2873
2874 ret = snprintf( p, n, "\n%snext update : " \
2875 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2876 crl->next_update.year, crl->next_update.mon,
2877 crl->next_update.day, crl->next_update.hour,
2878 crl->next_update.min, crl->next_update.sec );
2879 SAFE_SNPRINTF();
2880
2881 entry = &crl->entry;
2882
2883 ret = snprintf( p, n, "\n%sRevoked certificates:",
2884 prefix );
2885 SAFE_SNPRINTF();
2886
Paul Bakker9be19372009-07-27 20:21:53 +00002887 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002888 {
2889 ret = snprintf( p, n, "\n%sserial number: ",
2890 prefix );
2891 SAFE_SNPRINTF();
2892
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002893 ret = x509parse_serial_gets( p, n, &entry->serial);
2894 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002895
Paul Bakkerd98030e2009-05-02 15:13:40 +00002896 ret = snprintf( p, n, " revocation date: " \
2897 "%04d-%02d-%02d %02d:%02d:%02d",
2898 entry->revocation_date.year, entry->revocation_date.mon,
2899 entry->revocation_date.day, entry->revocation_date.hour,
2900 entry->revocation_date.min, entry->revocation_date.sec );
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002901 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002902
2903 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002904 }
2905
Paul Bakkerc70b9822013-04-07 22:00:46 +02002906 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002907 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002908
Paul Bakkerc70b9822013-04-07 22:00:46 +02002909 ret = oid_get_sig_alg_desc( &crl->sig_oid1, &desc );
2910 if( ret != 0 )
2911 ret = snprintf( p, n, "???" );
2912 else
2913 ret = snprintf( p, n, desc );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002914 SAFE_SNPRINTF();
2915
Paul Bakker1e27bb22009-07-19 20:25:25 +00002916 ret = snprintf( p, n, "\n" );
2917 SAFE_SNPRINTF();
2918
Paul Bakker23986e52011-04-24 08:57:21 +00002919 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002920}
2921
2922/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00002923 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00002924 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002925int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00002926{
Paul Bakkercce9d772011-11-18 14:26:47 +00002927 int year, mon, day;
2928 int hour, min, sec;
2929
2930#if defined(_WIN32)
2931 SYSTEMTIME st;
2932
2933 GetLocalTime(&st);
2934
2935 year = st.wYear;
2936 mon = st.wMonth;
2937 day = st.wDay;
2938 hour = st.wHour;
2939 min = st.wMinute;
2940 sec = st.wSecond;
2941#else
Paul Bakker5121ce52009-01-03 21:22:43 +00002942 struct tm *lt;
2943 time_t tt;
2944
2945 tt = time( NULL );
2946 lt = localtime( &tt );
2947
Paul Bakkercce9d772011-11-18 14:26:47 +00002948 year = lt->tm_year + 1900;
2949 mon = lt->tm_mon + 1;
2950 day = lt->tm_mday;
2951 hour = lt->tm_hour;
2952 min = lt->tm_min;
2953 sec = lt->tm_sec;
2954#endif
2955
2956 if( year > to->year )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002957 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002958
Paul Bakkercce9d772011-11-18 14:26:47 +00002959 if( year == to->year &&
2960 mon > to->mon )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002961 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002962
Paul Bakkercce9d772011-11-18 14:26:47 +00002963 if( year == to->year &&
2964 mon == to->mon &&
2965 day > to->day )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002966 return( 1 );
2967
Paul Bakkercce9d772011-11-18 14:26:47 +00002968 if( year == to->year &&
2969 mon == to->mon &&
2970 day == to->day &&
2971 hour > to->hour )
Paul Bakkerb6194992011-01-16 21:40:22 +00002972 return( 1 );
2973
Paul Bakkercce9d772011-11-18 14:26:47 +00002974 if( year == to->year &&
2975 mon == to->mon &&
2976 day == to->day &&
2977 hour == to->hour &&
2978 min > to->min )
Paul Bakkerb6194992011-01-16 21:40:22 +00002979 return( 1 );
2980
Paul Bakkercce9d772011-11-18 14:26:47 +00002981 if( year == to->year &&
2982 mon == to->mon &&
2983 day == to->day &&
2984 hour == to->hour &&
2985 min == to->min &&
2986 sec > to->sec )
Paul Bakkerb6194992011-01-16 21:40:22 +00002987 return( 1 );
2988
Paul Bakker40ea7de2009-05-03 10:18:48 +00002989 return( 0 );
2990}
2991
2992/*
2993 * Return 1 if the certificate is revoked, or 0 otherwise.
2994 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002995int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002996{
Paul Bakkerff60ee62010-03-16 21:09:09 +00002997 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00002998
2999 while( cur != NULL && cur->serial.len != 0 )
3000 {
Paul Bakkera056efc2011-01-16 21:38:35 +00003001 if( crt->serial.len == cur->serial.len &&
3002 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003003 {
3004 if( x509parse_time_expired( &cur->revocation_date ) )
3005 return( 1 );
3006 }
3007
3008 cur = cur->next;
3009 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003010
3011 return( 0 );
3012}
3013
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003014/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00003015 * Check that the given certificate is valid accoring to the CRL.
3016 */
3017static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
3018 x509_crl *crl_list)
3019{
3020 int flags = 0;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003021 unsigned char hash[POLARSSL_MD_MAX_SIZE];
3022 const md_info_t *md_info;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003023
Paul Bakker915275b2012-09-28 07:10:55 +00003024 if( ca == NULL )
3025 return( flags );
3026
Paul Bakker76fd75a2011-01-16 21:12:10 +00003027 /*
3028 * TODO: What happens if no CRL is present?
3029 * Suggestion: Revocation state should be unknown if no CRL is present.
3030 * For backwards compatibility this is not yet implemented.
3031 */
3032
Paul Bakker915275b2012-09-28 07:10:55 +00003033 while( crl_list != NULL )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003034 {
Paul Bakker915275b2012-09-28 07:10:55 +00003035 if( crl_list->version == 0 ||
3036 crl_list->issuer_raw.len != ca->subject_raw.len ||
Paul Bakker76fd75a2011-01-16 21:12:10 +00003037 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
3038 crl_list->issuer_raw.len ) != 0 )
3039 {
3040 crl_list = crl_list->next;
3041 continue;
3042 }
3043
3044 /*
3045 * Check if CRL is correctly signed by the trusted CA
3046 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02003047 md_info = md_info_from_type( crl_list->sig_md );
3048 if( md_info == NULL )
3049 {
3050 /*
3051 * Cannot check 'unknown' hash
3052 */
3053 flags |= BADCRL_NOT_TRUSTED;
3054 break;
3055 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00003056
Paul Bakkerc70b9822013-04-07 22:00:46 +02003057 md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
Paul Bakker76fd75a2011-01-16 21:12:10 +00003058
Paul Bakkerc70b9822013-04-07 22:00:46 +02003059 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, crl_list->sig_md,
Paul Bakker76fd75a2011-01-16 21:12:10 +00003060 0, hash, crl_list->sig.p ) == 0 )
3061 {
3062 /*
3063 * CRL is not trusted
3064 */
3065 flags |= BADCRL_NOT_TRUSTED;
3066 break;
3067 }
3068
3069 /*
3070 * Check for validity of CRL (Do not drop out)
3071 */
3072 if( x509parse_time_expired( &crl_list->next_update ) )
3073 flags |= BADCRL_EXPIRED;
3074
3075 /*
3076 * Check if certificate is revoked
3077 */
3078 if( x509parse_revoked(crt, crl_list) )
3079 {
3080 flags |= BADCERT_REVOKED;
3081 break;
3082 }
3083
3084 crl_list = crl_list->next;
3085 }
3086 return flags;
3087}
3088
Paul Bakker57b12982012-02-11 17:38:38 +00003089int x509_wildcard_verify( const char *cn, x509_buf *name )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003090{
3091 size_t i;
3092 size_t cn_idx = 0;
3093
Paul Bakker57b12982012-02-11 17:38:38 +00003094 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003095 return( 0 );
3096
3097 for( i = 0; i < strlen( cn ); ++i )
3098 {
3099 if( cn[i] == '.' )
3100 {
3101 cn_idx = i;
3102 break;
3103 }
3104 }
3105
3106 if( cn_idx == 0 )
3107 return( 0 );
3108
Paul Bakker535e97d2012-08-23 10:49:55 +00003109 if( strlen( cn ) - cn_idx == name->len - 1 &&
3110 memcmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003111 {
3112 return( 1 );
3113 }
3114
3115 return( 0 );
3116}
3117
Paul Bakker915275b2012-09-28 07:10:55 +00003118static int x509parse_verify_top(
3119 x509_cert *child, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003120 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003121 int (*f_vrfy)(void *, x509_cert *, int, int *),
3122 void *p_vrfy )
3123{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003124 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003125 int ca_flags = 0, check_path_cnt = path_cnt + 1;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003126 unsigned char hash[POLARSSL_MD_MAX_SIZE];
3127 const md_info_t *md_info;
Paul Bakker915275b2012-09-28 07:10:55 +00003128
3129 if( x509parse_time_expired( &child->valid_to ) )
3130 *flags |= BADCERT_EXPIRED;
3131
3132 /*
3133 * Child is the top of the chain. Check against the trust_ca list.
3134 */
3135 *flags |= BADCERT_NOT_TRUSTED;
3136
3137 while( trust_ca != NULL )
3138 {
3139 if( trust_ca->version == 0 ||
3140 child->issuer_raw.len != trust_ca->subject_raw.len ||
3141 memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
3142 child->issuer_raw.len ) != 0 )
3143 {
3144 trust_ca = trust_ca->next;
3145 continue;
3146 }
3147
Paul Bakker9a736322012-11-14 12:39:52 +00003148 /*
3149 * Reduce path_len to check against if top of the chain is
3150 * the same as the trusted CA
3151 */
3152 if( child->subject_raw.len == trust_ca->subject_raw.len &&
3153 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3154 child->issuer_raw.len ) == 0 )
3155 {
3156 check_path_cnt--;
3157 }
3158
Paul Bakker915275b2012-09-28 07:10:55 +00003159 if( trust_ca->max_pathlen > 0 &&
Paul Bakker9a736322012-11-14 12:39:52 +00003160 trust_ca->max_pathlen < check_path_cnt )
Paul Bakker915275b2012-09-28 07:10:55 +00003161 {
3162 trust_ca = trust_ca->next;
3163 continue;
3164 }
3165
Paul Bakkerc70b9822013-04-07 22:00:46 +02003166 md_info = md_info_from_type( child->sig_md );
3167 if( md_info == NULL )
3168 {
3169 /*
3170 * Cannot check 'unknown' hash
3171 */
3172 continue;
3173 }
Paul Bakker915275b2012-09-28 07:10:55 +00003174
Paul Bakkerc70b9822013-04-07 22:00:46 +02003175 md( md_info, child->tbs.p, child->tbs.len, hash );
Paul Bakker915275b2012-09-28 07:10:55 +00003176
Paul Bakkerc70b9822013-04-07 22:00:46 +02003177 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, child->sig_md,
Paul Bakker915275b2012-09-28 07:10:55 +00003178 0, hash, child->sig.p ) != 0 )
3179 {
3180 trust_ca = trust_ca->next;
3181 continue;
3182 }
3183
3184 /*
3185 * Top of chain is signed by a trusted CA
3186 */
3187 *flags &= ~BADCERT_NOT_TRUSTED;
3188 break;
3189 }
3190
Paul Bakker9a736322012-11-14 12:39:52 +00003191 /*
Paul Bakker3497d8c2012-11-24 11:53:17 +01003192 * If top of chain is not the same as the trusted CA send a verify request
3193 * to the callback for any issues with validity and CRL presence for the
3194 * trusted CA certificate.
Paul Bakker9a736322012-11-14 12:39:52 +00003195 */
3196 if( trust_ca != NULL &&
3197 ( child->subject_raw.len != trust_ca->subject_raw.len ||
3198 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3199 child->issuer_raw.len ) != 0 ) )
Paul Bakker915275b2012-09-28 07:10:55 +00003200 {
3201 /* Check trusted CA's CRL for then chain's top crt */
3202 *flags |= x509parse_verifycrl( child, trust_ca, ca_crl );
3203
3204 if( x509parse_time_expired( &trust_ca->valid_to ) )
3205 ca_flags |= BADCERT_EXPIRED;
3206
Paul Bakker915275b2012-09-28 07:10:55 +00003207 if( NULL != f_vrfy )
3208 {
Paul Bakker9a736322012-11-14 12:39:52 +00003209 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003210 return( ret );
3211 }
3212 }
3213
3214 /* Call callback on top cert */
3215 if( NULL != f_vrfy )
3216 {
Paul Bakker9a736322012-11-14 12:39:52 +00003217 if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003218 return( ret );
3219 }
3220
Paul Bakker915275b2012-09-28 07:10:55 +00003221 *flags |= ca_flags;
3222
3223 return( 0 );
3224}
3225
3226static int x509parse_verify_child(
3227 x509_cert *child, x509_cert *parent, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003228 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003229 int (*f_vrfy)(void *, x509_cert *, int, int *),
3230 void *p_vrfy )
3231{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003232 int ret;
Paul Bakker915275b2012-09-28 07:10:55 +00003233 int parent_flags = 0;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003234 unsigned char hash[POLARSSL_MD_MAX_SIZE];
Paul Bakker915275b2012-09-28 07:10:55 +00003235 x509_cert *grandparent;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003236 const md_info_t *md_info;
Paul Bakker915275b2012-09-28 07:10:55 +00003237
3238 if( x509parse_time_expired( &child->valid_to ) )
3239 *flags |= BADCERT_EXPIRED;
3240
Paul Bakkerc70b9822013-04-07 22:00:46 +02003241 md_info = md_info_from_type( child->sig_md );
3242 if( md_info == NULL )
3243 {
3244 /*
3245 * Cannot check 'unknown' hash
3246 */
Paul Bakker915275b2012-09-28 07:10:55 +00003247 *flags |= BADCERT_NOT_TRUSTED;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003248 }
3249 else
3250 {
3251 md( md_info, child->tbs.p, child->tbs.len, hash );
3252
3253 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, child->sig_md, 0, hash,
3254 child->sig.p ) != 0 )
3255 *flags |= BADCERT_NOT_TRUSTED;
3256 }
3257
Paul Bakker915275b2012-09-28 07:10:55 +00003258 /* Check trusted CA's CRL for the given crt */
3259 *flags |= x509parse_verifycrl(child, parent, ca_crl);
3260
3261 grandparent = parent->next;
3262
3263 while( grandparent != NULL )
3264 {
3265 if( grandparent->version == 0 ||
3266 grandparent->ca_istrue == 0 ||
3267 parent->issuer_raw.len != grandparent->subject_raw.len ||
3268 memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
3269 parent->issuer_raw.len ) != 0 )
3270 {
3271 grandparent = grandparent->next;
3272 continue;
3273 }
3274 break;
3275 }
3276
Paul Bakker915275b2012-09-28 07:10:55 +00003277 if( grandparent != NULL )
3278 {
3279 /*
3280 * Part of the chain
3281 */
Paul Bakker9a736322012-11-14 12:39:52 +00003282 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 +00003283 if( ret != 0 )
3284 return( ret );
3285 }
3286 else
3287 {
Paul Bakker9a736322012-11-14 12:39:52 +00003288 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 +00003289 if( ret != 0 )
3290 return( ret );
3291 }
3292
3293 /* child is verified to be a child of the parent, call verify callback */
3294 if( NULL != f_vrfy )
Paul Bakker9a736322012-11-14 12:39:52 +00003295 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003296 return( ret );
Paul Bakker915275b2012-09-28 07:10:55 +00003297
3298 *flags |= parent_flags;
3299
3300 return( 0 );
3301}
3302
Paul Bakker76fd75a2011-01-16 21:12:10 +00003303/*
Paul Bakker5121ce52009-01-03 21:22:43 +00003304 * Verify the certificate validity
3305 */
3306int x509parse_verify( x509_cert *crt,
3307 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00003308 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003309 const char *cn, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003310 int (*f_vrfy)(void *, x509_cert *, int, int *),
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003311 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00003312{
Paul Bakker23986e52011-04-24 08:57:21 +00003313 size_t cn_len;
Paul Bakker915275b2012-09-28 07:10:55 +00003314 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003315 int pathlen = 0;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003316 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00003317 x509_name *name;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003318 x509_sequence *cur = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003319
Paul Bakker40ea7de2009-05-03 10:18:48 +00003320 *flags = 0;
3321
Paul Bakker5121ce52009-01-03 21:22:43 +00003322 if( cn != NULL )
3323 {
3324 name = &crt->subject;
3325 cn_len = strlen( cn );
3326
Paul Bakker4d2c1242012-05-10 14:12:46 +00003327 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
Paul Bakker5121ce52009-01-03 21:22:43 +00003328 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00003329 cur = &crt->subject_alt_names;
3330
3331 while( cur != NULL )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003332 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003333 if( cur->buf.len == cn_len &&
3334 memcmp( cn, cur->buf.p, cn_len ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003335 break;
3336
Paul Bakker535e97d2012-08-23 10:49:55 +00003337 if( cur->buf.len > 2 &&
3338 memcmp( cur->buf.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003339 x509_wildcard_verify( cn, &cur->buf ) )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003340 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003341
Paul Bakker4d2c1242012-05-10 14:12:46 +00003342 cur = cur->next;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003343 }
3344
3345 if( cur == NULL )
3346 *flags |= BADCERT_CN_MISMATCH;
3347 }
Paul Bakker4d2c1242012-05-10 14:12:46 +00003348 else
3349 {
3350 while( name != NULL )
3351 {
Paul Bakkerc70b9822013-04-07 22:00:46 +02003352 if( OID_CMP( OID_AT_CN, &name->oid ) )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003353 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003354 if( name->val.len == cn_len &&
3355 memcmp( name->val.p, cn, cn_len ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003356 break;
3357
Paul Bakker535e97d2012-08-23 10:49:55 +00003358 if( name->val.len > 2 &&
3359 memcmp( name->val.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003360 x509_wildcard_verify( cn, &name->val ) )
3361 break;
3362 }
3363
3364 name = name->next;
3365 }
3366
3367 if( name == NULL )
3368 *flags |= BADCERT_CN_MISMATCH;
3369 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003370 }
3371
Paul Bakker5121ce52009-01-03 21:22:43 +00003372 /*
Paul Bakker915275b2012-09-28 07:10:55 +00003373 * Iterate upwards in the given cert chain, to find our crt parent.
3374 * Ignore any upper cert with CA != TRUE.
Paul Bakker5121ce52009-01-03 21:22:43 +00003375 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003376 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003377
Paul Bakker76fd75a2011-01-16 21:12:10 +00003378 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003379 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003380 if( parent->ca_istrue == 0 ||
3381 crt->issuer_raw.len != parent->subject_raw.len ||
3382 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00003383 crt->issuer_raw.len ) != 0 )
3384 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003385 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003386 continue;
3387 }
Paul Bakker915275b2012-09-28 07:10:55 +00003388 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003389 }
3390
Paul Bakker915275b2012-09-28 07:10:55 +00003391 if( parent != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003392 {
Paul Bakker915275b2012-09-28 07:10:55 +00003393 /*
3394 * Part of the chain
3395 */
Paul Bakker9a736322012-11-14 12:39:52 +00003396 ret = x509parse_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003397 if( ret != 0 )
3398 return( ret );
3399 }
3400 else
Paul Bakker74111d32011-01-15 16:57:55 +00003401 {
Paul Bakker9a736322012-11-14 12:39:52 +00003402 ret = x509parse_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003403 if( ret != 0 )
3404 return( ret );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003405 }
Paul Bakker915275b2012-09-28 07:10:55 +00003406
3407 if( *flags != 0 )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003408 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003409
Paul Bakker5121ce52009-01-03 21:22:43 +00003410 return( 0 );
3411}
3412
3413/*
3414 * Unallocate all certificate data
3415 */
3416void x509_free( x509_cert *crt )
3417{
3418 x509_cert *cert_cur = crt;
3419 x509_cert *cert_prv;
3420 x509_name *name_cur;
3421 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00003422 x509_sequence *seq_cur;
3423 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00003424
3425 if( crt == NULL )
3426 return;
3427
3428 do
3429 {
3430 rsa_free( &cert_cur->rsa );
3431
3432 name_cur = cert_cur->issuer.next;
3433 while( name_cur != NULL )
3434 {
3435 name_prv = name_cur;
3436 name_cur = name_cur->next;
3437 memset( name_prv, 0, sizeof( x509_name ) );
3438 free( name_prv );
3439 }
3440
3441 name_cur = cert_cur->subject.next;
3442 while( name_cur != NULL )
3443 {
3444 name_prv = name_cur;
3445 name_cur = name_cur->next;
3446 memset( name_prv, 0, sizeof( x509_name ) );
3447 free( name_prv );
3448 }
3449
Paul Bakker74111d32011-01-15 16:57:55 +00003450 seq_cur = cert_cur->ext_key_usage.next;
3451 while( seq_cur != NULL )
3452 {
3453 seq_prv = seq_cur;
3454 seq_cur = seq_cur->next;
3455 memset( seq_prv, 0, sizeof( x509_sequence ) );
3456 free( seq_prv );
3457 }
3458
Paul Bakker8afa70d2012-02-11 18:42:45 +00003459 seq_cur = cert_cur->subject_alt_names.next;
3460 while( seq_cur != NULL )
3461 {
3462 seq_prv = seq_cur;
3463 seq_cur = seq_cur->next;
3464 memset( seq_prv, 0, sizeof( x509_sequence ) );
3465 free( seq_prv );
3466 }
3467
Paul Bakker5121ce52009-01-03 21:22:43 +00003468 if( cert_cur->raw.p != NULL )
3469 {
3470 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
3471 free( cert_cur->raw.p );
3472 }
3473
3474 cert_cur = cert_cur->next;
3475 }
3476 while( cert_cur != NULL );
3477
3478 cert_cur = crt;
3479 do
3480 {
3481 cert_prv = cert_cur;
3482 cert_cur = cert_cur->next;
3483
3484 memset( cert_prv, 0, sizeof( x509_cert ) );
3485 if( cert_prv != crt )
3486 free( cert_prv );
3487 }
3488 while( cert_cur != NULL );
3489}
3490
Paul Bakkerd98030e2009-05-02 15:13:40 +00003491/*
3492 * Unallocate all CRL data
3493 */
3494void x509_crl_free( x509_crl *crl )
3495{
3496 x509_crl *crl_cur = crl;
3497 x509_crl *crl_prv;
3498 x509_name *name_cur;
3499 x509_name *name_prv;
3500 x509_crl_entry *entry_cur;
3501 x509_crl_entry *entry_prv;
3502
3503 if( crl == NULL )
3504 return;
3505
3506 do
3507 {
3508 name_cur = crl_cur->issuer.next;
3509 while( name_cur != NULL )
3510 {
3511 name_prv = name_cur;
3512 name_cur = name_cur->next;
3513 memset( name_prv, 0, sizeof( x509_name ) );
3514 free( name_prv );
3515 }
3516
3517 entry_cur = crl_cur->entry.next;
3518 while( entry_cur != NULL )
3519 {
3520 entry_prv = entry_cur;
3521 entry_cur = entry_cur->next;
3522 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
3523 free( entry_prv );
3524 }
3525
3526 if( crl_cur->raw.p != NULL )
3527 {
3528 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
3529 free( crl_cur->raw.p );
3530 }
3531
3532 crl_cur = crl_cur->next;
3533 }
3534 while( crl_cur != NULL );
3535
3536 crl_cur = crl;
3537 do
3538 {
3539 crl_prv = crl_cur;
3540 crl_cur = crl_cur->next;
3541
3542 memset( crl_prv, 0, sizeof( x509_crl ) );
3543 if( crl_prv != crl )
3544 free( crl_prv );
3545 }
3546 while( crl_cur != NULL );
3547}
3548
Paul Bakker40e46942009-01-03 21:51:57 +00003549#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00003550
Paul Bakker40e46942009-01-03 21:51:57 +00003551#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00003552
3553/*
3554 * Checkup routine
3555 */
3556int x509_self_test( int verbose )
3557{
Paul Bakker5690efc2011-05-26 13:16:06 +00003558#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00003559 int ret;
3560 int flags;
3561 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00003562 x509_cert cacert;
3563 x509_cert clicert;
3564 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00003565#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003566 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00003567#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003568
3569 if( verbose != 0 )
3570 printf( " X.509 certificate load: " );
3571
3572 memset( &clicert, 0, sizeof( x509_cert ) );
3573
Paul Bakker3c2122f2013-06-24 19:03:14 +02003574 ret = x509parse_crt( &clicert, (const unsigned char *) test_cli_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003575 strlen( test_cli_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003576 if( ret != 0 )
3577 {
3578 if( verbose != 0 )
3579 printf( "failed\n" );
3580
3581 return( ret );
3582 }
3583
3584 memset( &cacert, 0, sizeof( x509_cert ) );
3585
Paul Bakker3c2122f2013-06-24 19:03:14 +02003586 ret = x509parse_crt( &cacert, (const unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003587 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003588 if( ret != 0 )
3589 {
3590 if( verbose != 0 )
3591 printf( "failed\n" );
3592
3593 return( ret );
3594 }
3595
3596 if( verbose != 0 )
3597 printf( "passed\n X.509 private key load: " );
3598
3599 i = strlen( test_ca_key );
3600 j = strlen( test_ca_pwd );
3601
Paul Bakker66b78b22011-03-25 14:22:50 +00003602 rsa_init( &rsa, RSA_PKCS_V15, 0 );
3603
Paul Bakker5121ce52009-01-03 21:22:43 +00003604 if( ( ret = x509parse_key( &rsa,
Paul Bakker3c2122f2013-06-24 19:03:14 +02003605 (const unsigned char *) test_ca_key, i,
3606 (const unsigned char *) test_ca_pwd, j ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003607 {
3608 if( verbose != 0 )
3609 printf( "failed\n" );
3610
3611 return( ret );
3612 }
3613
3614 if( verbose != 0 )
3615 printf( "passed\n X.509 signature verify: ");
3616
Paul Bakker23986e52011-04-24 08:57:21 +00003617 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003618 if( ret != 0 )
3619 {
Paul Bakker23986e52011-04-24 08:57:21 +00003620 printf("%02x", flags);
Paul Bakker5121ce52009-01-03 21:22:43 +00003621 if( verbose != 0 )
3622 printf( "failed\n" );
3623
3624 return( ret );
3625 }
3626
Paul Bakker5690efc2011-05-26 13:16:06 +00003627#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003628 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003629 printf( "passed\n X.509 DHM parameter load: " );
3630
3631 i = strlen( test_dhm_params );
3632 j = strlen( test_ca_pwd );
3633
Paul Bakker3c2122f2013-06-24 19:03:14 +02003634 if( ( ret = x509parse_dhm( &dhm, (const unsigned char *) test_dhm_params, i ) ) != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003635 {
3636 if( verbose != 0 )
3637 printf( "failed\n" );
3638
3639 return( ret );
3640 }
3641
3642 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003643 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00003644#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003645
3646 x509_free( &cacert );
3647 x509_free( &clicert );
3648 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00003649#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003650 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00003651#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003652
3653 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003654#else
3655 ((void) verbose);
3656 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3657#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003658}
3659
3660#endif
3661
3662#endif