blob: 49c170528aa1e91441575fa6006db192acb12a7b [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * X.509 certificate and private key decoding
3 *
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02004 * Copyright (C) 2006-2013, 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 Bakker1b57b062011-01-06 15:48:19 +000045#include "polarssl/dhm.h"
Paul Bakker28144de2013-06-24 19:28:55 +020046#if defined(POLARSSL_PKCS5_C)
47#include "polarssl/pkcs5.h"
48#endif
Paul Bakker38b50d72013-06-24 19:33:27 +020049#if defined(POLARSSL_PKCS12_C)
50#include "polarssl/pkcs12.h"
51#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000052
53#include <string.h>
54#include <stdlib.h>
Paul Bakker4f229e52011-12-04 22:11:35 +000055#if defined(_WIN32)
Paul Bakkercce9d772011-11-18 14:26:47 +000056#include <windows.h>
57#else
Paul Bakker5121ce52009-01-03 21:22:43 +000058#include <time.h>
Paul Bakkercce9d772011-11-18 14:26:47 +000059#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000060
Paul Bakker335db3f2011-04-25 15:28:35 +000061#if defined(POLARSSL_FS_IO)
62#include <stdio.h>
Paul Bakker4a2bd0d2012-11-02 11:06:08 +000063#if !defined(_WIN32)
Paul Bakker8d914582012-06-04 12:46:42 +000064#include <sys/types.h>
Paul Bakker2c8cdd22013-06-24 19:22:42 +020065#include <sys/stat.h>
Paul Bakker8d914582012-06-04 12:46:42 +000066#include <dirent.h>
67#endif
Paul Bakker335db3f2011-04-25 15:28:35 +000068#endif
69
Paul Bakker5121ce52009-01-03 21:22:43 +000070/*
Paul Bakker5121ce52009-01-03 21:22:43 +000071 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
72 */
73static int x509_get_version( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +000074 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +000075 int *ver )
76{
Paul Bakker23986e52011-04-24 08:57:21 +000077 int ret;
78 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +000079
80 if( ( ret = asn1_get_tag( p, end, &len,
81 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
82 {
Paul Bakker40e46942009-01-03 21:51:57 +000083 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +000084 {
85 *ver = 0;
86 return( 0 );
87 }
Paul Bakker5121ce52009-01-03 21:22:43 +000088
89 return( ret );
90 }
91
92 end = *p + len;
93
94 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +000095 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +000096
97 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +000098 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION +
Paul Bakker40e46942009-01-03 21:51:57 +000099 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000100
101 return( 0 );
102}
103
104/*
Paul Bakkerfae618f2011-10-12 11:53:52 +0000105 * Version ::= INTEGER { v1(0), v2(1) }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000106 */
107static int x509_crl_get_version( unsigned char **p,
108 const unsigned char *end,
109 int *ver )
110{
111 int ret;
112
113 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
114 {
115 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +0000116 {
117 *ver = 0;
118 return( 0 );
119 }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000120
121 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
122 }
123
124 return( 0 );
125}
126
127/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000128 * CertificateSerialNumber ::= INTEGER
129 */
130static int x509_get_serial( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000131 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000132 x509_buf *serial )
133{
134 int ret;
135
136 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000137 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000138 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000139
140 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
141 **p != ASN1_INTEGER )
Paul Bakker9d781402011-05-09 16:17:09 +0000142 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000143 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000144
145 serial->tag = *(*p)++;
146
147 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000148 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000149
150 serial->p = *p;
151 *p += serial->len;
152
153 return( 0 );
154}
155
156/*
157 * AlgorithmIdentifier ::= SEQUENCE {
158 * algorithm OBJECT IDENTIFIER,
159 * parameters ANY DEFINED BY algorithm OPTIONAL }
160 */
161static int x509_get_alg( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000162 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000163 x509_buf *alg )
164{
Paul Bakker23986e52011-04-24 08:57:21 +0000165 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000166
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200167 if( ( ret = asn1_get_alg_null( p, end, alg ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000168 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000169
Paul Bakker5121ce52009-01-03 21:22:43 +0000170 return( 0 );
171}
172
173/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000174 * AttributeTypeAndValue ::= SEQUENCE {
175 * type AttributeType,
176 * value AttributeValue }
177 *
178 * AttributeType ::= OBJECT IDENTIFIER
179 *
180 * AttributeValue ::= ANY DEFINED BY AttributeType
181 */
Paul Bakker400ff6f2011-02-20 10:40:16 +0000182static int x509_get_attr_type_value( unsigned char **p,
183 const unsigned char *end,
184 x509_name *cur )
Paul Bakker5121ce52009-01-03 21:22:43 +0000185{
Paul Bakker23986e52011-04-24 08:57:21 +0000186 int ret;
187 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000188 x509_buf *oid;
189 x509_buf *val;
190
191 if( ( ret = asn1_get_tag( p, end, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000192 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000193 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000194
Paul Bakker5121ce52009-01-03 21:22:43 +0000195 oid = &cur->oid;
196 oid->tag = **p;
197
198 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000199 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000200
201 oid->p = *p;
202 *p += oid->len;
203
204 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000205 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000206 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000207
208 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
209 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
210 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker9d781402011-05-09 16:17:09 +0000211 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000212 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000213
214 val = &cur->val;
215 val->tag = *(*p)++;
216
217 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000218 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000219
220 val->p = *p;
221 *p += val->len;
222
223 cur->next = NULL;
224
Paul Bakker400ff6f2011-02-20 10:40:16 +0000225 return( 0 );
226}
227
228/*
229 * RelativeDistinguishedName ::=
230 * SET OF AttributeTypeAndValue
231 *
232 * AttributeTypeAndValue ::= SEQUENCE {
233 * type AttributeType,
234 * value AttributeValue }
235 *
236 * AttributeType ::= OBJECT IDENTIFIER
237 *
238 * AttributeValue ::= ANY DEFINED BY AttributeType
239 */
240static int x509_get_name( unsigned char **p,
241 const unsigned char *end,
242 x509_name *cur )
243{
Paul Bakker23986e52011-04-24 08:57:21 +0000244 int ret;
245 size_t len;
Paul Bakker400ff6f2011-02-20 10:40:16 +0000246 const unsigned char *end2;
247 x509_name *use;
248
249 if( ( ret = asn1_get_tag( p, end, &len,
250 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000251 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000252
253 end2 = end;
254 end = *p + len;
255 use = cur;
256
257 do
258 {
259 if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
260 return( ret );
261
262 if( *p != end )
263 {
264 use->next = (x509_name *) malloc(
265 sizeof( x509_name ) );
266
267 if( use->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000268 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000269
270 memset( use->next, 0, sizeof( x509_name ) );
271
272 use = use->next;
273 }
274 }
275 while( *p != end );
Paul Bakker5121ce52009-01-03 21:22:43 +0000276
277 /*
278 * recurse until end of SEQUENCE is reached
279 */
280 if( *p == end2 )
281 return( 0 );
282
283 cur->next = (x509_name *) malloc(
284 sizeof( x509_name ) );
285
286 if( cur->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000287 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000288
Paul Bakker430ffbe2012-05-01 08:14:20 +0000289 memset( cur->next, 0, sizeof( x509_name ) );
290
Paul Bakker5121ce52009-01-03 21:22:43 +0000291 return( x509_get_name( p, end2, cur->next ) );
292}
293
294/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000295 * Time ::= CHOICE {
296 * utcTime UTCTime,
297 * generalTime GeneralizedTime }
298 */
Paul Bakker91200182010-02-18 21:26:15 +0000299static int x509_get_time( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000300 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000301 x509_time *time )
302{
Paul Bakker23986e52011-04-24 08:57:21 +0000303 int ret;
304 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000305 char date[64];
Paul Bakker91200182010-02-18 21:26:15 +0000306 unsigned char tag;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000307
Paul Bakker91200182010-02-18 21:26:15 +0000308 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000309 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
310 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000311
Paul Bakker91200182010-02-18 21:26:15 +0000312 tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000313
Paul Bakker91200182010-02-18 21:26:15 +0000314 if ( tag == ASN1_UTC_TIME )
315 {
316 (*p)++;
317 ret = asn1_get_len( p, end, &len );
318
319 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000320 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000321
Paul Bakker91200182010-02-18 21:26:15 +0000322 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000323 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
324 len : sizeof( date ) - 1 );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000325
Paul Bakker91200182010-02-18 21:26:15 +0000326 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
327 &time->year, &time->mon, &time->day,
328 &time->hour, &time->min, &time->sec ) < 5 )
329 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000330
Paul Bakker400ff6f2011-02-20 10:40:16 +0000331 time->year += 100 * ( time->year < 50 );
Paul Bakker91200182010-02-18 21:26:15 +0000332 time->year += 1900;
333
334 *p += len;
335
336 return( 0 );
337 }
338 else if ( tag == ASN1_GENERALIZED_TIME )
339 {
340 (*p)++;
341 ret = asn1_get_len( p, end, &len );
342
343 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000344 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker91200182010-02-18 21:26:15 +0000345
346 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000347 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
348 len : sizeof( date ) - 1 );
Paul Bakker91200182010-02-18 21:26:15 +0000349
350 if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
351 &time->year, &time->mon, &time->day,
352 &time->hour, &time->min, &time->sec ) < 5 )
353 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
354
355 *p += len;
356
357 return( 0 );
358 }
359 else
Paul Bakker9d781402011-05-09 16:17:09 +0000360 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000361}
362
363
364/*
365 * Validity ::= SEQUENCE {
366 * notBefore Time,
367 * notAfter Time }
368 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000369static int x509_get_dates( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000370 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000371 x509_time *from,
372 x509_time *to )
373{
Paul Bakker23986e52011-04-24 08:57:21 +0000374 int ret;
375 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000376
377 if( ( ret = asn1_get_tag( p, end, &len,
378 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000379 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000380
381 end = *p + len;
382
Paul Bakker91200182010-02-18 21:26:15 +0000383 if( ( ret = x509_get_time( p, end, from ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000384 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000385
Paul Bakker91200182010-02-18 21:26:15 +0000386 if( ( ret = x509_get_time( p, end, to ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000387 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000388
389 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000390 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker40e46942009-01-03 21:51:57 +0000391 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000392
393 return( 0 );
394}
395
396/*
397 * SubjectPublicKeyInfo ::= SEQUENCE {
398 * algorithm AlgorithmIdentifier,
399 * subjectPublicKey BIT STRING }
400 */
401static int x509_get_pubkey( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000402 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000403 x509_buf *pk_alg_oid,
404 mpi *N, mpi *E )
405{
Paul Bakkerc70b9822013-04-07 22:00:46 +0200406 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000407 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000408 unsigned char *end2;
Paul Bakkerc70b9822013-04-07 22:00:46 +0200409 pk_type_t pk_alg = POLARSSL_PK_NONE;
Paul Bakker5121ce52009-01-03 21:22:43 +0000410
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200411 if( ( ret = asn1_get_alg_null( p, end, pk_alg_oid ) ) != 0 )
412 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000413
414 /*
415 * only RSA public keys handled at this time
416 */
Paul Bakkerc70b9822013-04-07 22:00:46 +0200417 if( oid_get_pk_alg( pk_alg_oid, &pk_alg ) != 0 )
Paul Bakkered56b222011-07-13 11:26:43 +0000418 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000419
420 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000421 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000422
423 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000424 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000425 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000426
427 end2 = *p + len;
428
429 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000430 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000431
432 /*
433 * RSAPublicKey ::= SEQUENCE {
434 * modulus INTEGER, -- n
435 * publicExponent INTEGER -- e
436 * }
437 */
438 if( ( ret = asn1_get_tag( p, end2, &len,
439 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000440 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000441
442 if( *p + len != end2 )
Paul Bakker9d781402011-05-09 16:17:09 +0000443 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000444 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000445
446 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
447 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000448 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000449
450 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000451 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000452 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000453
454 return( 0 );
455}
456
457static int x509_get_sig( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000458 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000459 x509_buf *sig )
460{
Paul Bakker23986e52011-04-24 08:57:21 +0000461 int ret;
462 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000463
Paul Bakker8afa70d2012-02-11 18:42:45 +0000464 if( ( end - *p ) < 1 )
465 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE +
466 POLARSSL_ERR_ASN1_OUT_OF_DATA );
467
Paul Bakker5121ce52009-01-03 21:22:43 +0000468 sig->tag = **p;
469
470 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000471 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000472
Paul Bakker74111d32011-01-15 16:57:55 +0000473
Paul Bakker5121ce52009-01-03 21:22:43 +0000474 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000475 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000476
477 sig->len = len;
478 sig->p = *p;
479
480 *p += len;
481
482 return( 0 );
483}
484
485/*
486 * X.509 v2/v3 unique identifier (not parsed)
487 */
488static int x509_get_uid( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000489 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000490 x509_buf *uid, int n )
491{
492 int ret;
493
494 if( *p == end )
495 return( 0 );
496
497 uid->tag = **p;
498
499 if( ( ret = asn1_get_tag( p, end, &uid->len,
500 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
501 {
Paul Bakker40e46942009-01-03 21:51:57 +0000502 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000503 return( 0 );
504
505 return( ret );
506 }
507
508 uid->p = *p;
509 *p += uid->len;
510
511 return( 0 );
512}
513
514/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000515 * X.509 Extensions (No parsing of extensions, pointer should
516 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000517 */
518static int x509_get_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000519 const unsigned char *end,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000520 x509_buf *ext, int tag )
Paul Bakker5121ce52009-01-03 21:22:43 +0000521{
Paul Bakker23986e52011-04-24 08:57:21 +0000522 int ret;
523 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000524
525 if( *p == end )
526 return( 0 );
527
528 ext->tag = **p;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000529
Paul Bakker5121ce52009-01-03 21:22:43 +0000530 if( ( ret = asn1_get_tag( p, end, &ext->len,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000531 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000532 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000533
534 ext->p = *p;
535 end = *p + ext->len;
536
537 /*
538 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
539 *
540 * Extension ::= SEQUENCE {
541 * extnID OBJECT IDENTIFIER,
542 * critical BOOLEAN DEFAULT FALSE,
543 * extnValue OCTET STRING }
544 */
545 if( ( ret = asn1_get_tag( p, end, &len,
546 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000547 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000548
549 if( end != *p + len )
Paul Bakker9d781402011-05-09 16:17:09 +0000550 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +0000551 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000552
Paul Bakkerd98030e2009-05-02 15:13:40 +0000553 return( 0 );
554}
555
556/*
557 * X.509 CRL v2 extensions (no extensions parsed yet.)
558 */
559static int x509_get_crl_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000560 const unsigned char *end,
561 x509_buf *ext )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000562{
Paul Bakker23986e52011-04-24 08:57:21 +0000563 int ret;
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000564 size_t len = 0;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000565
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000566 /* Get explicit tag */
567 if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000568 {
569 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
570 return( 0 );
571
572 return( ret );
573 }
574
575 while( *p < end )
576 {
577 if( ( ret = asn1_get_tag( p, end, &len,
578 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000579 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000580
581 *p += len;
582 }
583
584 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000585 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerd98030e2009-05-02 15:13:40 +0000586 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
587
588 return( 0 );
589}
590
Paul Bakkerb5a11ab2011-10-12 09:58:41 +0000591/*
592 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
593 */
594static int x509_get_crl_entry_ext( unsigned char **p,
595 const unsigned char *end,
596 x509_buf *ext )
597{
598 int ret;
599 size_t len = 0;
600
601 /* OPTIONAL */
602 if (end <= *p)
603 return( 0 );
604
605 ext->tag = **p;
606 ext->p = *p;
607
608 /*
609 * Get CRL-entry extension sequence header
610 * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
611 */
612 if( ( ret = asn1_get_tag( p, end, &ext->len,
613 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
614 {
615 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
616 {
617 ext->p = NULL;
618 return( 0 );
619 }
620 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
621 }
622
623 end = *p + ext->len;
624
625 if( end != *p + ext->len )
626 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
627 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
628
629 while( *p < end )
630 {
631 if( ( ret = asn1_get_tag( p, end, &len,
632 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
633 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
634
635 *p += len;
636 }
637
638 if( *p != end )
639 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
640 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
641
642 return( 0 );
643}
644
Paul Bakker74111d32011-01-15 16:57:55 +0000645static int x509_get_basic_constraints( unsigned char **p,
646 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000647 int *ca_istrue,
648 int *max_pathlen )
649{
Paul Bakker23986e52011-04-24 08:57:21 +0000650 int ret;
651 size_t len;
Paul Bakker74111d32011-01-15 16:57:55 +0000652
653 /*
654 * BasicConstraints ::= SEQUENCE {
655 * cA BOOLEAN DEFAULT FALSE,
656 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
657 */
Paul Bakker3cccddb2011-01-16 21:46:31 +0000658 *ca_istrue = 0; /* DEFAULT FALSE */
Paul Bakker74111d32011-01-15 16:57:55 +0000659 *max_pathlen = 0; /* endless */
660
661 if( ( ret = asn1_get_tag( p, end, &len,
662 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000663 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000664
665 if( *p == end )
666 return 0;
667
Paul Bakker3cccddb2011-01-16 21:46:31 +0000668 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000669 {
670 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker3cccddb2011-01-16 21:46:31 +0000671 ret = asn1_get_int( p, end, ca_istrue );
Paul Bakker74111d32011-01-15 16:57:55 +0000672
673 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000674 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000675
Paul Bakker3cccddb2011-01-16 21:46:31 +0000676 if( *ca_istrue != 0 )
677 *ca_istrue = 1;
Paul Bakker74111d32011-01-15 16:57:55 +0000678 }
679
680 if( *p == end )
681 return 0;
682
683 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000684 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000685
686 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000687 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000688 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
689
690 (*max_pathlen)++;
691
Paul Bakker74111d32011-01-15 16:57:55 +0000692 return 0;
693}
694
695static int x509_get_ns_cert_type( unsigned char **p,
696 const unsigned char *end,
697 unsigned char *ns_cert_type)
698{
699 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000700 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000701
702 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000703 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000704
705 if( bs.len != 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000706 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000707 POLARSSL_ERR_ASN1_INVALID_LENGTH );
708
709 /* Get actual bitstring */
710 *ns_cert_type = *bs.p;
711 return 0;
712}
713
714static int x509_get_key_usage( unsigned char **p,
715 const unsigned char *end,
716 unsigned char *key_usage)
717{
718 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000719 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000720
721 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000722 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000723
Paul Bakker94a67962012-08-23 13:03:52 +0000724 if( bs.len < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000725 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000726 POLARSSL_ERR_ASN1_INVALID_LENGTH );
727
728 /* Get actual bitstring */
729 *key_usage = *bs.p;
730 return 0;
731}
732
Paul Bakkerd98030e2009-05-02 15:13:40 +0000733/*
Paul Bakker74111d32011-01-15 16:57:55 +0000734 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
735 *
736 * KeyPurposeId ::= OBJECT IDENTIFIER
737 */
738static int x509_get_ext_key_usage( unsigned char **p,
739 const unsigned char *end,
740 x509_sequence *ext_key_usage)
741{
742 int ret;
743
744 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000745 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000746
747 /* Sequence length must be >= 1 */
748 if( ext_key_usage->buf.p == NULL )
Paul Bakker9d781402011-05-09 16:17:09 +0000749 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000750 POLARSSL_ERR_ASN1_INVALID_LENGTH );
751
752 return 0;
753}
754
755/*
Paul Bakkera8cd2392012-02-11 16:09:32 +0000756 * SubjectAltName ::= GeneralNames
757 *
758 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
759 *
760 * GeneralName ::= CHOICE {
761 * otherName [0] OtherName,
762 * rfc822Name [1] IA5String,
763 * dNSName [2] IA5String,
764 * x400Address [3] ORAddress,
765 * directoryName [4] Name,
766 * ediPartyName [5] EDIPartyName,
767 * uniformResourceIdentifier [6] IA5String,
768 * iPAddress [7] OCTET STRING,
769 * registeredID [8] OBJECT IDENTIFIER }
770 *
771 * OtherName ::= SEQUENCE {
772 * type-id OBJECT IDENTIFIER,
773 * value [0] EXPLICIT ANY DEFINED BY type-id }
774 *
775 * EDIPartyName ::= SEQUENCE {
776 * nameAssigner [0] DirectoryString OPTIONAL,
777 * partyName [1] DirectoryString }
778 *
779 * NOTE: PolarSSL only parses and uses dNSName at this point.
780 */
781static int x509_get_subject_alt_name( unsigned char **p,
782 const unsigned char *end,
783 x509_sequence *subject_alt_name )
784{
785 int ret;
786 size_t len, tag_len;
787 asn1_buf *buf;
788 unsigned char tag;
789 asn1_sequence *cur = subject_alt_name;
790
791 /* Get main sequence tag */
792 if( ( ret = asn1_get_tag( p, end, &len,
793 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
794 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
795
796 if( *p + len != end )
797 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
798 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
799
800 while( *p < end )
801 {
802 if( ( end - *p ) < 1 )
803 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
804 POLARSSL_ERR_ASN1_OUT_OF_DATA );
805
806 tag = **p;
807 (*p)++;
808 if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 )
809 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
810
811 if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC )
812 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
813 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
814
815 if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) )
816 {
817 *p += tag_len;
818 continue;
819 }
820
821 buf = &(cur->buf);
822 buf->tag = tag;
823 buf->p = *p;
824 buf->len = tag_len;
825 *p += buf->len;
826
827 /* Allocate and assign next pointer */
828 if (*p < end)
829 {
830 cur->next = (asn1_sequence *) malloc(
831 sizeof( asn1_sequence ) );
832
833 if( cur->next == NULL )
834 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
835 POLARSSL_ERR_ASN1_MALLOC_FAILED );
836
Paul Bakker535e97d2012-08-23 10:49:55 +0000837 memset( cur->next, 0, sizeof( asn1_sequence ) );
Paul Bakkera8cd2392012-02-11 16:09:32 +0000838 cur = cur->next;
839 }
840 }
841
842 /* Set final sequence entry's next pointer to NULL */
843 cur->next = NULL;
844
845 if( *p != end )
846 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
847 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
848
849 return( 0 );
850}
851
852/*
Paul Bakker74111d32011-01-15 16:57:55 +0000853 * X.509 v3 extensions
854 *
855 * TODO: Perform all of the basic constraints tests required by the RFC
856 * TODO: Set values for undetected extensions to a sane default?
857 *
Paul Bakkerd98030e2009-05-02 15:13:40 +0000858 */
859static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000860 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000861 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000862{
Paul Bakker23986e52011-04-24 08:57:21 +0000863 int ret;
864 size_t len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000865 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000866
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000867 if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000868 {
869 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
870 return( 0 );
871
872 return( ret );
873 }
874
Paul Bakker5121ce52009-01-03 21:22:43 +0000875 while( *p < end )
876 {
Paul Bakker74111d32011-01-15 16:57:55 +0000877 /*
878 * Extension ::= SEQUENCE {
879 * extnID OBJECT IDENTIFIER,
880 * critical BOOLEAN DEFAULT FALSE,
881 * extnValue OCTET STRING }
882 */
883 x509_buf extn_oid = {0, 0, NULL};
884 int is_critical = 0; /* DEFAULT FALSE */
Paul Bakkerc70b9822013-04-07 22:00:46 +0200885 int ext_type = 0;
Paul Bakker74111d32011-01-15 16:57:55 +0000886
Paul Bakker5121ce52009-01-03 21:22:43 +0000887 if( ( ret = asn1_get_tag( p, end, &len,
888 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000889 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000890
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000891 end_ext_data = *p + len;
892
Paul Bakker74111d32011-01-15 16:57:55 +0000893 /* Get extension ID */
894 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000895
Paul Bakker74111d32011-01-15 16:57:55 +0000896 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000897 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000898
Paul Bakker74111d32011-01-15 16:57:55 +0000899 extn_oid.p = *p;
900 *p += extn_oid.len;
901
902 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000903 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000904 POLARSSL_ERR_ASN1_OUT_OF_DATA );
905
906 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000907 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000908 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
Paul Bakker9d781402011-05-09 16:17:09 +0000909 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000910
Paul Bakker74111d32011-01-15 16:57:55 +0000911 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000912 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000913 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000914 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000915
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000916 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000917
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000918 if( end_ext_octet != end_ext_data )
Paul Bakker9d781402011-05-09 16:17:09 +0000919 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000920 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000921
Paul Bakker74111d32011-01-15 16:57:55 +0000922 /*
923 * Detect supported extensions
924 */
Paul Bakkerc70b9822013-04-07 22:00:46 +0200925 ret = oid_get_x509_ext_type( &extn_oid, &ext_type );
926
927 if( ret != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000928 {
929 /* No parser found, skip extension */
930 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +0000931
Paul Bakker5c721f92011-07-27 16:51:09 +0000932#if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
Paul Bakker74111d32011-01-15 16:57:55 +0000933 if( is_critical )
934 {
935 /* Data is marked as critical: fail */
Paul Bakker9d781402011-05-09 16:17:09 +0000936 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000937 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
938 }
Paul Bakker5c721f92011-07-27 16:51:09 +0000939#endif
Paul Bakkerc70b9822013-04-07 22:00:46 +0200940 continue;
941 }
942
943 crt->ext_types |= ext_type;
944
945 switch( ext_type )
946 {
947 case EXT_BASIC_CONSTRAINTS:
948 /* Parse basic constraints */
949 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
950 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
951 return ( ret );
952 break;
953
954 case EXT_KEY_USAGE:
955 /* Parse key usage */
956 if( ( ret = x509_get_key_usage( p, end_ext_octet,
957 &crt->key_usage ) ) != 0 )
958 return ( ret );
959 break;
960
961 case EXT_EXTENDED_KEY_USAGE:
962 /* Parse extended key usage */
963 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
964 &crt->ext_key_usage ) ) != 0 )
965 return ( ret );
966 break;
967
968 case EXT_SUBJECT_ALT_NAME:
969 /* Parse subject alt name */
970 if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
971 &crt->subject_alt_names ) ) != 0 )
972 return ( ret );
973 break;
974
975 case EXT_NS_CERT_TYPE:
976 /* Parse netscape certificate type */
977 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
978 &crt->ns_cert_type ) ) != 0 )
979 return ( ret );
980 break;
981
982 default:
983 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
Paul Bakker74111d32011-01-15 16:57:55 +0000984 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000985 }
986
987 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000988 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +0000989 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000990
Paul Bakker5121ce52009-01-03 21:22:43 +0000991 return( 0 );
992}
993
994/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000995 * X.509 CRL Entries
996 */
997static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000998 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000999 x509_crl_entry *entry )
1000{
Paul Bakker23986e52011-04-24 08:57:21 +00001001 int ret;
1002 size_t entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001003 x509_crl_entry *cur_entry = entry;
1004
1005 if( *p == end )
1006 return( 0 );
1007
Paul Bakker9be19372009-07-27 20:21:53 +00001008 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001009 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1010 {
1011 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
1012 return( 0 );
1013
1014 return( ret );
1015 }
1016
Paul Bakker9be19372009-07-27 20:21:53 +00001017 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001018
1019 while( *p < end )
1020 {
Paul Bakker23986e52011-04-24 08:57:21 +00001021 size_t len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001022 const unsigned char *end2;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001023
1024 if( ( ret = asn1_get_tag( p, end, &len2,
1025 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1026 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001027 return( ret );
1028 }
1029
Paul Bakker9be19372009-07-27 20:21:53 +00001030 cur_entry->raw.tag = **p;
1031 cur_entry->raw.p = *p;
1032 cur_entry->raw.len = len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001033 end2 = *p + len2;
Paul Bakker9be19372009-07-27 20:21:53 +00001034
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001035 if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001036 return( ret );
1037
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001038 if( ( ret = x509_get_time( p, end2, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001039 return( ret );
1040
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001041 if( ( ret = x509_get_crl_entry_ext( p, end2, &cur_entry->entry_ext ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001042 return( ret );
1043
Paul Bakker74111d32011-01-15 16:57:55 +00001044 if ( *p < end )
1045 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001046 cur_entry->next = malloc( sizeof( x509_crl_entry ) );
Paul Bakkerb15b8512012-01-13 13:44:06 +00001047
1048 if( cur_entry->next == NULL )
1049 return( POLARSSL_ERR_X509_MALLOC_FAILED );
1050
Paul Bakkerd98030e2009-05-02 15:13:40 +00001051 cur_entry = cur_entry->next;
1052 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
1053 }
1054 }
1055
1056 return( 0 );
1057}
1058
Paul Bakkerc70b9822013-04-07 22:00:46 +02001059static int x509_get_sig_alg( const x509_buf *sig_oid, md_type_t *md_alg,
1060 pk_type_t *pk_alg )
Paul Bakker27d66162010-03-17 06:56:01 +00001061{
Paul Bakkerc70b9822013-04-07 22:00:46 +02001062 int ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg );
Paul Bakker27d66162010-03-17 06:56:01 +00001063
Paul Bakkerc70b9822013-04-07 22:00:46 +02001064 if( ret != 0 )
1065 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG + ret );
Paul Bakker27d66162010-03-17 06:56:01 +00001066
Paul Bakkerc70b9822013-04-07 22:00:46 +02001067 return( 0 );
Paul Bakker27d66162010-03-17 06:56:01 +00001068}
1069
Paul Bakkerd98030e2009-05-02 15:13:40 +00001070/*
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001071 * Parse and fill a single X.509 certificate in DER format
Paul Bakker5121ce52009-01-03 21:22:43 +00001072 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02001073static int x509parse_crt_der_core( x509_cert *crt, const unsigned char *buf,
1074 size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001075{
Paul Bakker23986e52011-04-24 08:57:21 +00001076 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001077 size_t len;
Paul Bakkerb00ca422012-09-25 12:10:00 +00001078 unsigned char *p, *end, *crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001079
Paul Bakker320a4b52009-03-28 18:52:39 +00001080 /*
1081 * Check for valid input
1082 */
1083 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001084 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker320a4b52009-03-28 18:52:39 +00001085
Paul Bakker96743fc2011-02-12 14:30:57 +00001086 p = (unsigned char *) malloc( len = buflen );
1087
1088 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001089 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001090
1091 memcpy( p, buf, buflen );
1092
1093 buflen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001094
1095 crt->raw.p = p;
1096 crt->raw.len = len;
1097 end = p + len;
1098
1099 /*
1100 * Certificate ::= SEQUENCE {
1101 * tbsCertificate TBSCertificate,
1102 * signatureAlgorithm AlgorithmIdentifier,
1103 * signatureValue BIT STRING }
1104 */
1105 if( ( ret = asn1_get_tag( &p, end, &len,
1106 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1107 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001108 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001109 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001110 }
1111
Paul Bakkerb00ca422012-09-25 12:10:00 +00001112 if( len > (size_t) ( end - p ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001113 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001114 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001115 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001116 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001117 }
Paul Bakkerb00ca422012-09-25 12:10:00 +00001118 crt_end = p + len;
Paul Bakker42c65812013-06-24 19:21:59 +02001119
Paul Bakker5121ce52009-01-03 21:22:43 +00001120 /*
1121 * TBSCertificate ::= SEQUENCE {
1122 */
1123 crt->tbs.p = p;
1124
1125 if( ( ret = asn1_get_tag( &p, end, &len,
1126 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1127 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001128 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001129 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001130 }
1131
1132 end = p + len;
1133 crt->tbs.len = end - crt->tbs.p;
1134
1135 /*
1136 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1137 *
1138 * CertificateSerialNumber ::= INTEGER
1139 *
1140 * signature AlgorithmIdentifier
1141 */
1142 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1143 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1144 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
1145 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001146 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001147 return( ret );
1148 }
1149
1150 crt->version++;
1151
1152 if( crt->version > 3 )
1153 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001154 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001155 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001156 }
1157
Paul Bakkerc70b9822013-04-07 22:00:46 +02001158 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_md,
1159 &crt->sig_pk ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001160 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001161 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001162 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001163 }
1164
1165 /*
1166 * issuer Name
1167 */
1168 crt->issuer_raw.p = p;
1169
1170 if( ( ret = asn1_get_tag( &p, end, &len,
1171 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1172 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001173 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001174 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001175 }
1176
1177 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1178 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001179 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001180 return( ret );
1181 }
1182
1183 crt->issuer_raw.len = p - crt->issuer_raw.p;
1184
1185 /*
1186 * Validity ::= SEQUENCE {
1187 * notBefore Time,
1188 * notAfter Time }
1189 *
1190 */
1191 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1192 &crt->valid_to ) ) != 0 )
1193 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001194 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001195 return( ret );
1196 }
1197
1198 /*
1199 * subject Name
1200 */
1201 crt->subject_raw.p = p;
1202
1203 if( ( ret = asn1_get_tag( &p, end, &len,
1204 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1205 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001206 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001207 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001208 }
1209
Paul Bakkercefb3962012-06-27 11:51:09 +00001210 if( len && ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001211 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001212 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001213 return( ret );
1214 }
1215
1216 crt->subject_raw.len = p - crt->subject_raw.p;
1217
1218 /*
1219 * SubjectPublicKeyInfo ::= SEQUENCE
1220 * algorithm AlgorithmIdentifier,
1221 * subjectPublicKey BIT STRING }
1222 */
1223 if( ( ret = asn1_get_tag( &p, end, &len,
1224 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1225 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001226 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001227 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001228 }
1229
1230 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1231 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1232 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001233 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001234 return( ret );
1235 }
1236
1237 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1238 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001239 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001240 return( ret );
1241 }
1242
1243 crt->rsa.len = mpi_size( &crt->rsa.N );
1244
1245 /*
1246 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1247 * -- If present, version shall be v2 or v3
1248 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1249 * -- If present, version shall be v2 or v3
1250 * extensions [3] EXPLICIT Extensions OPTIONAL
1251 * -- If present, version shall be v3
1252 */
1253 if( crt->version == 2 || crt->version == 3 )
1254 {
1255 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1256 if( ret != 0 )
1257 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001258 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001259 return( ret );
1260 }
1261 }
1262
1263 if( crt->version == 2 || crt->version == 3 )
1264 {
1265 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1266 if( ret != 0 )
1267 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001268 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001269 return( ret );
1270 }
1271 }
1272
1273 if( crt->version == 3 )
1274 {
Paul Bakker74111d32011-01-15 16:57:55 +00001275 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001276 if( ret != 0 )
1277 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001278 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001279 return( ret );
1280 }
1281 }
1282
1283 if( p != end )
1284 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001285 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001286 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001287 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001288 }
1289
Paul Bakkerb00ca422012-09-25 12:10:00 +00001290 end = crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001291
1292 /*
1293 * signatureAlgorithm AlgorithmIdentifier,
1294 * signatureValue BIT STRING
1295 */
1296 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1297 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001298 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001299 return( ret );
1300 }
1301
Paul Bakker535e97d2012-08-23 10:49:55 +00001302 if( crt->sig_oid1.len != crt->sig_oid2.len ||
1303 memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001304 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001305 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001306 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001307 }
1308
1309 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1310 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001311 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001312 return( ret );
1313 }
1314
1315 if( p != end )
1316 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001317 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001318 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001319 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001320 }
1321
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001322 return( 0 );
1323}
1324
1325/*
Paul Bakker42c65812013-06-24 19:21:59 +02001326 * Parse one X.509 certificate in DER format from a buffer and add them to a
1327 * chained list
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001328 */
Paul Bakker42c65812013-06-24 19:21:59 +02001329int x509parse_crt_der( x509_cert *chain, const unsigned char *buf, size_t buflen )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001330{
Paul Bakker42c65812013-06-24 19:21:59 +02001331 int ret;
1332 x509_cert *crt = chain, *prev = NULL;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001333
1334 /*
1335 * Check for valid input
1336 */
1337 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001338 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001339
1340 while( crt->version != 0 && crt->next != NULL )
1341 {
1342 prev = crt;
1343 crt = crt->next;
1344 }
1345
1346 /*
1347 * Add new certificate on the end of the chain if needed.
1348 */
1349 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001350 {
1351 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1352
Paul Bakker7d06ad22009-05-02 15:53:56 +00001353 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001354 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker320a4b52009-03-28 18:52:39 +00001355
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001356 prev = crt;
Paul Bakker7d06ad22009-05-02 15:53:56 +00001357 crt = crt->next;
1358 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001359 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001360
Paul Bakker42c65812013-06-24 19:21:59 +02001361 if( ( ret = x509parse_crt_der_core( crt, buf, buflen ) ) != 0 )
1362 {
1363 if( prev )
1364 prev->next = NULL;
1365
1366 if( crt != chain )
1367 free( crt );
1368
1369 return( ret );
1370 }
1371
1372 return( 0 );
1373}
1374
1375/*
1376 * Parse one or more PEM certificates from a buffer and add them to the chained list
1377 */
1378int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
1379{
1380 int ret, success = 0, first_error = 0, total_failed = 0;
1381 int buf_format = X509_FORMAT_DER;
1382
1383 /*
1384 * Check for valid input
1385 */
1386 if( chain == NULL || buf == NULL )
1387 return( POLARSSL_ERR_X509_INVALID_INPUT );
1388
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001389 /*
1390 * Determine buffer content. Buffer contains either one DER certificate or
1391 * one or more PEM certificates.
1392 */
1393#if defined(POLARSSL_PEM_C)
Paul Bakker3c2122f2013-06-24 19:03:14 +02001394 if( strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001395 buf_format = X509_FORMAT_PEM;
1396#endif
1397
1398 if( buf_format == X509_FORMAT_DER )
Paul Bakker42c65812013-06-24 19:21:59 +02001399 return x509parse_crt_der( chain, buf, buflen );
1400
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001401#if defined(POLARSSL_PEM_C)
1402 if( buf_format == X509_FORMAT_PEM )
1403 {
1404 pem_context pem;
1405
1406 while( buflen > 0 )
1407 {
1408 size_t use_len;
1409 pem_init( &pem );
1410
1411 ret = pem_read_buffer( &pem,
1412 "-----BEGIN CERTIFICATE-----",
1413 "-----END CERTIFICATE-----",
1414 buf, NULL, 0, &use_len );
1415
1416 if( ret == 0 )
1417 {
1418 /*
1419 * Was PEM encoded
1420 */
1421 buflen -= use_len;
1422 buf += use_len;
1423 }
Paul Bakker5ed3b342013-06-24 19:05:46 +02001424 else if( ret == POLARSSL_ERR_PEM_BAD_INPUT_DATA )
1425 {
1426 return( ret );
1427 }
Paul Bakker00b28602013-06-24 13:02:41 +02001428 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001429 {
1430 pem_free( &pem );
1431
Paul Bakker5ed3b342013-06-24 19:05:46 +02001432 /*
1433 * PEM header and footer were found
1434 */
1435 buflen -= use_len;
1436 buf += use_len;
1437
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001438 if( first_error == 0 )
1439 first_error = ret;
1440
1441 continue;
1442 }
1443 else
1444 break;
1445
Paul Bakker42c65812013-06-24 19:21:59 +02001446 ret = x509parse_crt_der( chain, pem.buf, pem.buflen );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001447
1448 pem_free( &pem );
1449
1450 if( ret != 0 )
1451 {
1452 /*
Paul Bakker42c65812013-06-24 19:21:59 +02001453 * Quit parsing on a memory error
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001454 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001455 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001456 return( ret );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001457
1458 if( first_error == 0 )
1459 first_error = ret;
1460
Paul Bakker42c65812013-06-24 19:21:59 +02001461 total_failed++;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001462 continue;
1463 }
1464
1465 success = 1;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001466 }
1467 }
1468#endif
1469
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001470 if( success )
Paul Bakker69e095c2011-12-10 21:55:01 +00001471 return( total_failed );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001472 else if( first_error )
1473 return( first_error );
1474 else
1475 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001476}
1477
1478/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001479 * Parse one or more CRLs and add them to the chained list
1480 */
Paul Bakker23986e52011-04-24 08:57:21 +00001481int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001482{
Paul Bakker23986e52011-04-24 08:57:21 +00001483 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001484 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001485 unsigned char *p, *end;
1486 x509_crl *crl;
Paul Bakker96743fc2011-02-12 14:30:57 +00001487#if defined(POLARSSL_PEM_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00001488 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001489 pem_context pem;
1490#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001491
1492 crl = chain;
1493
1494 /*
1495 * Check for valid input
1496 */
1497 if( crl == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001498 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001499
1500 while( crl->version != 0 && crl->next != NULL )
1501 crl = crl->next;
1502
1503 /*
1504 * Add new CRL on the end of the chain if needed.
1505 */
1506 if ( crl->version != 0 && crl->next == NULL)
1507 {
1508 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1509
Paul Bakker7d06ad22009-05-02 15:53:56 +00001510 if( crl->next == NULL )
1511 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001512 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001513 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001514 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001515
Paul Bakker7d06ad22009-05-02 15:53:56 +00001516 crl = crl->next;
1517 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001518 }
1519
Paul Bakker96743fc2011-02-12 14:30:57 +00001520#if defined(POLARSSL_PEM_C)
1521 pem_init( &pem );
1522 ret = pem_read_buffer( &pem,
1523 "-----BEGIN X509 CRL-----",
1524 "-----END X509 CRL-----",
1525 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001526
Paul Bakker96743fc2011-02-12 14:30:57 +00001527 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001528 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001529 /*
1530 * Was PEM encoded
1531 */
1532 buflen -= use_len;
1533 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001534
1535 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001536 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001537 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001538 p = pem.buf;
1539 pem.buf = NULL;
1540 len = pem.buflen;
1541 pem_free( &pem );
1542 }
Paul Bakker00b28602013-06-24 13:02:41 +02001543 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker96743fc2011-02-12 14:30:57 +00001544 {
1545 pem_free( &pem );
1546 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001547 }
1548 else
1549 {
1550 /*
1551 * nope, copy the raw DER data
1552 */
1553 p = (unsigned char *) malloc( len = buflen );
1554
1555 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001556 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001557
1558 memcpy( p, buf, buflen );
1559
1560 buflen = 0;
1561 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001562#else
1563 p = (unsigned char *) malloc( len = buflen );
1564
1565 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001566 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001567
1568 memcpy( p, buf, buflen );
1569
1570 buflen = 0;
1571#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001572
1573 crl->raw.p = p;
1574 crl->raw.len = len;
1575 end = p + len;
1576
1577 /*
1578 * CertificateList ::= SEQUENCE {
1579 * tbsCertList TBSCertList,
1580 * signatureAlgorithm AlgorithmIdentifier,
1581 * signatureValue BIT STRING }
1582 */
1583 if( ( ret = asn1_get_tag( &p, end, &len,
1584 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1585 {
1586 x509_crl_free( crl );
1587 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1588 }
1589
Paul Bakker23986e52011-04-24 08:57:21 +00001590 if( len != (size_t) ( end - p ) )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001591 {
1592 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001593 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001594 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1595 }
1596
1597 /*
1598 * TBSCertList ::= SEQUENCE {
1599 */
1600 crl->tbs.p = p;
1601
1602 if( ( ret = asn1_get_tag( &p, end, &len,
1603 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1604 {
1605 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001606 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001607 }
1608
1609 end = p + len;
1610 crl->tbs.len = end - crl->tbs.p;
1611
1612 /*
1613 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1614 * -- if present, MUST be v2
1615 *
1616 * signature AlgorithmIdentifier
1617 */
Paul Bakker3329d1f2011-10-12 09:55:01 +00001618 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
Paul Bakkerd98030e2009-05-02 15:13:40 +00001619 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1620 {
1621 x509_crl_free( crl );
1622 return( ret );
1623 }
1624
1625 crl->version++;
1626
1627 if( crl->version > 2 )
1628 {
1629 x509_crl_free( crl );
1630 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1631 }
1632
Paul Bakkerc70b9822013-04-07 22:00:46 +02001633 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_md,
1634 &crl->sig_pk ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001635 {
1636 x509_crl_free( crl );
1637 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1638 }
1639
1640 /*
1641 * issuer Name
1642 */
1643 crl->issuer_raw.p = p;
1644
1645 if( ( ret = asn1_get_tag( &p, end, &len,
1646 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1647 {
1648 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001649 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001650 }
1651
1652 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1653 {
1654 x509_crl_free( crl );
1655 return( ret );
1656 }
1657
1658 crl->issuer_raw.len = p - crl->issuer_raw.p;
1659
1660 /*
1661 * thisUpdate Time
1662 * nextUpdate Time OPTIONAL
1663 */
Paul Bakker91200182010-02-18 21:26:15 +00001664 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001665 {
1666 x509_crl_free( crl );
1667 return( ret );
1668 }
1669
Paul Bakker91200182010-02-18 21:26:15 +00001670 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001671 {
Paul Bakker9d781402011-05-09 16:17:09 +00001672 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001673 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker9d781402011-05-09 16:17:09 +00001674 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001675 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001676 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001677 x509_crl_free( crl );
1678 return( ret );
1679 }
1680 }
1681
1682 /*
1683 * revokedCertificates SEQUENCE OF SEQUENCE {
1684 * userCertificate CertificateSerialNumber,
1685 * revocationDate Time,
1686 * crlEntryExtensions Extensions OPTIONAL
1687 * -- if present, MUST be v2
1688 * } OPTIONAL
1689 */
1690 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1691 {
1692 x509_crl_free( crl );
1693 return( ret );
1694 }
1695
1696 /*
1697 * crlExtensions EXPLICIT Extensions OPTIONAL
1698 * -- if present, MUST be v2
1699 */
1700 if( crl->version == 2 )
1701 {
1702 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1703
1704 if( ret != 0 )
1705 {
1706 x509_crl_free( crl );
1707 return( ret );
1708 }
1709 }
1710
1711 if( p != end )
1712 {
1713 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001714 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001715 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1716 }
1717
1718 end = crl->raw.p + crl->raw.len;
1719
1720 /*
1721 * signatureAlgorithm AlgorithmIdentifier,
1722 * signatureValue BIT STRING
1723 */
1724 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1725 {
1726 x509_crl_free( crl );
1727 return( ret );
1728 }
1729
Paul Bakker535e97d2012-08-23 10:49:55 +00001730 if( crl->sig_oid1.len != crl->sig_oid2.len ||
1731 memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001732 {
1733 x509_crl_free( crl );
1734 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1735 }
1736
1737 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1738 {
1739 x509_crl_free( crl );
1740 return( ret );
1741 }
1742
1743 if( p != end )
1744 {
1745 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001746 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001747 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1748 }
1749
1750 if( buflen > 0 )
1751 {
1752 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1753
Paul Bakker7d06ad22009-05-02 15:53:56 +00001754 if( crl->next == NULL )
1755 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001756 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001757 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001758 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001759
Paul Bakker7d06ad22009-05-02 15:53:56 +00001760 crl = crl->next;
1761 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001762
1763 return( x509parse_crl( crl, buf, buflen ) );
1764 }
1765
1766 return( 0 );
1767}
1768
Paul Bakker335db3f2011-04-25 15:28:35 +00001769#if defined(POLARSSL_FS_IO)
Paul Bakkerd98030e2009-05-02 15:13:40 +00001770/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001771 * Load all data from a file into a given buffer.
1772 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02001773static int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001774{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001775 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001776
Paul Bakkerd98030e2009-05-02 15:13:40 +00001777 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001778 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001779
Paul Bakkerd98030e2009-05-02 15:13:40 +00001780 fseek( f, 0, SEEK_END );
1781 *n = (size_t) ftell( f );
1782 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001783
Paul Bakkerd98030e2009-05-02 15:13:40 +00001784 if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
Paul Bakkerf6a19bd2013-05-14 13:26:51 +02001785 {
1786 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +00001787 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerf6a19bd2013-05-14 13:26:51 +02001788 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001789
Paul Bakkerd98030e2009-05-02 15:13:40 +00001790 if( fread( *buf, 1, *n, f ) != *n )
1791 {
1792 fclose( f );
1793 free( *buf );
Paul Bakker69e095c2011-12-10 21:55:01 +00001794 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001795 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001796
Paul Bakkerd98030e2009-05-02 15:13:40 +00001797 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001798
Paul Bakkerd98030e2009-05-02 15:13:40 +00001799 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001800
Paul Bakkerd98030e2009-05-02 15:13:40 +00001801 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001802}
1803
1804/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001805 * Load one or more certificates and add them to the chained list
1806 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001807int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001808{
1809 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001810 size_t n;
1811 unsigned char *buf;
1812
Paul Bakker69e095c2011-12-10 21:55:01 +00001813 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1814 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001815
Paul Bakker69e095c2011-12-10 21:55:01 +00001816 ret = x509parse_crt( chain, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001817
1818 memset( buf, 0, n + 1 );
1819 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001820
1821 return( ret );
1822}
1823
Paul Bakker8d914582012-06-04 12:46:42 +00001824int x509parse_crtpath( x509_cert *chain, const char *path )
1825{
1826 int ret = 0;
1827#if defined(_WIN32)
Paul Bakker3338b792012-10-01 21:13:10 +00001828 int w_ret;
1829 WCHAR szDir[MAX_PATH];
1830 char filename[MAX_PATH];
1831 char *p;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001832 int len = strlen( path );
Paul Bakker3338b792012-10-01 21:13:10 +00001833
Paul Bakker97872ac2012-11-02 12:53:26 +00001834 WIN32_FIND_DATAW file_data;
Paul Bakker8d914582012-06-04 12:46:42 +00001835 HANDLE hFind;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001836
1837 if( len > MAX_PATH - 3 )
1838 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker8d914582012-06-04 12:46:42 +00001839
Paul Bakker3338b792012-10-01 21:13:10 +00001840 memset( szDir, 0, sizeof(szDir) );
1841 memset( filename, 0, MAX_PATH );
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001842 memcpy( filename, path, len );
1843 filename[len++] = '\\';
1844 p = filename + len;
1845 filename[len++] = '*';
Paul Bakker3338b792012-10-01 21:13:10 +00001846
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001847 w_ret = MultiByteToWideChar( CP_ACP, 0, path, len, szDir, MAX_PATH - 3 );
Paul Bakker8d914582012-06-04 12:46:42 +00001848
Paul Bakker97872ac2012-11-02 12:53:26 +00001849 hFind = FindFirstFileW( szDir, &file_data );
Paul Bakker8d914582012-06-04 12:46:42 +00001850 if (hFind == INVALID_HANDLE_VALUE)
1851 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1852
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001853 len = MAX_PATH - len;
Paul Bakker8d914582012-06-04 12:46:42 +00001854 do
1855 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001856 memset( p, 0, len );
Paul Bakker3338b792012-10-01 21:13:10 +00001857
Paul Bakkere4791f32012-06-04 21:29:15 +00001858 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
Paul Bakker8d914582012-06-04 12:46:42 +00001859 continue;
1860
Paul Bakker3338b792012-10-01 21:13:10 +00001861 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
1862 lstrlenW(file_data.cFileName),
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001863 p, len - 1,
1864 NULL, NULL );
Paul Bakker8d914582012-06-04 12:46:42 +00001865
Paul Bakker3338b792012-10-01 21:13:10 +00001866 w_ret = x509parse_crtfile( chain, filename );
1867 if( w_ret < 0 )
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001868 ret++;
1869 else
1870 ret += w_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001871 }
Paul Bakker97872ac2012-11-02 12:53:26 +00001872 while( FindNextFileW( hFind, &file_data ) != 0 );
Paul Bakker8d914582012-06-04 12:46:42 +00001873
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001874 if (GetLastError() != ERROR_NO_MORE_FILES)
1875 ret = POLARSSL_ERR_X509_FILE_IO_ERROR;
Paul Bakker8d914582012-06-04 12:46:42 +00001876
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001877cleanup:
Paul Bakker8d914582012-06-04 12:46:42 +00001878 FindClose( hFind );
1879#else
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001880 int t_ret, i;
1881 struct stat sb;
1882 struct dirent entry, *result = NULL;
Paul Bakker8d914582012-06-04 12:46:42 +00001883 char entry_name[255];
1884 DIR *dir = opendir( path );
1885
1886 if( dir == NULL)
1887 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1888
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001889 while( ( t_ret = readdir_r( dir, &entry, &result ) ) == 0 )
Paul Bakker8d914582012-06-04 12:46:42 +00001890 {
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001891 if( result == NULL )
1892 break;
1893
1894 snprintf( entry_name, sizeof(entry_name), "%s/%s", path, entry.d_name );
1895
1896 i = stat( entry_name, &sb );
1897
1898 if( i == -1 )
1899 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1900
1901 if( !S_ISREG( sb.st_mode ) )
Paul Bakker8d914582012-06-04 12:46:42 +00001902 continue;
1903
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001904 // Ignore parse errors
1905 //
Paul Bakker8d914582012-06-04 12:46:42 +00001906 t_ret = x509parse_crtfile( chain, entry_name );
1907 if( t_ret < 0 )
Paul Bakker2c8cdd22013-06-24 19:22:42 +02001908 ret++;
1909 else
1910 ret += t_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001911 }
1912 closedir( dir );
1913#endif
1914
1915 return( ret );
1916}
1917
Paul Bakkerd98030e2009-05-02 15:13:40 +00001918/*
1919 * Load one or more CRLs and add them to the chained list
1920 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001921int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001922{
1923 int ret;
1924 size_t n;
1925 unsigned char *buf;
1926
Paul Bakker69e095c2011-12-10 21:55:01 +00001927 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1928 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001929
Paul Bakker27fdf462011-06-09 13:55:13 +00001930 ret = x509parse_crl( chain, buf, n );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001931
1932 memset( buf, 0, n + 1 );
1933 free( buf );
1934
1935 return( ret );
1936}
1937
Paul Bakker5121ce52009-01-03 21:22:43 +00001938/*
Paul Bakker335db3f2011-04-25 15:28:35 +00001939 * Load and parse a private RSA key
1940 */
1941int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
1942{
1943 int ret;
1944 size_t n;
1945 unsigned char *buf;
1946
Paul Bakker69e095c2011-12-10 21:55:01 +00001947 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1948 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00001949
1950 if( pwd == NULL )
Paul Bakker27fdf462011-06-09 13:55:13 +00001951 ret = x509parse_key( rsa, buf, n, NULL, 0 );
Paul Bakker335db3f2011-04-25 15:28:35 +00001952 else
Paul Bakker27fdf462011-06-09 13:55:13 +00001953 ret = x509parse_key( rsa, buf, n,
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02001954 (const unsigned char *) pwd, strlen( pwd ) );
Paul Bakker335db3f2011-04-25 15:28:35 +00001955
1956 memset( buf, 0, n + 1 );
1957 free( buf );
1958
1959 return( ret );
1960}
1961
1962/*
1963 * Load and parse a public RSA key
1964 */
1965int x509parse_public_keyfile( rsa_context *rsa, const char *path )
1966{
1967 int ret;
1968 size_t n;
1969 unsigned char *buf;
1970
Paul Bakker69e095c2011-12-10 21:55:01 +00001971 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1972 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00001973
Paul Bakker27fdf462011-06-09 13:55:13 +00001974 ret = x509parse_public_key( rsa, buf, n );
Paul Bakker335db3f2011-04-25 15:28:35 +00001975
1976 memset( buf, 0, n + 1 );
1977 free( buf );
1978
1979 return( ret );
1980}
1981#endif /* POLARSSL_FS_IO */
1982
1983/*
Paul Bakkere2f50402013-06-24 19:00:59 +02001984 * Parse a PKCS#1 encoded private RSA key
Paul Bakker5121ce52009-01-03 21:22:43 +00001985 */
Paul Bakkere2f50402013-06-24 19:00:59 +02001986static int x509parse_key_pkcs1_der( rsa_context *rsa,
1987 const unsigned char *key,
1988 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001989{
Paul Bakker23986e52011-04-24 08:57:21 +00001990 int ret;
1991 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00001992 unsigned char *p, *end;
Paul Bakkered56b222011-07-13 11:26:43 +00001993
Paul Bakker96743fc2011-02-12 14:30:57 +00001994 p = (unsigned char *) key;
Paul Bakker96743fc2011-02-12 14:30:57 +00001995 end = p + keylen;
1996
Paul Bakker5121ce52009-01-03 21:22:43 +00001997 /*
Paul Bakkere2f50402013-06-24 19:00:59 +02001998 * This function parses the RSAPrivateKey (PKCS#1)
Paul Bakkered56b222011-07-13 11:26:43 +00001999 *
Paul Bakker5121ce52009-01-03 21:22:43 +00002000 * RSAPrivateKey ::= SEQUENCE {
2001 * version Version,
2002 * modulus INTEGER, -- n
2003 * publicExponent INTEGER, -- e
2004 * privateExponent INTEGER, -- d
2005 * prime1 INTEGER, -- p
2006 * prime2 INTEGER, -- q
2007 * exponent1 INTEGER, -- d mod (p-1)
2008 * exponent2 INTEGER, -- d mod (q-1)
2009 * coefficient INTEGER, -- (inverse of q) mod p
2010 * otherPrimeInfos OtherPrimeInfos OPTIONAL
2011 * }
2012 */
2013 if( ( ret = asn1_get_tag( &p, end, &len,
2014 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2015 {
Paul Bakker9d781402011-05-09 16:17:09 +00002016 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002017 }
2018
2019 end = p + len;
2020
2021 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2022 {
Paul Bakker9d781402011-05-09 16:17:09 +00002023 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002024 }
2025
2026 if( rsa->ver != 0 )
2027 {
Paul Bakker9d781402011-05-09 16:17:09 +00002028 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002029 }
2030
2031 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
2032 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
2033 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
2034 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
2035 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
2036 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
2037 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
2038 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
2039 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002040 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002041 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002042 }
2043
2044 rsa->len = mpi_size( &rsa->N );
2045
2046 if( p != end )
2047 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002048 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002049 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00002050 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002051 }
2052
2053 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2054 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002055 rsa_free( rsa );
2056 return( ret );
2057 }
2058
Paul Bakkere2f50402013-06-24 19:00:59 +02002059 return( 0 );
2060}
2061
2062/*
2063 * Parse an unencrypted PKCS#8 encoded private RSA key
2064 */
2065static int x509parse_key_pkcs8_unencrypted_der(
2066 rsa_context *rsa,
2067 const unsigned char *key,
2068 size_t keylen )
2069{
2070 int ret;
2071 size_t len;
2072 unsigned char *p, *end;
2073 x509_buf pk_alg_oid;
2074 pk_type_t pk_alg = POLARSSL_PK_NONE;
2075
2076 p = (unsigned char *) key;
2077 end = p + keylen;
2078
2079 /*
2080 * This function parses the PrivatKeyInfo object (PKCS#8)
2081 *
2082 * PrivateKeyInfo ::= SEQUENCE {
2083 * version Version,
2084 * algorithm AlgorithmIdentifier,
2085 * PrivateKey BIT STRING
2086 * }
2087 *
2088 * AlgorithmIdentifier ::= SEQUENCE {
2089 * algorithm OBJECT IDENTIFIER,
2090 * parameters ANY DEFINED BY algorithm OPTIONAL
2091 * }
2092 *
2093 * The PrivateKey BIT STRING is a PKCS#1 RSAPrivateKey
2094 */
2095 if( ( ret = asn1_get_tag( &p, end, &len,
2096 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2097 {
2098 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2099 }
2100
2101 end = p + len;
2102
2103 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2104 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2105
2106 if( rsa->ver != 0 )
2107 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2108
Paul Bakkerf8d018a2013-06-29 12:16:17 +02002109 if( ( ret = asn1_get_alg_null( &p, end, &pk_alg_oid ) ) != 0 )
Paul Bakkere2f50402013-06-24 19:00:59 +02002110 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2111
2112 /*
2113 * only RSA keys handled at this time
2114 */
2115 if( oid_get_pk_alg( &pk_alg_oid, &pk_alg ) != 0 )
2116 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
2117
2118 /*
2119 * Get the OCTET STRING and parse the PKCS#1 format inside
2120 */
2121 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2122 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2123
2124 if( ( end - p ) < 1 )
2125 {
2126 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
2127 POLARSSL_ERR_ASN1_OUT_OF_DATA );
2128 }
2129
2130 end = p + len;
2131
2132 if( ( ret = x509parse_key_pkcs1_der( rsa, p, end - p ) ) != 0 )
2133 return( ret );
2134
2135 return( 0 );
2136}
2137
2138/*
Paul Bakkerbda7cb72013-06-24 19:34:25 +02002139 * Parse an encrypted PKCS#8 encoded private RSA key
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002140 */
2141static int x509parse_key_pkcs8_encrypted_der(
2142 rsa_context *rsa,
2143 const unsigned char *key,
2144 size_t keylen,
2145 const unsigned char *pwd,
2146 size_t pwdlen )
2147{
2148 int ret;
2149 size_t len;
Paul Bakkerf8d018a2013-06-29 12:16:17 +02002150 unsigned char *p, *end;
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002151 x509_buf pbe_alg_oid, pbe_params;
2152 unsigned char buf[2048];
Paul Bakker7749a222013-06-28 17:28:20 +02002153#if defined(POLARSSL_PKCS12_C)
2154 cipher_type_t cipher_alg;
2155 md_type_t md_alg;
2156#endif
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002157
2158 memset(buf, 0, 2048);
2159
2160 p = (unsigned char *) key;
2161 end = p + keylen;
2162
Paul Bakker28144de2013-06-24 19:28:55 +02002163 if( pwdlen == 0 )
2164 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
2165
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002166 /*
2167 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
2168 *
2169 * EncryptedPrivateKeyInfo ::= SEQUENCE {
2170 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
2171 * encryptedData EncryptedData
2172 * }
2173 *
2174 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
2175 *
2176 * EncryptedData ::= OCTET STRING
2177 *
2178 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
2179 */
2180 if( ( ret = asn1_get_tag( &p, end, &len,
2181 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2182 {
2183 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2184 }
2185
2186 end = p + len;
2187
Paul Bakkerf8d018a2013-06-29 12:16:17 +02002188 if( ( ret = asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002189 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002190
2191 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2192 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2193
2194 // buf has been sized to 2048 bytes
2195 if( len > 2048 )
2196 return( POLARSSL_ERR_X509_INVALID_INPUT );
2197
2198 /*
2199 * Decrypt EncryptedData with appropriate PDE
2200 */
Paul Bakker38b50d72013-06-24 19:33:27 +02002201#if defined(POLARSSL_PKCS12_C)
Paul Bakker7749a222013-06-28 17:28:20 +02002202 if( oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002203 {
Paul Bakker38b50d72013-06-24 19:33:27 +02002204 if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
Paul Bakker7749a222013-06-28 17:28:20 +02002205 cipher_alg, md_alg,
Paul Bakker38b50d72013-06-24 19:33:27 +02002206 pwd, pwdlen, p, len, buf ) ) != 0 )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002207 {
Paul Bakker38b50d72013-06-24 19:33:27 +02002208 if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH )
2209 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2210
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002211 return( ret );
2212 }
2213 }
2214 else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) )
2215 {
2216 if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params,
2217 PKCS12_PBE_DECRYPT,
2218 pwd, pwdlen,
2219 p, len, buf ) ) != 0 )
2220 {
2221 return( ret );
2222 }
Paul Bakker38b50d72013-06-24 19:33:27 +02002223
2224 // Best guess for password mismatch when using RC4. If first tag is
2225 // not ASN1_CONSTRUCTED | ASN1_SEQUENCE
2226 //
2227 if( *buf != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
2228 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002229 }
Paul Bakker38b50d72013-06-24 19:33:27 +02002230 else
2231#endif /* POLARSSL_PKCS12_C */
Paul Bakker28144de2013-06-24 19:28:55 +02002232#if defined(POLARSSL_PKCS5_C)
Paul Bakker38b50d72013-06-24 19:33:27 +02002233 if( OID_CMP( OID_PKCS5_PBES2, &pbe_alg_oid ) )
Paul Bakker28144de2013-06-24 19:28:55 +02002234 {
2235 if( ( ret = pkcs5_pbes2( &pbe_params, PKCS5_DECRYPT, pwd, pwdlen,
2236 p, len, buf ) ) != 0 )
2237 {
2238 if( ret == POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH )
2239 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2240
2241 return( ret );
2242 }
2243 }
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002244 else
Paul Bakker38b50d72013-06-24 19:33:27 +02002245#endif /* POLARSSL_PKCS5_C */
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002246 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
2247
2248 return x509parse_key_pkcs8_unencrypted_der( rsa, buf, len );
2249}
2250
2251/*
Paul Bakkere2f50402013-06-24 19:00:59 +02002252 * Parse a private RSA key
2253 */
2254int x509parse_key( rsa_context *rsa, const unsigned char *key, size_t keylen,
2255 const unsigned char *pwd, size_t pwdlen )
2256{
2257 int ret;
2258
Paul Bakker96743fc2011-02-12 14:30:57 +00002259#if defined(POLARSSL_PEM_C)
Paul Bakkere2f50402013-06-24 19:00:59 +02002260 size_t len;
2261 pem_context pem;
2262
2263 pem_init( &pem );
2264 ret = pem_read_buffer( &pem,
2265 "-----BEGIN RSA PRIVATE KEY-----",
2266 "-----END RSA PRIVATE KEY-----",
2267 key, pwd, pwdlen, &len );
2268 if( ret == 0 )
2269 {
2270 if( ( ret = x509parse_key_pkcs1_der( rsa, pem.buf, pem.buflen ) ) != 0 )
2271 {
2272 rsa_free( rsa );
2273 }
2274
2275 pem_free( &pem );
2276 return( ret );
2277 }
Paul Bakkera4232a72013-06-24 19:32:25 +02002278 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
2279 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2280 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
2281 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
Paul Bakkere2f50402013-06-24 19:00:59 +02002282 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkere2f50402013-06-24 19:00:59 +02002283 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002284
2285 ret = pem_read_buffer( &pem,
2286 "-----BEGIN PRIVATE KEY-----",
2287 "-----END PRIVATE KEY-----",
2288 key, NULL, 0, &len );
2289 if( ret == 0 )
2290 {
2291 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa,
2292 pem.buf, pem.buflen ) ) != 0 )
2293 {
2294 rsa_free( rsa );
2295 }
2296
2297 pem_free( &pem );
2298 return( ret );
2299 }
2300 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkere2f50402013-06-24 19:00:59 +02002301 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002302
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002303 ret = pem_read_buffer( &pem,
2304 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
2305 "-----END ENCRYPTED PRIVATE KEY-----",
2306 key, NULL, 0, &len );
2307 if( ret == 0 )
2308 {
2309 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa,
2310 pem.buf, pem.buflen,
2311 pwd, pwdlen ) ) != 0 )
2312 {
2313 rsa_free( rsa );
2314 }
2315
2316 pem_free( &pem );
2317 return( ret );
2318 }
2319 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002320 return( ret );
Paul Bakkere2f50402013-06-24 19:00:59 +02002321#else
2322 ((void) pwd);
2323 ((void) pwdlen);
2324#endif /* POLARSSL_PEM_C */
2325
2326 // At this point we only know it's not a PEM formatted key. Could be any
2327 // of the known DER encoded private key formats
2328 //
2329 // We try the different DER format parsers to see if one passes without
2330 // error
2331 //
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002332 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa, key, keylen,
2333 pwd, pwdlen ) ) == 0 )
Paul Bakkere2f50402013-06-24 19:00:59 +02002334 {
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002335 return( 0 );
Paul Bakkere2f50402013-06-24 19:00:59 +02002336 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002337
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002338 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002339
2340 if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH )
2341 {
2342 return( ret );
2343 }
2344
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002345 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa, key, keylen ) ) == 0 )
2346 return( 0 );
2347
2348 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002349
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002350 if( ( ret = x509parse_key_pkcs1_der( rsa, key, keylen ) ) == 0 )
2351 return( 0 );
2352
2353 rsa_free( rsa );
Paul Bakker28144de2013-06-24 19:28:55 +02002354
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02002355 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00002356}
2357
2358/*
Paul Bakker53019ae2011-03-25 13:58:48 +00002359 * Parse a public RSA key
2360 */
Paul Bakker23986e52011-04-24 08:57:21 +00002361int x509parse_public_key( rsa_context *rsa, const unsigned char *key, size_t keylen )
Paul Bakker53019ae2011-03-25 13:58:48 +00002362{
Paul Bakker23986e52011-04-24 08:57:21 +00002363 int ret;
2364 size_t len;
Paul Bakker53019ae2011-03-25 13:58:48 +00002365 unsigned char *p, *end;
2366 x509_buf alg_oid;
2367#if defined(POLARSSL_PEM_C)
2368 pem_context pem;
2369
2370 pem_init( &pem );
2371 ret = pem_read_buffer( &pem,
2372 "-----BEGIN PUBLIC KEY-----",
2373 "-----END PUBLIC KEY-----",
2374 key, NULL, 0, &len );
2375
2376 if( ret == 0 )
2377 {
2378 /*
2379 * Was PEM encoded
2380 */
2381 keylen = pem.buflen;
2382 }
Paul Bakker00b28602013-06-24 13:02:41 +02002383 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker53019ae2011-03-25 13:58:48 +00002384 {
2385 pem_free( &pem );
2386 return( ret );
2387 }
2388
2389 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2390#else
2391 p = (unsigned char *) key;
2392#endif
2393 end = p + keylen;
2394
2395 /*
2396 * PublicKeyInfo ::= SEQUENCE {
2397 * algorithm AlgorithmIdentifier,
2398 * PublicKey BIT STRING
2399 * }
2400 *
2401 * AlgorithmIdentifier ::= SEQUENCE {
2402 * algorithm OBJECT IDENTIFIER,
2403 * parameters ANY DEFINED BY algorithm OPTIONAL
2404 * }
2405 *
2406 * RSAPublicKey ::= SEQUENCE {
2407 * modulus INTEGER, -- n
2408 * publicExponent INTEGER -- e
2409 * }
2410 */
2411
2412 if( ( ret = asn1_get_tag( &p, end, &len,
2413 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2414 {
2415#if defined(POLARSSL_PEM_C)
2416 pem_free( &pem );
2417#endif
2418 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002419 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002420 }
2421
2422 if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
2423 {
2424#if defined(POLARSSL_PEM_C)
2425 pem_free( &pem );
2426#endif
2427 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002428 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002429 }
2430
2431 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
2432 {
2433#if defined(POLARSSL_PEM_C)
2434 pem_free( &pem );
2435#endif
2436 rsa_free( rsa );
2437 return( ret );
2438 }
2439
2440 rsa->len = mpi_size( &rsa->N );
2441
2442#if defined(POLARSSL_PEM_C)
2443 pem_free( &pem );
2444#endif
2445
2446 return( 0 );
2447}
2448
Paul Bakkereaa89f82011-04-04 21:36:15 +00002449#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00002450/*
Paul Bakker1b57b062011-01-06 15:48:19 +00002451 * Parse DHM parameters
2452 */
Paul Bakker23986e52011-04-24 08:57:21 +00002453int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
Paul Bakker1b57b062011-01-06 15:48:19 +00002454{
Paul Bakker23986e52011-04-24 08:57:21 +00002455 int ret;
2456 size_t len;
Paul Bakker1b57b062011-01-06 15:48:19 +00002457 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00002458#if defined(POLARSSL_PEM_C)
2459 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00002460
Paul Bakker96743fc2011-02-12 14:30:57 +00002461 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00002462
Paul Bakker96743fc2011-02-12 14:30:57 +00002463 ret = pem_read_buffer( &pem,
2464 "-----BEGIN DH PARAMETERS-----",
2465 "-----END DH PARAMETERS-----",
2466 dhmin, NULL, 0, &dhminlen );
2467
2468 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00002469 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002470 /*
2471 * Was PEM encoded
2472 */
2473 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00002474 }
Paul Bakker00b28602013-06-24 13:02:41 +02002475 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00002476 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002477 pem_free( &pem );
2478 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002479 }
2480
Paul Bakker96743fc2011-02-12 14:30:57 +00002481 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
2482#else
2483 p = (unsigned char *) dhmin;
2484#endif
2485 end = p + dhminlen;
2486
Paul Bakker1b57b062011-01-06 15:48:19 +00002487 memset( dhm, 0, sizeof( dhm_context ) );
2488
Paul Bakker1b57b062011-01-06 15:48:19 +00002489 /*
2490 * DHParams ::= SEQUENCE {
2491 * prime INTEGER, -- P
2492 * generator INTEGER, -- g
2493 * }
2494 */
2495 if( ( ret = asn1_get_tag( &p, end, &len,
2496 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2497 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002498#if defined(POLARSSL_PEM_C)
2499 pem_free( &pem );
2500#endif
Paul Bakker9d781402011-05-09 16:17:09 +00002501 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002502 }
2503
2504 end = p + len;
2505
2506 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
2507 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
2508 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002509#if defined(POLARSSL_PEM_C)
2510 pem_free( &pem );
2511#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002512 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002513 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002514 }
2515
2516 if( p != end )
2517 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002518#if defined(POLARSSL_PEM_C)
2519 pem_free( &pem );
2520#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002521 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002522 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker1b57b062011-01-06 15:48:19 +00002523 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
2524 }
2525
Paul Bakker96743fc2011-02-12 14:30:57 +00002526#if defined(POLARSSL_PEM_C)
2527 pem_free( &pem );
2528#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002529
2530 return( 0 );
2531}
2532
Paul Bakker335db3f2011-04-25 15:28:35 +00002533#if defined(POLARSSL_FS_IO)
Paul Bakker1b57b062011-01-06 15:48:19 +00002534/*
2535 * Load and parse a private RSA key
2536 */
2537int x509parse_dhmfile( dhm_context *dhm, const char *path )
2538{
2539 int ret;
2540 size_t n;
2541 unsigned char *buf;
2542
Paul Bakker69e095c2011-12-10 21:55:01 +00002543 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
2544 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002545
Paul Bakker27fdf462011-06-09 13:55:13 +00002546 ret = x509parse_dhm( dhm, buf, n );
Paul Bakker1b57b062011-01-06 15:48:19 +00002547
2548 memset( buf, 0, n + 1 );
2549 free( buf );
2550
2551 return( ret );
2552}
Paul Bakker335db3f2011-04-25 15:28:35 +00002553#endif /* POLARSSL_FS_IO */
Paul Bakkereaa89f82011-04-04 21:36:15 +00002554#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00002555
Paul Bakker5121ce52009-01-03 21:22:43 +00002556#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002557#include <stdarg.h>
2558
2559#if !defined vsnprintf
2560#define vsnprintf _vsnprintf
2561#endif // vsnprintf
2562
2563/*
2564 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2565 * Result value is not size of buffer needed, but -1 if no fit is possible.
2566 *
2567 * This fuction tries to 'fix' this by at least suggesting enlarging the
2568 * size by 20.
2569 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02002570static int compat_snprintf(char *str, size_t size, const char *format, ...)
Paul Bakkerd98030e2009-05-02 15:13:40 +00002571{
2572 va_list ap;
2573 int res = -1;
2574
2575 va_start( ap, format );
2576
2577 res = vsnprintf( str, size, format, ap );
2578
2579 va_end( ap );
2580
2581 // No quick fix possible
2582 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00002583 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002584
2585 return res;
2586}
2587
2588#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002589#endif
2590
Paul Bakkerd98030e2009-05-02 15:13:40 +00002591#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2592
2593#define SAFE_SNPRINTF() \
2594{ \
2595 if( ret == -1 ) \
2596 return( -1 ); \
2597 \
Paul Bakker23986e52011-04-24 08:57:21 +00002598 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002599 p[n - 1] = '\0'; \
2600 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2601 } \
2602 \
Paul Bakker23986e52011-04-24 08:57:21 +00002603 n -= (unsigned int) ret; \
2604 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002605}
2606
Paul Bakker5121ce52009-01-03 21:22:43 +00002607/*
2608 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002609 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002610 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002611int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002612{
Paul Bakker23986e52011-04-24 08:57:21 +00002613 int ret;
2614 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002615 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002616 const x509_name *name;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002617 const char *short_name = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00002618 char s[128], *p;
2619
2620 memset( s, 0, sizeof( s ) );
2621
2622 name = dn;
2623 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002624 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002625
2626 while( name != NULL )
2627 {
Paul Bakkercefb3962012-06-27 11:51:09 +00002628 if( !name->oid.p )
2629 {
2630 name = name->next;
2631 continue;
2632 }
2633
Paul Bakker74111d32011-01-15 16:57:55 +00002634 if( name != dn )
2635 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002636 ret = snprintf( p, n, ", " );
2637 SAFE_SNPRINTF();
2638 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002639
Paul Bakkerc70b9822013-04-07 22:00:46 +02002640 ret = oid_get_attr_short_name( &name->oid, &short_name );
Paul Bakker5121ce52009-01-03 21:22:43 +00002641
Paul Bakkerc70b9822013-04-07 22:00:46 +02002642 if( ret == 0 )
2643 ret = snprintf( p, n, "%s=", short_name );
Paul Bakker5121ce52009-01-03 21:22:43 +00002644 else
Paul Bakkerd98030e2009-05-02 15:13:40 +00002645 ret = snprintf( p, n, "\?\?=" );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002646 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002647
2648 for( i = 0; i < name->val.len; i++ )
2649 {
Paul Bakker27fdf462011-06-09 13:55:13 +00002650 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002651 break;
2652
2653 c = name->val.p[i];
2654 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2655 s[i] = '?';
2656 else s[i] = c;
2657 }
2658 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002659 ret = snprintf( p, n, "%s", s );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002660 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002661 name = name->next;
2662 }
2663
Paul Bakker23986e52011-04-24 08:57:21 +00002664 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002665}
2666
2667/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002668 * Store the serial in printable form into buf; no more
2669 * than size characters will be written
2670 */
2671int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2672{
Paul Bakker23986e52011-04-24 08:57:21 +00002673 int ret;
2674 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00002675 char *p;
2676
2677 p = buf;
2678 n = size;
2679
2680 nr = ( serial->len <= 32 )
Paul Bakker03c7c252011-11-25 12:37:37 +00002681 ? serial->len : 28;
Paul Bakkerdd476992011-01-16 21:34:59 +00002682
2683 for( i = 0; i < nr; i++ )
2684 {
Paul Bakker93048802011-12-05 14:38:06 +00002685 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002686 continue;
2687
Paul Bakkerdd476992011-01-16 21:34:59 +00002688 ret = snprintf( p, n, "%02X%s",
2689 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2690 SAFE_SNPRINTF();
2691 }
2692
Paul Bakker03c7c252011-11-25 12:37:37 +00002693 if( nr != serial->len )
2694 {
2695 ret = snprintf( p, n, "...." );
2696 SAFE_SNPRINTF();
2697 }
2698
Paul Bakker23986e52011-04-24 08:57:21 +00002699 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00002700}
2701
2702/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002703 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002704 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002705int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2706 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002707{
Paul Bakker23986e52011-04-24 08:57:21 +00002708 int ret;
2709 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002710 char *p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002711 const char *desc = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00002712
2713 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002714 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002715
Paul Bakkerd98030e2009-05-02 15:13:40 +00002716 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002717 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002718 SAFE_SNPRINTF();
2719 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002720 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002721 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002722
Paul Bakkerdd476992011-01-16 21:34:59 +00002723 ret = x509parse_serial_gets( p, n, &crt->serial);
2724 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002725
Paul Bakkerd98030e2009-05-02 15:13:40 +00002726 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2727 SAFE_SNPRINTF();
2728 ret = x509parse_dn_gets( p, n, &crt->issuer );
2729 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002730
Paul Bakkerd98030e2009-05-02 15:13:40 +00002731 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2732 SAFE_SNPRINTF();
2733 ret = x509parse_dn_gets( p, n, &crt->subject );
2734 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002735
Paul Bakkerd98030e2009-05-02 15:13:40 +00002736 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002737 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2738 crt->valid_from.year, crt->valid_from.mon,
2739 crt->valid_from.day, crt->valid_from.hour,
2740 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002741 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002742
Paul Bakkerd98030e2009-05-02 15:13:40 +00002743 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002744 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2745 crt->valid_to.year, crt->valid_to.mon,
2746 crt->valid_to.day, crt->valid_to.hour,
2747 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002748 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002749
Paul Bakkerc70b9822013-04-07 22:00:46 +02002750 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002751 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002752
Paul Bakkerc70b9822013-04-07 22:00:46 +02002753 ret = oid_get_sig_alg_desc( &crt->sig_oid1, &desc );
2754 if( ret != 0 )
2755 ret = snprintf( p, n, "???" );
2756 else
2757 ret = snprintf( p, n, desc );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002758 SAFE_SNPRINTF();
2759
2760 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
Paul Bakker5c2364c2012-10-01 14:41:15 +00002761 (int) crt->rsa.N.n * (int) sizeof( t_uint ) * 8 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002762 SAFE_SNPRINTF();
2763
Paul Bakker23986e52011-04-24 08:57:21 +00002764 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002765}
2766
Paul Bakker74111d32011-01-15 16:57:55 +00002767/*
2768 * Return an informational string describing the given OID
2769 */
2770const char *x509_oid_get_description( x509_buf *oid )
2771{
Paul Bakkerc70b9822013-04-07 22:00:46 +02002772 const char *desc = NULL;
2773 int ret;
Paul Bakker74111d32011-01-15 16:57:55 +00002774
Paul Bakkerc70b9822013-04-07 22:00:46 +02002775 ret = oid_get_extended_key_usage( oid, &desc );
Paul Bakker74111d32011-01-15 16:57:55 +00002776
Paul Bakkerc70b9822013-04-07 22:00:46 +02002777 if( ret != 0 )
2778 return( NULL );
Paul Bakker74111d32011-01-15 16:57:55 +00002779
Paul Bakkerc70b9822013-04-07 22:00:46 +02002780 return( desc );
Paul Bakker74111d32011-01-15 16:57:55 +00002781}
2782
2783/* Return the x.y.z.... style numeric string for the given OID */
2784int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2785{
Paul Bakkerc70b9822013-04-07 22:00:46 +02002786 return oid_get_numeric_string( buf, size, oid );
Paul Bakker74111d32011-01-15 16:57:55 +00002787}
2788
Paul Bakkerd98030e2009-05-02 15:13:40 +00002789/*
2790 * Return an informational string about the CRL.
2791 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002792int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2793 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002794{
Paul Bakker23986e52011-04-24 08:57:21 +00002795 int ret;
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002796 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002797 char *p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002798 const char *desc;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002799 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002800
2801 p = buf;
2802 n = size;
2803
2804 ret = snprintf( p, n, "%sCRL version : %d",
2805 prefix, crl->version );
2806 SAFE_SNPRINTF();
2807
2808 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2809 SAFE_SNPRINTF();
2810 ret = x509parse_dn_gets( p, n, &crl->issuer );
2811 SAFE_SNPRINTF();
2812
2813 ret = snprintf( p, n, "\n%sthis update : " \
2814 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2815 crl->this_update.year, crl->this_update.mon,
2816 crl->this_update.day, crl->this_update.hour,
2817 crl->this_update.min, crl->this_update.sec );
2818 SAFE_SNPRINTF();
2819
2820 ret = snprintf( p, n, "\n%snext update : " \
2821 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2822 crl->next_update.year, crl->next_update.mon,
2823 crl->next_update.day, crl->next_update.hour,
2824 crl->next_update.min, crl->next_update.sec );
2825 SAFE_SNPRINTF();
2826
2827 entry = &crl->entry;
2828
2829 ret = snprintf( p, n, "\n%sRevoked certificates:",
2830 prefix );
2831 SAFE_SNPRINTF();
2832
Paul Bakker9be19372009-07-27 20:21:53 +00002833 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002834 {
2835 ret = snprintf( p, n, "\n%sserial number: ",
2836 prefix );
2837 SAFE_SNPRINTF();
2838
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002839 ret = x509parse_serial_gets( p, n, &entry->serial);
2840 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002841
Paul Bakkerd98030e2009-05-02 15:13:40 +00002842 ret = snprintf( p, n, " revocation date: " \
2843 "%04d-%02d-%02d %02d:%02d:%02d",
2844 entry->revocation_date.year, entry->revocation_date.mon,
2845 entry->revocation_date.day, entry->revocation_date.hour,
2846 entry->revocation_date.min, entry->revocation_date.sec );
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002847 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002848
2849 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002850 }
2851
Paul Bakkerc70b9822013-04-07 22:00:46 +02002852 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002853 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002854
Paul Bakkerc70b9822013-04-07 22:00:46 +02002855 ret = oid_get_sig_alg_desc( &crl->sig_oid1, &desc );
2856 if( ret != 0 )
2857 ret = snprintf( p, n, "???" );
2858 else
2859 ret = snprintf( p, n, desc );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002860 SAFE_SNPRINTF();
2861
Paul Bakker1e27bb22009-07-19 20:25:25 +00002862 ret = snprintf( p, n, "\n" );
2863 SAFE_SNPRINTF();
2864
Paul Bakker23986e52011-04-24 08:57:21 +00002865 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002866}
2867
2868/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00002869 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00002870 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002871int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00002872{
Paul Bakkercce9d772011-11-18 14:26:47 +00002873 int year, mon, day;
2874 int hour, min, sec;
2875
2876#if defined(_WIN32)
2877 SYSTEMTIME st;
2878
2879 GetLocalTime(&st);
2880
2881 year = st.wYear;
2882 mon = st.wMonth;
2883 day = st.wDay;
2884 hour = st.wHour;
2885 min = st.wMinute;
2886 sec = st.wSecond;
2887#else
Paul Bakker5121ce52009-01-03 21:22:43 +00002888 struct tm *lt;
2889 time_t tt;
2890
2891 tt = time( NULL );
2892 lt = localtime( &tt );
2893
Paul Bakkercce9d772011-11-18 14:26:47 +00002894 year = lt->tm_year + 1900;
2895 mon = lt->tm_mon + 1;
2896 day = lt->tm_mday;
2897 hour = lt->tm_hour;
2898 min = lt->tm_min;
2899 sec = lt->tm_sec;
2900#endif
2901
2902 if( year > to->year )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002903 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002904
Paul Bakkercce9d772011-11-18 14:26:47 +00002905 if( year == to->year &&
2906 mon > to->mon )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002907 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002908
Paul Bakkercce9d772011-11-18 14:26:47 +00002909 if( year == to->year &&
2910 mon == to->mon &&
2911 day > to->day )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002912 return( 1 );
2913
Paul Bakkercce9d772011-11-18 14:26:47 +00002914 if( year == to->year &&
2915 mon == to->mon &&
2916 day == to->day &&
2917 hour > to->hour )
Paul Bakkerb6194992011-01-16 21:40:22 +00002918 return( 1 );
2919
Paul Bakkercce9d772011-11-18 14:26:47 +00002920 if( year == to->year &&
2921 mon == to->mon &&
2922 day == to->day &&
2923 hour == to->hour &&
2924 min > to->min )
Paul Bakkerb6194992011-01-16 21:40:22 +00002925 return( 1 );
2926
Paul Bakkercce9d772011-11-18 14:26:47 +00002927 if( year == to->year &&
2928 mon == to->mon &&
2929 day == to->day &&
2930 hour == to->hour &&
2931 min == to->min &&
2932 sec > to->sec )
Paul Bakkerb6194992011-01-16 21:40:22 +00002933 return( 1 );
2934
Paul Bakker40ea7de2009-05-03 10:18:48 +00002935 return( 0 );
2936}
2937
2938/*
2939 * Return 1 if the certificate is revoked, or 0 otherwise.
2940 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002941int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002942{
Paul Bakkerff60ee62010-03-16 21:09:09 +00002943 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00002944
2945 while( cur != NULL && cur->serial.len != 0 )
2946 {
Paul Bakkera056efc2011-01-16 21:38:35 +00002947 if( crt->serial.len == cur->serial.len &&
2948 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002949 {
2950 if( x509parse_time_expired( &cur->revocation_date ) )
2951 return( 1 );
2952 }
2953
2954 cur = cur->next;
2955 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002956
2957 return( 0 );
2958}
2959
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002960/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00002961 * Check that the given certificate is valid accoring to the CRL.
2962 */
2963static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
2964 x509_crl *crl_list)
2965{
2966 int flags = 0;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002967 unsigned char hash[POLARSSL_MD_MAX_SIZE];
2968 const md_info_t *md_info;
Paul Bakker76fd75a2011-01-16 21:12:10 +00002969
Paul Bakker915275b2012-09-28 07:10:55 +00002970 if( ca == NULL )
2971 return( flags );
2972
Paul Bakker76fd75a2011-01-16 21:12:10 +00002973 /*
2974 * TODO: What happens if no CRL is present?
2975 * Suggestion: Revocation state should be unknown if no CRL is present.
2976 * For backwards compatibility this is not yet implemented.
2977 */
2978
Paul Bakker915275b2012-09-28 07:10:55 +00002979 while( crl_list != NULL )
Paul Bakker76fd75a2011-01-16 21:12:10 +00002980 {
Paul Bakker915275b2012-09-28 07:10:55 +00002981 if( crl_list->version == 0 ||
2982 crl_list->issuer_raw.len != ca->subject_raw.len ||
Paul Bakker76fd75a2011-01-16 21:12:10 +00002983 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
2984 crl_list->issuer_raw.len ) != 0 )
2985 {
2986 crl_list = crl_list->next;
2987 continue;
2988 }
2989
2990 /*
2991 * Check if CRL is correctly signed by the trusted CA
2992 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02002993 md_info = md_info_from_type( crl_list->sig_md );
2994 if( md_info == NULL )
2995 {
2996 /*
2997 * Cannot check 'unknown' hash
2998 */
2999 flags |= BADCRL_NOT_TRUSTED;
3000 break;
3001 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00003002
Paul Bakkerc70b9822013-04-07 22:00:46 +02003003 md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
Paul Bakker76fd75a2011-01-16 21:12:10 +00003004
Paul Bakkerc70b9822013-04-07 22:00:46 +02003005 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, crl_list->sig_md,
Paul Bakker76fd75a2011-01-16 21:12:10 +00003006 0, hash, crl_list->sig.p ) == 0 )
3007 {
3008 /*
3009 * CRL is not trusted
3010 */
3011 flags |= BADCRL_NOT_TRUSTED;
3012 break;
3013 }
3014
3015 /*
3016 * Check for validity of CRL (Do not drop out)
3017 */
3018 if( x509parse_time_expired( &crl_list->next_update ) )
3019 flags |= BADCRL_EXPIRED;
3020
3021 /*
3022 * Check if certificate is revoked
3023 */
3024 if( x509parse_revoked(crt, crl_list) )
3025 {
3026 flags |= BADCERT_REVOKED;
3027 break;
3028 }
3029
3030 crl_list = crl_list->next;
3031 }
3032 return flags;
3033}
3034
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02003035static int x509_wildcard_verify( const char *cn, x509_buf *name )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003036{
3037 size_t i;
3038 size_t cn_idx = 0;
3039
Paul Bakker57b12982012-02-11 17:38:38 +00003040 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003041 return( 0 );
3042
3043 for( i = 0; i < strlen( cn ); ++i )
3044 {
3045 if( cn[i] == '.' )
3046 {
3047 cn_idx = i;
3048 break;
3049 }
3050 }
3051
3052 if( cn_idx == 0 )
3053 return( 0 );
3054
Paul Bakker535e97d2012-08-23 10:49:55 +00003055 if( strlen( cn ) - cn_idx == name->len - 1 &&
3056 memcmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003057 {
3058 return( 1 );
3059 }
3060
3061 return( 0 );
3062}
3063
Paul Bakker915275b2012-09-28 07:10:55 +00003064static int x509parse_verify_top(
3065 x509_cert *child, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003066 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003067 int (*f_vrfy)(void *, x509_cert *, int, int *),
3068 void *p_vrfy )
3069{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003070 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003071 int ca_flags = 0, check_path_cnt = path_cnt + 1;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003072 unsigned char hash[POLARSSL_MD_MAX_SIZE];
3073 const md_info_t *md_info;
Paul Bakker915275b2012-09-28 07:10:55 +00003074
3075 if( x509parse_time_expired( &child->valid_to ) )
3076 *flags |= BADCERT_EXPIRED;
3077
3078 /*
3079 * Child is the top of the chain. Check against the trust_ca list.
3080 */
3081 *flags |= BADCERT_NOT_TRUSTED;
3082
3083 while( trust_ca != NULL )
3084 {
3085 if( trust_ca->version == 0 ||
3086 child->issuer_raw.len != trust_ca->subject_raw.len ||
3087 memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
3088 child->issuer_raw.len ) != 0 )
3089 {
3090 trust_ca = trust_ca->next;
3091 continue;
3092 }
3093
Paul Bakker9a736322012-11-14 12:39:52 +00003094 /*
3095 * Reduce path_len to check against if top of the chain is
3096 * the same as the trusted CA
3097 */
3098 if( child->subject_raw.len == trust_ca->subject_raw.len &&
3099 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3100 child->issuer_raw.len ) == 0 )
3101 {
3102 check_path_cnt--;
3103 }
3104
Paul Bakker915275b2012-09-28 07:10:55 +00003105 if( trust_ca->max_pathlen > 0 &&
Paul Bakker9a736322012-11-14 12:39:52 +00003106 trust_ca->max_pathlen < check_path_cnt )
Paul Bakker915275b2012-09-28 07:10:55 +00003107 {
3108 trust_ca = trust_ca->next;
3109 continue;
3110 }
3111
Paul Bakkerc70b9822013-04-07 22:00:46 +02003112 md_info = md_info_from_type( child->sig_md );
3113 if( md_info == NULL )
3114 {
3115 /*
3116 * Cannot check 'unknown' hash
3117 */
3118 continue;
3119 }
Paul Bakker915275b2012-09-28 07:10:55 +00003120
Paul Bakkerc70b9822013-04-07 22:00:46 +02003121 md( md_info, child->tbs.p, child->tbs.len, hash );
Paul Bakker915275b2012-09-28 07:10:55 +00003122
Paul Bakkerc70b9822013-04-07 22:00:46 +02003123 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, child->sig_md,
Paul Bakker915275b2012-09-28 07:10:55 +00003124 0, hash, child->sig.p ) != 0 )
3125 {
3126 trust_ca = trust_ca->next;
3127 continue;
3128 }
3129
3130 /*
3131 * Top of chain is signed by a trusted CA
3132 */
3133 *flags &= ~BADCERT_NOT_TRUSTED;
3134 break;
3135 }
3136
Paul Bakker9a736322012-11-14 12:39:52 +00003137 /*
Paul Bakker3497d8c2012-11-24 11:53:17 +01003138 * If top of chain is not the same as the trusted CA send a verify request
3139 * to the callback for any issues with validity and CRL presence for the
3140 * trusted CA certificate.
Paul Bakker9a736322012-11-14 12:39:52 +00003141 */
3142 if( trust_ca != NULL &&
3143 ( child->subject_raw.len != trust_ca->subject_raw.len ||
3144 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3145 child->issuer_raw.len ) != 0 ) )
Paul Bakker915275b2012-09-28 07:10:55 +00003146 {
3147 /* Check trusted CA's CRL for then chain's top crt */
3148 *flags |= x509parse_verifycrl( child, trust_ca, ca_crl );
3149
3150 if( x509parse_time_expired( &trust_ca->valid_to ) )
3151 ca_flags |= BADCERT_EXPIRED;
3152
Paul Bakker915275b2012-09-28 07:10:55 +00003153 if( NULL != f_vrfy )
3154 {
Paul Bakker9a736322012-11-14 12:39:52 +00003155 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003156 return( ret );
3157 }
3158 }
3159
3160 /* Call callback on top cert */
3161 if( NULL != f_vrfy )
3162 {
Paul Bakker9a736322012-11-14 12:39:52 +00003163 if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003164 return( ret );
3165 }
3166
Paul Bakker915275b2012-09-28 07:10:55 +00003167 *flags |= ca_flags;
3168
3169 return( 0 );
3170}
3171
3172static int x509parse_verify_child(
3173 x509_cert *child, x509_cert *parent, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003174 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003175 int (*f_vrfy)(void *, x509_cert *, int, int *),
3176 void *p_vrfy )
3177{
Paul Bakkerc70b9822013-04-07 22:00:46 +02003178 int ret;
Paul Bakker915275b2012-09-28 07:10:55 +00003179 int parent_flags = 0;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003180 unsigned char hash[POLARSSL_MD_MAX_SIZE];
Paul Bakker915275b2012-09-28 07:10:55 +00003181 x509_cert *grandparent;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003182 const md_info_t *md_info;
Paul Bakker915275b2012-09-28 07:10:55 +00003183
3184 if( x509parse_time_expired( &child->valid_to ) )
3185 *flags |= BADCERT_EXPIRED;
3186
Paul Bakkerc70b9822013-04-07 22:00:46 +02003187 md_info = md_info_from_type( child->sig_md );
3188 if( md_info == NULL )
3189 {
3190 /*
3191 * Cannot check 'unknown' hash
3192 */
Paul Bakker915275b2012-09-28 07:10:55 +00003193 *flags |= BADCERT_NOT_TRUSTED;
Paul Bakkerc70b9822013-04-07 22:00:46 +02003194 }
3195 else
3196 {
3197 md( md_info, child->tbs.p, child->tbs.len, hash );
3198
3199 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, child->sig_md, 0, hash,
3200 child->sig.p ) != 0 )
3201 *flags |= BADCERT_NOT_TRUSTED;
3202 }
3203
Paul Bakker915275b2012-09-28 07:10:55 +00003204 /* Check trusted CA's CRL for the given crt */
3205 *flags |= x509parse_verifycrl(child, parent, ca_crl);
3206
3207 grandparent = parent->next;
3208
3209 while( grandparent != NULL )
3210 {
3211 if( grandparent->version == 0 ||
3212 grandparent->ca_istrue == 0 ||
3213 parent->issuer_raw.len != grandparent->subject_raw.len ||
3214 memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
3215 parent->issuer_raw.len ) != 0 )
3216 {
3217 grandparent = grandparent->next;
3218 continue;
3219 }
3220 break;
3221 }
3222
Paul Bakker915275b2012-09-28 07:10:55 +00003223 if( grandparent != NULL )
3224 {
3225 /*
3226 * Part of the chain
3227 */
Paul Bakker9a736322012-11-14 12:39:52 +00003228 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 +00003229 if( ret != 0 )
3230 return( ret );
3231 }
3232 else
3233 {
Paul Bakker9a736322012-11-14 12:39:52 +00003234 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 +00003235 if( ret != 0 )
3236 return( ret );
3237 }
3238
3239 /* child is verified to be a child of the parent, call verify callback */
3240 if( NULL != f_vrfy )
Paul Bakker9a736322012-11-14 12:39:52 +00003241 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003242 return( ret );
Paul Bakker915275b2012-09-28 07:10:55 +00003243
3244 *flags |= parent_flags;
3245
3246 return( 0 );
3247}
3248
Paul Bakker76fd75a2011-01-16 21:12:10 +00003249/*
Paul Bakker5121ce52009-01-03 21:22:43 +00003250 * Verify the certificate validity
3251 */
3252int x509parse_verify( x509_cert *crt,
3253 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00003254 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003255 const char *cn, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003256 int (*f_vrfy)(void *, x509_cert *, int, int *),
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003257 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00003258{
Paul Bakker23986e52011-04-24 08:57:21 +00003259 size_t cn_len;
Paul Bakker915275b2012-09-28 07:10:55 +00003260 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003261 int pathlen = 0;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003262 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00003263 x509_name *name;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003264 x509_sequence *cur = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003265
Paul Bakker40ea7de2009-05-03 10:18:48 +00003266 *flags = 0;
3267
Paul Bakker5121ce52009-01-03 21:22:43 +00003268 if( cn != NULL )
3269 {
3270 name = &crt->subject;
3271 cn_len = strlen( cn );
3272
Paul Bakker4d2c1242012-05-10 14:12:46 +00003273 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
Paul Bakker5121ce52009-01-03 21:22:43 +00003274 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00003275 cur = &crt->subject_alt_names;
3276
3277 while( cur != NULL )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003278 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003279 if( cur->buf.len == cn_len &&
3280 memcmp( cn, cur->buf.p, cn_len ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003281 break;
3282
Paul Bakker535e97d2012-08-23 10:49:55 +00003283 if( cur->buf.len > 2 &&
3284 memcmp( cur->buf.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003285 x509_wildcard_verify( cn, &cur->buf ) )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003286 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003287
Paul Bakker4d2c1242012-05-10 14:12:46 +00003288 cur = cur->next;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003289 }
3290
3291 if( cur == NULL )
3292 *flags |= BADCERT_CN_MISMATCH;
3293 }
Paul Bakker4d2c1242012-05-10 14:12:46 +00003294 else
3295 {
3296 while( name != NULL )
3297 {
Paul Bakkerc70b9822013-04-07 22:00:46 +02003298 if( OID_CMP( OID_AT_CN, &name->oid ) )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003299 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003300 if( name->val.len == cn_len &&
3301 memcmp( name->val.p, cn, cn_len ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003302 break;
3303
Paul Bakker535e97d2012-08-23 10:49:55 +00003304 if( name->val.len > 2 &&
3305 memcmp( name->val.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003306 x509_wildcard_verify( cn, &name->val ) )
3307 break;
3308 }
3309
3310 name = name->next;
3311 }
3312
3313 if( name == NULL )
3314 *flags |= BADCERT_CN_MISMATCH;
3315 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003316 }
3317
Paul Bakker5121ce52009-01-03 21:22:43 +00003318 /*
Paul Bakker915275b2012-09-28 07:10:55 +00003319 * Iterate upwards in the given cert chain, to find our crt parent.
3320 * Ignore any upper cert with CA != TRUE.
Paul Bakker5121ce52009-01-03 21:22:43 +00003321 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003322 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003323
Paul Bakker76fd75a2011-01-16 21:12:10 +00003324 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003325 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003326 if( parent->ca_istrue == 0 ||
3327 crt->issuer_raw.len != parent->subject_raw.len ||
3328 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00003329 crt->issuer_raw.len ) != 0 )
3330 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003331 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003332 continue;
3333 }
Paul Bakker915275b2012-09-28 07:10:55 +00003334 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003335 }
3336
Paul Bakker915275b2012-09-28 07:10:55 +00003337 if( parent != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003338 {
Paul Bakker915275b2012-09-28 07:10:55 +00003339 /*
3340 * Part of the chain
3341 */
Paul Bakker9a736322012-11-14 12:39:52 +00003342 ret = x509parse_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003343 if( ret != 0 )
3344 return( ret );
3345 }
3346 else
Paul Bakker74111d32011-01-15 16:57:55 +00003347 {
Paul Bakker9a736322012-11-14 12:39:52 +00003348 ret = x509parse_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003349 if( ret != 0 )
3350 return( ret );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003351 }
Paul Bakker915275b2012-09-28 07:10:55 +00003352
3353 if( *flags != 0 )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003354 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003355
Paul Bakker5121ce52009-01-03 21:22:43 +00003356 return( 0 );
3357}
3358
3359/*
3360 * Unallocate all certificate data
3361 */
3362void x509_free( x509_cert *crt )
3363{
3364 x509_cert *cert_cur = crt;
3365 x509_cert *cert_prv;
3366 x509_name *name_cur;
3367 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00003368 x509_sequence *seq_cur;
3369 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00003370
3371 if( crt == NULL )
3372 return;
3373
3374 do
3375 {
3376 rsa_free( &cert_cur->rsa );
3377
3378 name_cur = cert_cur->issuer.next;
3379 while( name_cur != NULL )
3380 {
3381 name_prv = name_cur;
3382 name_cur = name_cur->next;
3383 memset( name_prv, 0, sizeof( x509_name ) );
3384 free( name_prv );
3385 }
3386
3387 name_cur = cert_cur->subject.next;
3388 while( name_cur != NULL )
3389 {
3390 name_prv = name_cur;
3391 name_cur = name_cur->next;
3392 memset( name_prv, 0, sizeof( x509_name ) );
3393 free( name_prv );
3394 }
3395
Paul Bakker74111d32011-01-15 16:57:55 +00003396 seq_cur = cert_cur->ext_key_usage.next;
3397 while( seq_cur != NULL )
3398 {
3399 seq_prv = seq_cur;
3400 seq_cur = seq_cur->next;
3401 memset( seq_prv, 0, sizeof( x509_sequence ) );
3402 free( seq_prv );
3403 }
3404
Paul Bakker8afa70d2012-02-11 18:42:45 +00003405 seq_cur = cert_cur->subject_alt_names.next;
3406 while( seq_cur != NULL )
3407 {
3408 seq_prv = seq_cur;
3409 seq_cur = seq_cur->next;
3410 memset( seq_prv, 0, sizeof( x509_sequence ) );
3411 free( seq_prv );
3412 }
3413
Paul Bakker5121ce52009-01-03 21:22:43 +00003414 if( cert_cur->raw.p != NULL )
3415 {
3416 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
3417 free( cert_cur->raw.p );
3418 }
3419
3420 cert_cur = cert_cur->next;
3421 }
3422 while( cert_cur != NULL );
3423
3424 cert_cur = crt;
3425 do
3426 {
3427 cert_prv = cert_cur;
3428 cert_cur = cert_cur->next;
3429
3430 memset( cert_prv, 0, sizeof( x509_cert ) );
3431 if( cert_prv != crt )
3432 free( cert_prv );
3433 }
3434 while( cert_cur != NULL );
3435}
3436
Paul Bakkerd98030e2009-05-02 15:13:40 +00003437/*
3438 * Unallocate all CRL data
3439 */
3440void x509_crl_free( x509_crl *crl )
3441{
3442 x509_crl *crl_cur = crl;
3443 x509_crl *crl_prv;
3444 x509_name *name_cur;
3445 x509_name *name_prv;
3446 x509_crl_entry *entry_cur;
3447 x509_crl_entry *entry_prv;
3448
3449 if( crl == NULL )
3450 return;
3451
3452 do
3453 {
3454 name_cur = crl_cur->issuer.next;
3455 while( name_cur != NULL )
3456 {
3457 name_prv = name_cur;
3458 name_cur = name_cur->next;
3459 memset( name_prv, 0, sizeof( x509_name ) );
3460 free( name_prv );
3461 }
3462
3463 entry_cur = crl_cur->entry.next;
3464 while( entry_cur != NULL )
3465 {
3466 entry_prv = entry_cur;
3467 entry_cur = entry_cur->next;
3468 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
3469 free( entry_prv );
3470 }
3471
3472 if( crl_cur->raw.p != NULL )
3473 {
3474 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
3475 free( crl_cur->raw.p );
3476 }
3477
3478 crl_cur = crl_cur->next;
3479 }
3480 while( crl_cur != NULL );
3481
3482 crl_cur = crl;
3483 do
3484 {
3485 crl_prv = crl_cur;
3486 crl_cur = crl_cur->next;
3487
3488 memset( crl_prv, 0, sizeof( x509_crl ) );
3489 if( crl_prv != crl )
3490 free( crl_prv );
3491 }
3492 while( crl_cur != NULL );
3493}
3494
Paul Bakker40e46942009-01-03 21:51:57 +00003495#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00003496
Paul Bakker40e46942009-01-03 21:51:57 +00003497#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00003498
3499/*
3500 * Checkup routine
3501 */
3502int x509_self_test( int verbose )
3503{
Paul Bakker5690efc2011-05-26 13:16:06 +00003504#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00003505 int ret;
3506 int flags;
3507 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00003508 x509_cert cacert;
3509 x509_cert clicert;
3510 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00003511#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003512 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00003513#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003514
3515 if( verbose != 0 )
3516 printf( " X.509 certificate load: " );
3517
3518 memset( &clicert, 0, sizeof( x509_cert ) );
3519
Paul Bakker3c2122f2013-06-24 19:03:14 +02003520 ret = x509parse_crt( &clicert, (const unsigned char *) test_cli_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003521 strlen( test_cli_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003522 if( ret != 0 )
3523 {
3524 if( verbose != 0 )
3525 printf( "failed\n" );
3526
3527 return( ret );
3528 }
3529
3530 memset( &cacert, 0, sizeof( x509_cert ) );
3531
Paul Bakker3c2122f2013-06-24 19:03:14 +02003532 ret = x509parse_crt( &cacert, (const unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003533 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003534 if( ret != 0 )
3535 {
3536 if( verbose != 0 )
3537 printf( "failed\n" );
3538
3539 return( ret );
3540 }
3541
3542 if( verbose != 0 )
3543 printf( "passed\n X.509 private key load: " );
3544
3545 i = strlen( test_ca_key );
3546 j = strlen( test_ca_pwd );
3547
Paul Bakker66b78b22011-03-25 14:22:50 +00003548 rsa_init( &rsa, RSA_PKCS_V15, 0 );
3549
Paul Bakker5121ce52009-01-03 21:22:43 +00003550 if( ( ret = x509parse_key( &rsa,
Paul Bakker3c2122f2013-06-24 19:03:14 +02003551 (const unsigned char *) test_ca_key, i,
3552 (const unsigned char *) test_ca_pwd, j ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003553 {
3554 if( verbose != 0 )
3555 printf( "failed\n" );
3556
3557 return( ret );
3558 }
3559
3560 if( verbose != 0 )
3561 printf( "passed\n X.509 signature verify: ");
3562
Paul Bakker23986e52011-04-24 08:57:21 +00003563 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003564 if( ret != 0 )
3565 {
Paul Bakker23986e52011-04-24 08:57:21 +00003566 printf("%02x", flags);
Paul Bakker5121ce52009-01-03 21:22:43 +00003567 if( verbose != 0 )
3568 printf( "failed\n" );
3569
3570 return( ret );
3571 }
3572
Paul Bakker5690efc2011-05-26 13:16:06 +00003573#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003574 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003575 printf( "passed\n X.509 DHM parameter load: " );
3576
3577 i = strlen( test_dhm_params );
3578 j = strlen( test_ca_pwd );
3579
Paul Bakker3c2122f2013-06-24 19:03:14 +02003580 if( ( ret = x509parse_dhm( &dhm, (const unsigned char *) test_dhm_params, i ) ) != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003581 {
3582 if( verbose != 0 )
3583 printf( "failed\n" );
3584
3585 return( ret );
3586 }
3587
3588 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003589 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00003590#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003591
3592 x509_free( &cacert );
3593 x509_free( &clicert );
3594 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00003595#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003596 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00003597#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003598
3599 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003600#else
3601 ((void) verbose);
3602 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3603#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003604}
3605
3606#endif
3607
3608#endif