blob: ce5628923b947d399baf99e714cca2cf57f7b21e [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * X.509 certificate and private key decoding
3 *
Paul Bakkerefc30292011-11-10 14:43:23 +00004 * Copyright (C) 2006-2011, Brainspark B.V.
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
Paul Bakker84f12b72010-07-18 10:13:04 +00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakkerb96f1542010-07-18 20:36:00 +00008 *
Paul Bakker77b385e2009-07-28 17:23:11 +00009 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +000010 *
Paul Bakker5121ce52009-01-03 21:22:43 +000011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25/*
Paul Bakkerad8d3542012-02-16 15:28:14 +000026 * The ITU-T X.509 standard defines a certificate format for PKI.
Paul Bakker5121ce52009-01-03 21:22:43 +000027 *
Paul Bakker5121ce52009-01-03 21:22:43 +000028 * http://www.ietf.org/rfc/rfc3279.txt
Paul Bakkerad8d3542012-02-16 15:28:14 +000029 * http://www.ietf.org/rfc/rfc3280.txt
Paul Bakker5121ce52009-01-03 21:22:43 +000030 *
31 * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
32 *
33 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
34 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
35 */
36
Paul Bakker40e46942009-01-03 21:51:57 +000037#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000038
Paul Bakker40e46942009-01-03 21:51:57 +000039#if defined(POLARSSL_X509_PARSE_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000040
Paul Bakker40e46942009-01-03 21:51:57 +000041#include "polarssl/x509.h"
Paul Bakkerefc30292011-11-10 14:43:23 +000042#include "polarssl/asn1.h"
Paul Bakker96743fc2011-02-12 14:30:57 +000043#include "polarssl/pem.h"
Paul Bakker40e46942009-01-03 21:51:57 +000044#include "polarssl/des.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010045#if defined(POLARSSL_MD2_C)
Paul Bakker40e46942009-01-03 21:51:57 +000046#include "polarssl/md2.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010047#endif
48#if defined(POLARSSL_MD4_C)
Paul Bakker40e46942009-01-03 21:51:57 +000049#include "polarssl/md4.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010050#endif
51#if defined(POLARSSL_MD5_C)
Paul Bakker40e46942009-01-03 21:51:57 +000052#include "polarssl/md5.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010053#endif
54#if defined(POLARSSL_SHA1_C)
Paul Bakker40e46942009-01-03 21:51:57 +000055#include "polarssl/sha1.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010056#endif
57#if defined(POLARSSL_SHA2_C)
Paul Bakker026c03b2009-03-28 17:53:03 +000058#include "polarssl/sha2.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010059#endif
60#if defined(POLARSSL_SHA4_C)
Paul Bakker026c03b2009-03-28 17:53:03 +000061#include "polarssl/sha4.h"
Paul Bakker2ca8ad12013-02-19 13:17:38 +010062#endif
Paul Bakker1b57b062011-01-06 15:48:19 +000063#include "polarssl/dhm.h"
Paul Bakkercf6e95d2013-06-12 13:18:15 +020064#include "polarssl/pkcs12.h"
Paul Bakker1fd43212013-06-17 15:14:42 +020065#if defined(POLARSSL_PKCS5_C)
66#include "polarssl/pkcs5.h"
67#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000068
69#include <string.h>
70#include <stdlib.h>
Paul Bakker4f229e52011-12-04 22:11:35 +000071#if defined(_WIN32)
Paul Bakkercce9d772011-11-18 14:26:47 +000072#include <windows.h>
73#else
Paul Bakker5121ce52009-01-03 21:22:43 +000074#include <time.h>
Paul Bakkercce9d772011-11-18 14:26:47 +000075#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000076
Paul Bakker335db3f2011-04-25 15:28:35 +000077#if defined(POLARSSL_FS_IO)
78#include <stdio.h>
Paul Bakker4a2bd0d2012-11-02 11:06:08 +000079#if !defined(_WIN32)
Paul Bakker8d914582012-06-04 12:46:42 +000080#include <sys/types.h>
Paul Bakkercbfcaa92013-06-13 09:20:25 +020081#include <sys/stat.h>
Paul Bakker8d914582012-06-04 12:46:42 +000082#include <dirent.h>
83#endif
Paul Bakker335db3f2011-04-25 15:28:35 +000084#endif
85
Paul Bakkercf6e95d2013-06-12 13:18:15 +020086/* Compare a given OID string with an OID x509_buf * */
87#define OID_CMP(oid_str, oid_buf) \
88 ( ( OID_SIZE(oid_str) == (oid_buf)->len ) && \
89 memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0)
90
Paul Bakker5121ce52009-01-03 21:22:43 +000091/*
Paul Bakker5121ce52009-01-03 21:22:43 +000092 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
93 */
94static int x509_get_version( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +000095 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +000096 int *ver )
97{
Paul Bakker23986e52011-04-24 08:57:21 +000098 int ret;
99 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000100
101 if( ( ret = asn1_get_tag( p, end, &len,
102 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
103 {
Paul Bakker40e46942009-01-03 21:51:57 +0000104 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +0000105 {
106 *ver = 0;
107 return( 0 );
108 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000109
110 return( ret );
111 }
112
113 end = *p + len;
114
115 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000116 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000117
118 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000119 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION +
Paul Bakker40e46942009-01-03 21:51:57 +0000120 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000121
122 return( 0 );
123}
124
125/*
Paul Bakkerfae618f2011-10-12 11:53:52 +0000126 * Version ::= INTEGER { v1(0), v2(1) }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000127 */
128static int x509_crl_get_version( unsigned char **p,
129 const unsigned char *end,
130 int *ver )
131{
132 int ret;
133
134 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
135 {
136 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +0000137 {
138 *ver = 0;
139 return( 0 );
140 }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000141
142 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
143 }
144
145 return( 0 );
146}
147
148/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000149 * CertificateSerialNumber ::= INTEGER
150 */
151static int x509_get_serial( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000152 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000153 x509_buf *serial )
154{
155 int ret;
156
157 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000158 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000159 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000160
161 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
162 **p != ASN1_INTEGER )
Paul Bakker9d781402011-05-09 16:17:09 +0000163 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000164 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000165
166 serial->tag = *(*p)++;
167
168 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000169 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000170
171 serial->p = *p;
172 *p += serial->len;
173
174 return( 0 );
175}
176
177/*
178 * AlgorithmIdentifier ::= SEQUENCE {
179 * algorithm OBJECT IDENTIFIER,
180 * parameters ANY DEFINED BY algorithm OPTIONAL }
181 */
182static int x509_get_alg( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000183 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000184 x509_buf *alg )
185{
Paul Bakker23986e52011-04-24 08:57:21 +0000186 int ret;
187 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000188
189 if( ( ret = asn1_get_tag( p, end, &len,
190 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000191 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000192
193 end = *p + len;
194 alg->tag = **p;
195
196 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000197 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000198
199 alg->p = *p;
200 *p += alg->len;
201
202 if( *p == end )
203 return( 0 );
204
205 /*
206 * assume the algorithm parameters must be NULL
207 */
208 if( ( ret = asn1_get_tag( p, end, &len, ASN1_NULL ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000209 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000210
211 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000212 return( POLARSSL_ERR_X509_CERT_INVALID_ALG +
Paul Bakker40e46942009-01-03 21:51:57 +0000213 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000214
215 return( 0 );
216}
217
218/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000219 * AttributeTypeAndValue ::= SEQUENCE {
220 * type AttributeType,
221 * value AttributeValue }
222 *
223 * AttributeType ::= OBJECT IDENTIFIER
224 *
225 * AttributeValue ::= ANY DEFINED BY AttributeType
226 */
Paul Bakker400ff6f2011-02-20 10:40:16 +0000227static int x509_get_attr_type_value( unsigned char **p,
228 const unsigned char *end,
229 x509_name *cur )
Paul Bakker5121ce52009-01-03 21:22:43 +0000230{
Paul Bakker23986e52011-04-24 08:57:21 +0000231 int ret;
232 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000233 x509_buf *oid;
234 x509_buf *val;
235
236 if( ( ret = asn1_get_tag( p, end, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000237 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000238 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000239
Paul Bakker5121ce52009-01-03 21:22:43 +0000240 oid = &cur->oid;
241 oid->tag = **p;
242
243 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000244 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000245
246 oid->p = *p;
247 *p += oid->len;
248
249 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000250 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000251 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000252
253 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
254 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
255 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker9d781402011-05-09 16:17:09 +0000256 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000257 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000258
259 val = &cur->val;
260 val->tag = *(*p)++;
261
262 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000263 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000264
265 val->p = *p;
266 *p += val->len;
267
268 cur->next = NULL;
269
Paul Bakker400ff6f2011-02-20 10:40:16 +0000270 return( 0 );
271}
272
273/*
274 * RelativeDistinguishedName ::=
275 * SET OF AttributeTypeAndValue
276 *
277 * AttributeTypeAndValue ::= SEQUENCE {
278 * type AttributeType,
279 * value AttributeValue }
280 *
281 * AttributeType ::= OBJECT IDENTIFIER
282 *
283 * AttributeValue ::= ANY DEFINED BY AttributeType
284 */
285static int x509_get_name( unsigned char **p,
286 const unsigned char *end,
287 x509_name *cur )
288{
Paul Bakker23986e52011-04-24 08:57:21 +0000289 int ret;
290 size_t len;
Paul Bakker400ff6f2011-02-20 10:40:16 +0000291 const unsigned char *end2;
292 x509_name *use;
293
294 if( ( ret = asn1_get_tag( p, end, &len,
295 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000296 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000297
298 end2 = end;
299 end = *p + len;
300 use = cur;
301
302 do
303 {
304 if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
305 return( ret );
306
307 if( *p != end )
308 {
309 use->next = (x509_name *) malloc(
310 sizeof( x509_name ) );
311
312 if( use->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000313 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000314
315 memset( use->next, 0, sizeof( x509_name ) );
316
317 use = use->next;
318 }
319 }
320 while( *p != end );
Paul Bakker5121ce52009-01-03 21:22:43 +0000321
322 /*
323 * recurse until end of SEQUENCE is reached
324 */
325 if( *p == end2 )
326 return( 0 );
327
328 cur->next = (x509_name *) malloc(
329 sizeof( x509_name ) );
330
331 if( cur->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000332 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000333
Paul Bakker430ffbe2012-05-01 08:14:20 +0000334 memset( cur->next, 0, sizeof( x509_name ) );
335
Paul Bakker5121ce52009-01-03 21:22:43 +0000336 return( x509_get_name( p, end2, cur->next ) );
337}
338
339/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000340 * Time ::= CHOICE {
341 * utcTime UTCTime,
342 * generalTime GeneralizedTime }
343 */
Paul Bakker91200182010-02-18 21:26:15 +0000344static int x509_get_time( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000345 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000346 x509_time *time )
347{
Paul Bakker23986e52011-04-24 08:57:21 +0000348 int ret;
349 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000350 char date[64];
Paul Bakker91200182010-02-18 21:26:15 +0000351 unsigned char tag;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000352
Paul Bakker91200182010-02-18 21:26:15 +0000353 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000354 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
355 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000356
Paul Bakker91200182010-02-18 21:26:15 +0000357 tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000358
Paul Bakker91200182010-02-18 21:26:15 +0000359 if ( tag == ASN1_UTC_TIME )
360 {
361 (*p)++;
362 ret = asn1_get_len( p, end, &len );
363
364 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000365 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000366
Paul Bakker91200182010-02-18 21:26:15 +0000367 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000368 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
369 len : sizeof( date ) - 1 );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000370
Paul Bakker91200182010-02-18 21:26:15 +0000371 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
372 &time->year, &time->mon, &time->day,
373 &time->hour, &time->min, &time->sec ) < 5 )
374 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000375
Paul Bakker400ff6f2011-02-20 10:40:16 +0000376 time->year += 100 * ( time->year < 50 );
Paul Bakker91200182010-02-18 21:26:15 +0000377 time->year += 1900;
378
379 *p += len;
380
381 return( 0 );
382 }
383 else if ( tag == ASN1_GENERALIZED_TIME )
384 {
385 (*p)++;
386 ret = asn1_get_len( p, end, &len );
387
388 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000389 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker91200182010-02-18 21:26:15 +0000390
391 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000392 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
393 len : sizeof( date ) - 1 );
Paul Bakker91200182010-02-18 21:26:15 +0000394
395 if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
396 &time->year, &time->mon, &time->day,
397 &time->hour, &time->min, &time->sec ) < 5 )
398 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
399
400 *p += len;
401
402 return( 0 );
403 }
404 else
Paul Bakker9d781402011-05-09 16:17:09 +0000405 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000406}
407
408
409/*
410 * Validity ::= SEQUENCE {
411 * notBefore Time,
412 * notAfter Time }
413 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000414static int x509_get_dates( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000415 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000416 x509_time *from,
417 x509_time *to )
418{
Paul Bakker23986e52011-04-24 08:57:21 +0000419 int ret;
420 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000421
422 if( ( ret = asn1_get_tag( p, end, &len,
423 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000424 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000425
426 end = *p + len;
427
Paul Bakker91200182010-02-18 21:26:15 +0000428 if( ( ret = x509_get_time( p, end, from ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000429 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000430
Paul Bakker91200182010-02-18 21:26:15 +0000431 if( ( ret = x509_get_time( p, end, to ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000432 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000433
434 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000435 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker40e46942009-01-03 21:51:57 +0000436 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000437
438 return( 0 );
439}
440
441/*
442 * SubjectPublicKeyInfo ::= SEQUENCE {
443 * algorithm AlgorithmIdentifier,
444 * subjectPublicKey BIT STRING }
445 */
446static int x509_get_pubkey( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000447 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000448 x509_buf *pk_alg_oid,
449 mpi *N, mpi *E )
450{
Paul Bakker65a19092013-06-06 21:14:58 +0200451 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000452 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000453 unsigned char *end2;
454
455 if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 )
456 return( ret );
457
458 /*
459 * only RSA public keys handled at this time
460 */
Paul Bakker65a19092013-06-06 21:14:58 +0200461 if( pk_alg_oid->len != 9 ||
462 memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) != 0 )
Paul Bakker400ff6f2011-02-20 10:40:16 +0000463 {
Paul Bakkered56b222011-07-13 11:26:43 +0000464 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
Paul Bakker65a19092013-06-06 21:14:58 +0200465 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000466
467 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000468 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000469
470 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000471 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000472 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000473
474 end2 = *p + len;
475
476 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000477 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000478
479 /*
480 * RSAPublicKey ::= SEQUENCE {
481 * modulus INTEGER, -- n
482 * publicExponent INTEGER -- e
483 * }
484 */
485 if( ( ret = asn1_get_tag( p, end2, &len,
486 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000487 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000488
489 if( *p + len != end2 )
Paul Bakker9d781402011-05-09 16:17:09 +0000490 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000491 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000492
493 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
494 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000495 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000496
497 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000498 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000499 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000500
501 return( 0 );
502}
503
504static int x509_get_sig( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000505 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000506 x509_buf *sig )
507{
Paul Bakker23986e52011-04-24 08:57:21 +0000508 int ret;
509 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000510
Paul Bakker8afa70d2012-02-11 18:42:45 +0000511 if( ( end - *p ) < 1 )
512 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE +
513 POLARSSL_ERR_ASN1_OUT_OF_DATA );
514
Paul Bakker5121ce52009-01-03 21:22:43 +0000515 sig->tag = **p;
516
517 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000518 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000519
Paul Bakker74111d32011-01-15 16:57:55 +0000520
Paul Bakker5121ce52009-01-03 21:22:43 +0000521 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000522 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000523
524 sig->len = len;
525 sig->p = *p;
526
527 *p += len;
528
529 return( 0 );
530}
531
532/*
533 * X.509 v2/v3 unique identifier (not parsed)
534 */
535static int x509_get_uid( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000536 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000537 x509_buf *uid, int n )
538{
539 int ret;
540
541 if( *p == end )
542 return( 0 );
543
544 uid->tag = **p;
545
546 if( ( ret = asn1_get_tag( p, end, &uid->len,
547 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
548 {
Paul Bakker40e46942009-01-03 21:51:57 +0000549 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000550 return( 0 );
551
552 return( ret );
553 }
554
555 uid->p = *p;
556 *p += uid->len;
557
558 return( 0 );
559}
560
561/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000562 * X.509 Extensions (No parsing of extensions, pointer should
563 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000564 */
565static int x509_get_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000566 const unsigned char *end,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000567 x509_buf *ext, int tag )
Paul Bakker5121ce52009-01-03 21:22:43 +0000568{
Paul Bakker23986e52011-04-24 08:57:21 +0000569 int ret;
570 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000571
572 if( *p == end )
573 return( 0 );
574
575 ext->tag = **p;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000576
Paul Bakker5121ce52009-01-03 21:22:43 +0000577 if( ( ret = asn1_get_tag( p, end, &ext->len,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000578 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000579 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000580
581 ext->p = *p;
582 end = *p + ext->len;
583
584 /*
585 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
586 *
587 * Extension ::= SEQUENCE {
588 * extnID OBJECT IDENTIFIER,
589 * critical BOOLEAN DEFAULT FALSE,
590 * extnValue OCTET STRING }
591 */
592 if( ( ret = asn1_get_tag( p, end, &len,
593 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000594 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000595
596 if( end != *p + len )
Paul Bakker9d781402011-05-09 16:17:09 +0000597 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +0000598 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000599
Paul Bakkerd98030e2009-05-02 15:13:40 +0000600 return( 0 );
601}
602
603/*
604 * X.509 CRL v2 extensions (no extensions parsed yet.)
605 */
606static int x509_get_crl_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000607 const unsigned char *end,
608 x509_buf *ext )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000609{
Paul Bakker23986e52011-04-24 08:57:21 +0000610 int ret;
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000611 size_t len = 0;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000612
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000613 /* Get explicit tag */
614 if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000615 {
616 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
617 return( 0 );
618
619 return( ret );
620 }
621
622 while( *p < end )
623 {
624 if( ( ret = asn1_get_tag( p, end, &len,
625 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000626 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000627
628 *p += len;
629 }
630
631 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000632 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerd98030e2009-05-02 15:13:40 +0000633 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
634
635 return( 0 );
636}
637
Paul Bakkerb5a11ab2011-10-12 09:58:41 +0000638/*
639 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
640 */
641static int x509_get_crl_entry_ext( unsigned char **p,
642 const unsigned char *end,
643 x509_buf *ext )
644{
645 int ret;
646 size_t len = 0;
647
648 /* OPTIONAL */
649 if (end <= *p)
650 return( 0 );
651
652 ext->tag = **p;
653 ext->p = *p;
654
655 /*
656 * Get CRL-entry extension sequence header
657 * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
658 */
659 if( ( ret = asn1_get_tag( p, end, &ext->len,
660 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
661 {
662 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
663 {
664 ext->p = NULL;
665 return( 0 );
666 }
667 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
668 }
669
670 end = *p + ext->len;
671
672 if( end != *p + ext->len )
673 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
674 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
675
676 while( *p < end )
677 {
678 if( ( ret = asn1_get_tag( p, end, &len,
679 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
680 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
681
682 *p += len;
683 }
684
685 if( *p != end )
686 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
687 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
688
689 return( 0 );
690}
691
Paul Bakker74111d32011-01-15 16:57:55 +0000692static int x509_get_basic_constraints( unsigned char **p,
693 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000694 int *ca_istrue,
695 int *max_pathlen )
696{
Paul Bakker23986e52011-04-24 08:57:21 +0000697 int ret;
698 size_t len;
Paul Bakker74111d32011-01-15 16:57:55 +0000699
700 /*
701 * BasicConstraints ::= SEQUENCE {
702 * cA BOOLEAN DEFAULT FALSE,
703 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
704 */
Paul Bakker3cccddb2011-01-16 21:46:31 +0000705 *ca_istrue = 0; /* DEFAULT FALSE */
Paul Bakker74111d32011-01-15 16:57:55 +0000706 *max_pathlen = 0; /* endless */
707
708 if( ( ret = asn1_get_tag( p, end, &len,
709 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000710 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000711
712 if( *p == end )
713 return 0;
714
Paul Bakker3cccddb2011-01-16 21:46:31 +0000715 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000716 {
717 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker3cccddb2011-01-16 21:46:31 +0000718 ret = asn1_get_int( p, end, ca_istrue );
Paul Bakker74111d32011-01-15 16:57:55 +0000719
720 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000721 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000722
Paul Bakker3cccddb2011-01-16 21:46:31 +0000723 if( *ca_istrue != 0 )
724 *ca_istrue = 1;
Paul Bakker74111d32011-01-15 16:57:55 +0000725 }
726
727 if( *p == end )
728 return 0;
729
730 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000731 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000732
733 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000734 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000735 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
736
737 (*max_pathlen)++;
738
Paul Bakker74111d32011-01-15 16:57:55 +0000739 return 0;
740}
741
742static int x509_get_ns_cert_type( unsigned char **p,
743 const unsigned char *end,
744 unsigned char *ns_cert_type)
745{
746 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000747 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000748
749 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000750 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000751
752 if( bs.len != 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000753 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000754 POLARSSL_ERR_ASN1_INVALID_LENGTH );
755
756 /* Get actual bitstring */
757 *ns_cert_type = *bs.p;
758 return 0;
759}
760
761static int x509_get_key_usage( unsigned char **p,
762 const unsigned char *end,
763 unsigned char *key_usage)
764{
765 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000766 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000767
768 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000769 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000770
Paul Bakker94a67962012-08-23 13:03:52 +0000771 if( bs.len < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000772 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000773 POLARSSL_ERR_ASN1_INVALID_LENGTH );
774
775 /* Get actual bitstring */
776 *key_usage = *bs.p;
777 return 0;
778}
779
Paul Bakkerd98030e2009-05-02 15:13:40 +0000780/*
Paul Bakker74111d32011-01-15 16:57:55 +0000781 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
782 *
783 * KeyPurposeId ::= OBJECT IDENTIFIER
784 */
785static int x509_get_ext_key_usage( unsigned char **p,
786 const unsigned char *end,
787 x509_sequence *ext_key_usage)
788{
789 int ret;
790
791 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000792 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000793
794 /* Sequence length must be >= 1 */
795 if( ext_key_usage->buf.p == NULL )
Paul Bakker9d781402011-05-09 16:17:09 +0000796 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000797 POLARSSL_ERR_ASN1_INVALID_LENGTH );
798
799 return 0;
800}
801
802/*
Paul Bakkera8cd2392012-02-11 16:09:32 +0000803 * SubjectAltName ::= GeneralNames
804 *
805 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
806 *
807 * GeneralName ::= CHOICE {
808 * otherName [0] OtherName,
809 * rfc822Name [1] IA5String,
810 * dNSName [2] IA5String,
811 * x400Address [3] ORAddress,
812 * directoryName [4] Name,
813 * ediPartyName [5] EDIPartyName,
814 * uniformResourceIdentifier [6] IA5String,
815 * iPAddress [7] OCTET STRING,
816 * registeredID [8] OBJECT IDENTIFIER }
817 *
818 * OtherName ::= SEQUENCE {
819 * type-id OBJECT IDENTIFIER,
820 * value [0] EXPLICIT ANY DEFINED BY type-id }
821 *
822 * EDIPartyName ::= SEQUENCE {
823 * nameAssigner [0] DirectoryString OPTIONAL,
824 * partyName [1] DirectoryString }
825 *
826 * NOTE: PolarSSL only parses and uses dNSName at this point.
827 */
828static int x509_get_subject_alt_name( unsigned char **p,
829 const unsigned char *end,
830 x509_sequence *subject_alt_name )
831{
832 int ret;
833 size_t len, tag_len;
834 asn1_buf *buf;
835 unsigned char tag;
836 asn1_sequence *cur = subject_alt_name;
837
838 /* Get main sequence tag */
839 if( ( ret = asn1_get_tag( p, end, &len,
840 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
841 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
842
843 if( *p + len != end )
844 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
845 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
846
847 while( *p < end )
848 {
849 if( ( end - *p ) < 1 )
850 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
851 POLARSSL_ERR_ASN1_OUT_OF_DATA );
852
853 tag = **p;
854 (*p)++;
855 if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 )
856 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
857
858 if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC )
859 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
860 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
861
862 if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) )
863 {
864 *p += tag_len;
865 continue;
866 }
867
868 buf = &(cur->buf);
869 buf->tag = tag;
870 buf->p = *p;
871 buf->len = tag_len;
872 *p += buf->len;
873
874 /* Allocate and assign next pointer */
875 if (*p < end)
876 {
877 cur->next = (asn1_sequence *) malloc(
878 sizeof( asn1_sequence ) );
879
880 if( cur->next == NULL )
881 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
882 POLARSSL_ERR_ASN1_MALLOC_FAILED );
883
Paul Bakker535e97d2012-08-23 10:49:55 +0000884 memset( cur->next, 0, sizeof( asn1_sequence ) );
Paul Bakkera8cd2392012-02-11 16:09:32 +0000885 cur = cur->next;
886 }
887 }
888
889 /* Set final sequence entry's next pointer to NULL */
890 cur->next = NULL;
891
892 if( *p != end )
893 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
894 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
895
896 return( 0 );
897}
898
899/*
Paul Bakker74111d32011-01-15 16:57:55 +0000900 * X.509 v3 extensions
901 *
902 * TODO: Perform all of the basic constraints tests required by the RFC
903 * TODO: Set values for undetected extensions to a sane default?
904 *
Paul Bakkerd98030e2009-05-02 15:13:40 +0000905 */
906static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000907 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000908 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000909{
Paul Bakker23986e52011-04-24 08:57:21 +0000910 int ret;
911 size_t len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000912 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000913
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000914 if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000915 {
916 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
917 return( 0 );
918
919 return( ret );
920 }
921
Paul Bakker5121ce52009-01-03 21:22:43 +0000922 while( *p < end )
923 {
Paul Bakker74111d32011-01-15 16:57:55 +0000924 /*
925 * Extension ::= SEQUENCE {
926 * extnID OBJECT IDENTIFIER,
927 * critical BOOLEAN DEFAULT FALSE,
928 * extnValue OCTET STRING }
929 */
930 x509_buf extn_oid = {0, 0, NULL};
931 int is_critical = 0; /* DEFAULT FALSE */
932
Paul Bakker5121ce52009-01-03 21:22:43 +0000933 if( ( ret = asn1_get_tag( p, end, &len,
934 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000935 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000936
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000937 end_ext_data = *p + len;
938
Paul Bakker74111d32011-01-15 16:57:55 +0000939 /* Get extension ID */
940 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000941
Paul Bakker74111d32011-01-15 16:57:55 +0000942 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000943 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000944
Paul Bakker74111d32011-01-15 16:57:55 +0000945 extn_oid.p = *p;
946 *p += extn_oid.len;
947
948 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000949 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000950 POLARSSL_ERR_ASN1_OUT_OF_DATA );
951
952 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000953 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000954 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
Paul Bakker9d781402011-05-09 16:17:09 +0000955 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000956
Paul Bakker74111d32011-01-15 16:57:55 +0000957 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000958 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000959 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000960 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000961
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000962 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000963
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000964 if( end_ext_octet != end_ext_data )
Paul Bakker9d781402011-05-09 16:17:09 +0000965 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000966 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000967
Paul Bakker74111d32011-01-15 16:57:55 +0000968 /*
969 * Detect supported extensions
970 */
971 if( ( OID_SIZE( OID_BASIC_CONSTRAINTS ) == extn_oid.len ) &&
972 memcmp( extn_oid.p, OID_BASIC_CONSTRAINTS, extn_oid.len ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000973 {
Paul Bakker74111d32011-01-15 16:57:55 +0000974 /* Parse basic constraints */
975 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
Paul Bakker3cccddb2011-01-16 21:46:31 +0000976 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000977 return ( ret );
978 crt->ext_types |= EXT_BASIC_CONSTRAINTS;
Paul Bakker5121ce52009-01-03 21:22:43 +0000979 }
Paul Bakker74111d32011-01-15 16:57:55 +0000980 else if( ( OID_SIZE( OID_NS_CERT_TYPE ) == extn_oid.len ) &&
981 memcmp( extn_oid.p, OID_NS_CERT_TYPE, extn_oid.len ) == 0 )
982 {
983 /* Parse netscape certificate type */
984 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
985 &crt->ns_cert_type ) ) != 0 )
986 return ( ret );
987 crt->ext_types |= EXT_NS_CERT_TYPE;
988 }
989 else if( ( OID_SIZE( OID_KEY_USAGE ) == extn_oid.len ) &&
990 memcmp( extn_oid.p, OID_KEY_USAGE, extn_oid.len ) == 0 )
991 {
992 /* Parse key usage */
993 if( ( ret = x509_get_key_usage( p, end_ext_octet,
994 &crt->key_usage ) ) != 0 )
995 return ( ret );
996 crt->ext_types |= EXT_KEY_USAGE;
997 }
998 else if( ( OID_SIZE( OID_EXTENDED_KEY_USAGE ) == extn_oid.len ) &&
999 memcmp( extn_oid.p, OID_EXTENDED_KEY_USAGE, extn_oid.len ) == 0 )
1000 {
1001 /* Parse extended key usage */
1002 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
1003 &crt->ext_key_usage ) ) != 0 )
1004 return ( ret );
1005 crt->ext_types |= EXT_EXTENDED_KEY_USAGE;
1006 }
Paul Bakkera8cd2392012-02-11 16:09:32 +00001007 else if( ( OID_SIZE( OID_SUBJECT_ALT_NAME ) == extn_oid.len ) &&
1008 memcmp( extn_oid.p, OID_SUBJECT_ALT_NAME, extn_oid.len ) == 0 )
1009 {
1010 /* Parse extended key usage */
1011 if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
1012 &crt->subject_alt_names ) ) != 0 )
1013 return ( ret );
1014 crt->ext_types |= EXT_SUBJECT_ALT_NAME;
1015 }
Paul Bakker74111d32011-01-15 16:57:55 +00001016 else
1017 {
1018 /* No parser found, skip extension */
1019 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +00001020
Paul Bakker5c721f92011-07-27 16:51:09 +00001021#if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
Paul Bakker74111d32011-01-15 16:57:55 +00001022 if( is_critical )
1023 {
1024 /* Data is marked as critical: fail */
Paul Bakker9d781402011-05-09 16:17:09 +00001025 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +00001026 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
1027 }
Paul Bakker5c721f92011-07-27 16:51:09 +00001028#endif
Paul Bakker74111d32011-01-15 16:57:55 +00001029 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001030 }
1031
1032 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +00001033 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +00001034 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001035
Paul Bakker5121ce52009-01-03 21:22:43 +00001036 return( 0 );
1037}
1038
1039/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001040 * X.509 CRL Entries
1041 */
1042static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001043 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001044 x509_crl_entry *entry )
1045{
Paul Bakker23986e52011-04-24 08:57:21 +00001046 int ret;
1047 size_t entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001048 x509_crl_entry *cur_entry = entry;
1049
1050 if( *p == end )
1051 return( 0 );
1052
Paul Bakker9be19372009-07-27 20:21:53 +00001053 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001054 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1055 {
1056 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
1057 return( 0 );
1058
1059 return( ret );
1060 }
1061
Paul Bakker9be19372009-07-27 20:21:53 +00001062 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001063
1064 while( *p < end )
1065 {
Paul Bakker23986e52011-04-24 08:57:21 +00001066 size_t len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001067 const unsigned char *end2;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001068
1069 if( ( ret = asn1_get_tag( p, end, &len2,
1070 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1071 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001072 return( ret );
1073 }
1074
Paul Bakker9be19372009-07-27 20:21:53 +00001075 cur_entry->raw.tag = **p;
1076 cur_entry->raw.p = *p;
1077 cur_entry->raw.len = len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001078 end2 = *p + len2;
Paul Bakker9be19372009-07-27 20:21:53 +00001079
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001080 if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001081 return( ret );
1082
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001083 if( ( ret = x509_get_time( p, end2, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001084 return( ret );
1085
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001086 if( ( ret = x509_get_crl_entry_ext( p, end2, &cur_entry->entry_ext ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001087 return( ret );
1088
Paul Bakker74111d32011-01-15 16:57:55 +00001089 if ( *p < end )
1090 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001091 cur_entry->next = malloc( sizeof( x509_crl_entry ) );
Paul Bakkerb15b8512012-01-13 13:44:06 +00001092
1093 if( cur_entry->next == NULL )
1094 return( POLARSSL_ERR_X509_MALLOC_FAILED );
1095
Paul Bakkerd98030e2009-05-02 15:13:40 +00001096 cur_entry = cur_entry->next;
1097 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
1098 }
1099 }
1100
1101 return( 0 );
1102}
1103
Paul Bakker27d66162010-03-17 06:56:01 +00001104static int x509_get_sig_alg( const x509_buf *sig_oid, int *sig_alg )
1105{
1106 if( sig_oid->len == 9 &&
1107 memcmp( sig_oid->p, OID_PKCS1, 8 ) == 0 )
1108 {
1109 if( sig_oid->p[8] >= 2 && sig_oid->p[8] <= 5 )
1110 {
1111 *sig_alg = sig_oid->p[8];
1112 return( 0 );
1113 }
1114
1115 if ( sig_oid->p[8] >= 11 && sig_oid->p[8] <= 14 )
1116 {
1117 *sig_alg = sig_oid->p[8];
1118 return( 0 );
1119 }
1120
1121 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1122 }
Paul Bakker400ff6f2011-02-20 10:40:16 +00001123 if( sig_oid->len == 5 &&
1124 memcmp( sig_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
1125 {
1126 *sig_alg = SIG_RSA_SHA1;
1127 return( 0 );
1128 }
Paul Bakker27d66162010-03-17 06:56:01 +00001129
1130 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1131}
1132
Paul Bakkerd98030e2009-05-02 15:13:40 +00001133/*
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001134 * Parse and fill a single X.509 certificate in DER format
Paul Bakker5121ce52009-01-03 21:22:43 +00001135 */
Paul Bakkerd6d41092013-06-13 09:00:25 +02001136int x509parse_crt_der_core( x509_cert *crt, const unsigned char *buf,
1137 size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001138{
Paul Bakker23986e52011-04-24 08:57:21 +00001139 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001140 size_t len;
Paul Bakkerb00ca422012-09-25 12:10:00 +00001141 unsigned char *p, *end, *crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001142
Paul Bakker320a4b52009-03-28 18:52:39 +00001143 /*
1144 * Check for valid input
1145 */
1146 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001147 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker320a4b52009-03-28 18:52:39 +00001148
Paul Bakker96743fc2011-02-12 14:30:57 +00001149 p = (unsigned char *) malloc( len = buflen );
1150
1151 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001152 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001153
1154 memcpy( p, buf, buflen );
1155
1156 buflen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001157
1158 crt->raw.p = p;
1159 crt->raw.len = len;
1160 end = p + len;
1161
1162 /*
1163 * Certificate ::= SEQUENCE {
1164 * tbsCertificate TBSCertificate,
1165 * signatureAlgorithm AlgorithmIdentifier,
1166 * signatureValue BIT STRING }
1167 */
1168 if( ( ret = asn1_get_tag( &p, end, &len,
1169 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1170 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001171 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001172 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001173 }
1174
Paul Bakkerb00ca422012-09-25 12:10:00 +00001175 if( len > (size_t) ( end - p ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001176 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001177 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001178 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001179 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001180 }
Paul Bakkerb00ca422012-09-25 12:10:00 +00001181 crt_end = p + len;
Paul Bakkerd6d41092013-06-13 09:00:25 +02001182
Paul Bakker5121ce52009-01-03 21:22:43 +00001183 /*
1184 * TBSCertificate ::= SEQUENCE {
1185 */
1186 crt->tbs.p = p;
1187
1188 if( ( ret = asn1_get_tag( &p, end, &len,
1189 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1190 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001191 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001192 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001193 }
1194
1195 end = p + len;
1196 crt->tbs.len = end - crt->tbs.p;
1197
1198 /*
1199 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1200 *
1201 * CertificateSerialNumber ::= INTEGER
1202 *
1203 * signature AlgorithmIdentifier
1204 */
1205 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1206 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1207 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
1208 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001209 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001210 return( ret );
1211 }
1212
1213 crt->version++;
1214
1215 if( crt->version > 3 )
1216 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001217 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001218 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001219 }
1220
Paul Bakker27d66162010-03-17 06:56:01 +00001221 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_alg ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001222 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001223 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001224 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001225 }
1226
1227 /*
1228 * issuer Name
1229 */
1230 crt->issuer_raw.p = p;
1231
1232 if( ( ret = asn1_get_tag( &p, end, &len,
1233 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1234 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001235 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001236 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001237 }
1238
1239 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1240 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001241 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001242 return( ret );
1243 }
1244
1245 crt->issuer_raw.len = p - crt->issuer_raw.p;
1246
1247 /*
1248 * Validity ::= SEQUENCE {
1249 * notBefore Time,
1250 * notAfter Time }
1251 *
1252 */
1253 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1254 &crt->valid_to ) ) != 0 )
1255 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001256 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001257 return( ret );
1258 }
1259
1260 /*
1261 * subject Name
1262 */
1263 crt->subject_raw.p = p;
1264
1265 if( ( ret = asn1_get_tag( &p, end, &len,
1266 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1267 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001268 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001269 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001270 }
1271
Paul Bakkercefb3962012-06-27 11:51:09 +00001272 if( len && ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001273 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001274 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001275 return( ret );
1276 }
1277
1278 crt->subject_raw.len = p - crt->subject_raw.p;
1279
1280 /*
1281 * SubjectPublicKeyInfo ::= SEQUENCE
1282 * algorithm AlgorithmIdentifier,
1283 * subjectPublicKey BIT STRING }
1284 */
1285 if( ( ret = asn1_get_tag( &p, end, &len,
1286 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1287 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001288 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001289 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001290 }
1291
1292 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1293 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1294 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001295 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001296 return( ret );
1297 }
1298
1299 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1300 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001301 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001302 return( ret );
1303 }
1304
1305 crt->rsa.len = mpi_size( &crt->rsa.N );
1306
1307 /*
1308 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1309 * -- If present, version shall be v2 or v3
1310 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1311 * -- If present, version shall be v2 or v3
1312 * extensions [3] EXPLICIT Extensions OPTIONAL
1313 * -- If present, version shall be v3
1314 */
1315 if( crt->version == 2 || crt->version == 3 )
1316 {
1317 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1318 if( ret != 0 )
1319 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001320 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001321 return( ret );
1322 }
1323 }
1324
1325 if( crt->version == 2 || crt->version == 3 )
1326 {
1327 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1328 if( ret != 0 )
1329 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001330 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001331 return( ret );
1332 }
1333 }
1334
1335 if( crt->version == 3 )
1336 {
Paul Bakker74111d32011-01-15 16:57:55 +00001337 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001338 if( ret != 0 )
1339 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001340 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001341 return( ret );
1342 }
1343 }
1344
1345 if( p != end )
1346 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001347 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001348 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001349 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001350 }
1351
Paul Bakkerb00ca422012-09-25 12:10:00 +00001352 end = crt_end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001353
1354 /*
1355 * signatureAlgorithm AlgorithmIdentifier,
1356 * signatureValue BIT STRING
1357 */
1358 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1359 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001360 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001361 return( ret );
1362 }
1363
Paul Bakker535e97d2012-08-23 10:49:55 +00001364 if( crt->sig_oid1.len != crt->sig_oid2.len ||
1365 memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001366 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001367 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001368 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001369 }
1370
1371 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1372 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001373 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001374 return( ret );
1375 }
1376
1377 if( p != end )
1378 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001379 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001380 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001381 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001382 }
1383
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001384 return( 0 );
1385}
1386
1387/*
Paul Bakkerd6d41092013-06-13 09:00:25 +02001388 * Parse one X.509 certificate in DER format from a buffer and add them to a
1389 * chained list
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001390 */
Paul Bakkerd6d41092013-06-13 09:00:25 +02001391int x509parse_crt_der( x509_cert *chain, const unsigned char *buf, size_t buflen )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001392{
Paul Bakkerd6d41092013-06-13 09:00:25 +02001393 int ret;
1394 x509_cert *crt = chain, *prev = NULL;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001395
1396 /*
1397 * Check for valid input
1398 */
1399 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001400 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001401
1402 while( crt->version != 0 && crt->next != NULL )
1403 {
1404 prev = crt;
1405 crt = crt->next;
1406 }
1407
1408 /*
1409 * Add new certificate on the end of the chain if needed.
1410 */
1411 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001412 {
1413 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1414
Paul Bakker7d06ad22009-05-02 15:53:56 +00001415 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001416 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker320a4b52009-03-28 18:52:39 +00001417
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001418 prev = crt;
Paul Bakker7d06ad22009-05-02 15:53:56 +00001419 crt = crt->next;
1420 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001421 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001422
Paul Bakkerd6d41092013-06-13 09:00:25 +02001423 if( ( ret = x509parse_crt_der_core( crt, buf, buflen ) ) != 0 )
1424 {
1425 if( prev )
1426 prev->next = NULL;
1427
1428 if( crt != chain )
1429 free( crt );
1430
1431 return( ret );
1432 }
1433
1434 return( 0 );
1435}
1436
1437/*
1438 * Parse one or more PEM certificates from a buffer and add them to the chained list
1439 */
1440int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
1441{
1442 int ret, success = 0, first_error = 0, total_failed = 0;
1443 int buf_format = X509_FORMAT_DER;
1444
1445 /*
1446 * Check for valid input
1447 */
1448 if( chain == NULL || buf == NULL )
1449 return( POLARSSL_ERR_X509_INVALID_INPUT );
1450
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001451 /*
1452 * Determine buffer content. Buffer contains either one DER certificate or
1453 * one or more PEM certificates.
1454 */
1455#if defined(POLARSSL_PEM_C)
Paul Bakkereae09db2013-06-06 12:35:54 +02001456 if( strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001457 buf_format = X509_FORMAT_PEM;
1458#endif
1459
1460 if( buf_format == X509_FORMAT_DER )
Paul Bakkerd6d41092013-06-13 09:00:25 +02001461 return x509parse_crt_der( chain, buf, buflen );
1462
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001463#if defined(POLARSSL_PEM_C)
1464 if( buf_format == X509_FORMAT_PEM )
1465 {
1466 pem_context pem;
1467
1468 while( buflen > 0 )
1469 {
1470 size_t use_len;
1471 pem_init( &pem );
1472
1473 ret = pem_read_buffer( &pem,
1474 "-----BEGIN CERTIFICATE-----",
1475 "-----END CERTIFICATE-----",
1476 buf, NULL, 0, &use_len );
1477
1478 if( ret == 0 )
1479 {
1480 /*
1481 * Was PEM encoded
1482 */
1483 buflen -= use_len;
1484 buf += use_len;
1485 }
Paul Bakker64171862013-06-06 15:01:18 +02001486 else if( ret == POLARSSL_ERR_PEM_BAD_INPUT_DATA )
1487 {
1488 return( ret );
1489 }
Paul Bakker9255e832013-06-06 14:58:28 +02001490 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001491 {
1492 pem_free( &pem );
1493
Paul Bakker64171862013-06-06 15:01:18 +02001494 /*
1495 * PEM header and footer were found
1496 */
1497 buflen -= use_len;
1498 buf += use_len;
1499
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001500 if( first_error == 0 )
1501 first_error = ret;
1502
1503 continue;
1504 }
1505 else
1506 break;
1507
Paul Bakkerd6d41092013-06-13 09:00:25 +02001508 ret = x509parse_crt_der( chain, pem.buf, pem.buflen );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001509
1510 pem_free( &pem );
1511
1512 if( ret != 0 )
1513 {
1514 /*
Paul Bakkerd6d41092013-06-13 09:00:25 +02001515 * Quit parsing on a memory error
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001516 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001517 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001518 return( ret );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001519
1520 if( first_error == 0 )
1521 first_error = ret;
1522
Paul Bakkerd6d41092013-06-13 09:00:25 +02001523 total_failed++;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001524 continue;
1525 }
1526
1527 success = 1;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001528 }
1529 }
1530#endif
1531
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001532 if( success )
Paul Bakker69e095c2011-12-10 21:55:01 +00001533 return( total_failed );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001534 else if( first_error )
1535 return( first_error );
1536 else
1537 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001538}
1539
1540/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001541 * Parse one or more CRLs and add them to the chained list
1542 */
Paul Bakker23986e52011-04-24 08:57:21 +00001543int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001544{
Paul Bakker23986e52011-04-24 08:57:21 +00001545 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001546 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001547 unsigned char *p, *end;
1548 x509_crl *crl;
Paul Bakker96743fc2011-02-12 14:30:57 +00001549#if defined(POLARSSL_PEM_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00001550 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001551 pem_context pem;
1552#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001553
1554 crl = chain;
1555
1556 /*
1557 * Check for valid input
1558 */
1559 if( crl == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001560 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001561
1562 while( crl->version != 0 && crl->next != NULL )
1563 crl = crl->next;
1564
1565 /*
1566 * Add new CRL on the end of the chain if needed.
1567 */
1568 if ( crl->version != 0 && crl->next == NULL)
1569 {
1570 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1571
Paul Bakker7d06ad22009-05-02 15:53:56 +00001572 if( crl->next == NULL )
1573 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001574 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001575 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001576 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001577
Paul Bakker7d06ad22009-05-02 15:53:56 +00001578 crl = crl->next;
1579 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001580 }
1581
Paul Bakker96743fc2011-02-12 14:30:57 +00001582#if defined(POLARSSL_PEM_C)
1583 pem_init( &pem );
1584 ret = pem_read_buffer( &pem,
1585 "-----BEGIN X509 CRL-----",
1586 "-----END X509 CRL-----",
1587 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001588
Paul Bakker96743fc2011-02-12 14:30:57 +00001589 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001590 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001591 /*
1592 * Was PEM encoded
1593 */
1594 buflen -= use_len;
1595 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001596
1597 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001598 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001599 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001600 p = pem.buf;
1601 pem.buf = NULL;
1602 len = pem.buflen;
1603 pem_free( &pem );
1604 }
Paul Bakker9255e832013-06-06 14:58:28 +02001605 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker96743fc2011-02-12 14:30:57 +00001606 {
1607 pem_free( &pem );
1608 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001609 }
1610 else
1611 {
1612 /*
1613 * nope, copy the raw DER data
1614 */
1615 p = (unsigned char *) malloc( len = buflen );
1616
1617 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001618 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001619
1620 memcpy( p, buf, buflen );
1621
1622 buflen = 0;
1623 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001624#else
1625 p = (unsigned char *) malloc( len = buflen );
1626
1627 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001628 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001629
1630 memcpy( p, buf, buflen );
1631
1632 buflen = 0;
1633#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001634
1635 crl->raw.p = p;
1636 crl->raw.len = len;
1637 end = p + len;
1638
1639 /*
1640 * CertificateList ::= SEQUENCE {
1641 * tbsCertList TBSCertList,
1642 * signatureAlgorithm AlgorithmIdentifier,
1643 * signatureValue BIT STRING }
1644 */
1645 if( ( ret = asn1_get_tag( &p, end, &len,
1646 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1647 {
1648 x509_crl_free( crl );
1649 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1650 }
1651
Paul Bakker23986e52011-04-24 08:57:21 +00001652 if( len != (size_t) ( end - p ) )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001653 {
1654 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001655 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001656 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1657 }
1658
1659 /*
1660 * TBSCertList ::= SEQUENCE {
1661 */
1662 crl->tbs.p = p;
1663
1664 if( ( ret = asn1_get_tag( &p, end, &len,
1665 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1666 {
1667 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001668 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001669 }
1670
1671 end = p + len;
1672 crl->tbs.len = end - crl->tbs.p;
1673
1674 /*
1675 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1676 * -- if present, MUST be v2
1677 *
1678 * signature AlgorithmIdentifier
1679 */
Paul Bakker3329d1f2011-10-12 09:55:01 +00001680 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
Paul Bakkerd98030e2009-05-02 15:13:40 +00001681 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1682 {
1683 x509_crl_free( crl );
1684 return( ret );
1685 }
1686
1687 crl->version++;
1688
1689 if( crl->version > 2 )
1690 {
1691 x509_crl_free( crl );
1692 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1693 }
1694
Paul Bakker27d66162010-03-17 06:56:01 +00001695 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_alg ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001696 {
1697 x509_crl_free( crl );
1698 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1699 }
1700
1701 /*
1702 * issuer Name
1703 */
1704 crl->issuer_raw.p = p;
1705
1706 if( ( ret = asn1_get_tag( &p, end, &len,
1707 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1708 {
1709 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001710 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001711 }
1712
1713 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1714 {
1715 x509_crl_free( crl );
1716 return( ret );
1717 }
1718
1719 crl->issuer_raw.len = p - crl->issuer_raw.p;
1720
1721 /*
1722 * thisUpdate Time
1723 * nextUpdate Time OPTIONAL
1724 */
Paul Bakker91200182010-02-18 21:26:15 +00001725 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001726 {
1727 x509_crl_free( crl );
1728 return( ret );
1729 }
1730
Paul Bakker91200182010-02-18 21:26:15 +00001731 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001732 {
Paul Bakker9d781402011-05-09 16:17:09 +00001733 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001734 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker9d781402011-05-09 16:17:09 +00001735 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001736 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001737 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001738 x509_crl_free( crl );
1739 return( ret );
1740 }
1741 }
1742
1743 /*
1744 * revokedCertificates SEQUENCE OF SEQUENCE {
1745 * userCertificate CertificateSerialNumber,
1746 * revocationDate Time,
1747 * crlEntryExtensions Extensions OPTIONAL
1748 * -- if present, MUST be v2
1749 * } OPTIONAL
1750 */
1751 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1752 {
1753 x509_crl_free( crl );
1754 return( ret );
1755 }
1756
1757 /*
1758 * crlExtensions EXPLICIT Extensions OPTIONAL
1759 * -- if present, MUST be v2
1760 */
1761 if( crl->version == 2 )
1762 {
1763 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1764
1765 if( ret != 0 )
1766 {
1767 x509_crl_free( crl );
1768 return( ret );
1769 }
1770 }
1771
1772 if( p != end )
1773 {
1774 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001775 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001776 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1777 }
1778
1779 end = crl->raw.p + crl->raw.len;
1780
1781 /*
1782 * signatureAlgorithm AlgorithmIdentifier,
1783 * signatureValue BIT STRING
1784 */
1785 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1786 {
1787 x509_crl_free( crl );
1788 return( ret );
1789 }
1790
Paul Bakker535e97d2012-08-23 10:49:55 +00001791 if( crl->sig_oid1.len != crl->sig_oid2.len ||
1792 memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001793 {
1794 x509_crl_free( crl );
1795 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1796 }
1797
1798 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1799 {
1800 x509_crl_free( crl );
1801 return( ret );
1802 }
1803
1804 if( p != end )
1805 {
1806 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001807 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001808 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1809 }
1810
1811 if( buflen > 0 )
1812 {
1813 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1814
Paul Bakker7d06ad22009-05-02 15:53:56 +00001815 if( crl->next == NULL )
1816 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001817 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001818 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001819 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001820
Paul Bakker7d06ad22009-05-02 15:53:56 +00001821 crl = crl->next;
1822 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001823
1824 return( x509parse_crl( crl, buf, buflen ) );
1825 }
1826
1827 return( 0 );
1828}
1829
Paul Bakker335db3f2011-04-25 15:28:35 +00001830#if defined(POLARSSL_FS_IO)
Paul Bakkerd98030e2009-05-02 15:13:40 +00001831/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001832 * Load all data from a file into a given buffer.
1833 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001834int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001835{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001836 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001837
Paul Bakkerd98030e2009-05-02 15:13:40 +00001838 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001839 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001840
Paul Bakkerd98030e2009-05-02 15:13:40 +00001841 fseek( f, 0, SEEK_END );
1842 *n = (size_t) ftell( f );
1843 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001844
Paul Bakkerd98030e2009-05-02 15:13:40 +00001845 if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001846 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001847
Paul Bakkerd98030e2009-05-02 15:13:40 +00001848 if( fread( *buf, 1, *n, f ) != *n )
1849 {
1850 fclose( f );
1851 free( *buf );
Paul Bakker69e095c2011-12-10 21:55:01 +00001852 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001853 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001854
Paul Bakkerd98030e2009-05-02 15:13:40 +00001855 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001856
Paul Bakkerd98030e2009-05-02 15:13:40 +00001857 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001858
Paul Bakkerd98030e2009-05-02 15:13:40 +00001859 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001860}
1861
1862/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001863 * Load one or more certificates and add them to the chained list
1864 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001865int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001866{
1867 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001868 size_t n;
1869 unsigned char *buf;
1870
Paul Bakker69e095c2011-12-10 21:55:01 +00001871 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1872 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001873
Paul Bakker69e095c2011-12-10 21:55:01 +00001874 ret = x509parse_crt( chain, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001875
1876 memset( buf, 0, n + 1 );
1877 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001878
1879 return( ret );
1880}
1881
Paul Bakker8d914582012-06-04 12:46:42 +00001882int x509parse_crtpath( x509_cert *chain, const char *path )
1883{
1884 int ret = 0;
1885#if defined(_WIN32)
Paul Bakker3338b792012-10-01 21:13:10 +00001886 int w_ret;
1887 WCHAR szDir[MAX_PATH];
1888 char filename[MAX_PATH];
1889 char *p;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001890 int len = strlen( path );
Paul Bakker3338b792012-10-01 21:13:10 +00001891
Paul Bakker97872ac2012-11-02 12:53:26 +00001892 WIN32_FIND_DATAW file_data;
Paul Bakker8d914582012-06-04 12:46:42 +00001893 HANDLE hFind;
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001894
1895 if( len > MAX_PATH - 3 )
1896 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker8d914582012-06-04 12:46:42 +00001897
Paul Bakker3338b792012-10-01 21:13:10 +00001898 memset( szDir, 0, sizeof(szDir) );
1899 memset( filename, 0, MAX_PATH );
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001900 memcpy( filename, path, len );
1901 filename[len++] = '\\';
1902 p = filename + len;
1903 filename[len++] = '*';
Paul Bakker3338b792012-10-01 21:13:10 +00001904
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001905 w_ret = MultiByteToWideChar( CP_ACP, 0, path, len, szDir, MAX_PATH - 3 );
Paul Bakker8d914582012-06-04 12:46:42 +00001906
Paul Bakker97872ac2012-11-02 12:53:26 +00001907 hFind = FindFirstFileW( szDir, &file_data );
Paul Bakker8d914582012-06-04 12:46:42 +00001908 if (hFind == INVALID_HANDLE_VALUE)
1909 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1910
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001911 len = MAX_PATH - len;
Paul Bakker8d914582012-06-04 12:46:42 +00001912 do
1913 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001914 memset( p, 0, len );
Paul Bakker3338b792012-10-01 21:13:10 +00001915
Paul Bakkere4791f32012-06-04 21:29:15 +00001916 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
Paul Bakker8d914582012-06-04 12:46:42 +00001917 continue;
1918
Paul Bakker3338b792012-10-01 21:13:10 +00001919 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
1920 lstrlenW(file_data.cFileName),
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001921 p, len - 1,
1922 NULL, NULL );
Paul Bakker8d914582012-06-04 12:46:42 +00001923
Paul Bakker3338b792012-10-01 21:13:10 +00001924 w_ret = x509parse_crtfile( chain, filename );
1925 if( w_ret < 0 )
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001926 ret++;
1927 else
1928 ret += w_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001929 }
Paul Bakker97872ac2012-11-02 12:53:26 +00001930 while( FindNextFileW( hFind, &file_data ) != 0 );
Paul Bakker8d914582012-06-04 12:46:42 +00001931
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001932 if (GetLastError() != ERROR_NO_MORE_FILES)
1933 ret = POLARSSL_ERR_X509_FILE_IO_ERROR;
Paul Bakker8d914582012-06-04 12:46:42 +00001934
Paul Bakker4a2bd0d2012-11-02 11:06:08 +00001935cleanup:
Paul Bakker8d914582012-06-04 12:46:42 +00001936 FindClose( hFind );
1937#else
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001938 int t_ret, i;
1939 struct stat sb;
1940 struct dirent entry, *result = NULL;
Paul Bakker8d914582012-06-04 12:46:42 +00001941 char entry_name[255];
1942 DIR *dir = opendir( path );
1943
1944 if( dir == NULL)
1945 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1946
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001947 while( ( t_ret = readdir_r( dir, &entry, &result ) ) == 0 )
Paul Bakker8d914582012-06-04 12:46:42 +00001948 {
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001949 if( result == NULL )
1950 break;
1951
1952 snprintf( entry_name, sizeof(entry_name), "%s/%s", path, entry.d_name );
1953
1954 i = stat( entry_name, &sb );
1955
1956 if( i == -1 )
1957 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1958
1959 if( !S_ISREG( sb.st_mode ) )
Paul Bakker8d914582012-06-04 12:46:42 +00001960 continue;
1961
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001962 // Ignore parse errors
1963 //
Paul Bakker8d914582012-06-04 12:46:42 +00001964 t_ret = x509parse_crtfile( chain, entry_name );
1965 if( t_ret < 0 )
Paul Bakkercbfcaa92013-06-13 09:20:25 +02001966 ret++;
1967 else
1968 ret += t_ret;
Paul Bakker8d914582012-06-04 12:46:42 +00001969 }
1970 closedir( dir );
1971#endif
1972
1973 return( ret );
1974}
1975
Paul Bakkerd98030e2009-05-02 15:13:40 +00001976/*
1977 * Load one or more CRLs and add them to the chained list
1978 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001979int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001980{
1981 int ret;
1982 size_t n;
1983 unsigned char *buf;
1984
Paul Bakker69e095c2011-12-10 21:55:01 +00001985 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1986 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001987
Paul Bakker27fdf462011-06-09 13:55:13 +00001988 ret = x509parse_crl( chain, buf, n );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001989
1990 memset( buf, 0, n + 1 );
1991 free( buf );
1992
1993 return( ret );
1994}
1995
Paul Bakker5121ce52009-01-03 21:22:43 +00001996/*
Paul Bakker335db3f2011-04-25 15:28:35 +00001997 * Load and parse a private RSA key
1998 */
1999int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
2000{
2001 int ret;
2002 size_t n;
2003 unsigned char *buf;
2004
Paul Bakker69e095c2011-12-10 21:55:01 +00002005 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2006 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002007
2008 if( pwd == NULL )
Paul Bakker27fdf462011-06-09 13:55:13 +00002009 ret = x509parse_key( rsa, buf, n, NULL, 0 );
Paul Bakker335db3f2011-04-25 15:28:35 +00002010 else
Paul Bakker27fdf462011-06-09 13:55:13 +00002011 ret = x509parse_key( rsa, buf, n,
Paul Bakker335db3f2011-04-25 15:28:35 +00002012 (unsigned char *) pwd, strlen( pwd ) );
2013
2014 memset( buf, 0, n + 1 );
2015 free( buf );
2016
2017 return( ret );
2018}
2019
2020/*
2021 * Load and parse a public RSA key
2022 */
2023int x509parse_public_keyfile( rsa_context *rsa, const char *path )
2024{
2025 int ret;
2026 size_t n;
2027 unsigned char *buf;
2028
Paul Bakker69e095c2011-12-10 21:55:01 +00002029 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
2030 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00002031
Paul Bakker27fdf462011-06-09 13:55:13 +00002032 ret = x509parse_public_key( rsa, buf, n );
Paul Bakker335db3f2011-04-25 15:28:35 +00002033
2034 memset( buf, 0, n + 1 );
2035 free( buf );
2036
2037 return( ret );
2038}
2039#endif /* POLARSSL_FS_IO */
2040
2041/*
Paul Bakker65a19092013-06-06 21:14:58 +02002042 * Parse a PKCS#1 encoded private RSA key
Paul Bakker5121ce52009-01-03 21:22:43 +00002043 */
Paul Bakker65a19092013-06-06 21:14:58 +02002044static int x509parse_key_pkcs1_der( rsa_context *rsa,
2045 const unsigned char *key,
2046 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +00002047{
Paul Bakker23986e52011-04-24 08:57:21 +00002048 int ret;
2049 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00002050 unsigned char *p, *end;
Paul Bakkered56b222011-07-13 11:26:43 +00002051
Paul Bakker96743fc2011-02-12 14:30:57 +00002052 p = (unsigned char *) key;
Paul Bakker96743fc2011-02-12 14:30:57 +00002053 end = p + keylen;
2054
Paul Bakker5121ce52009-01-03 21:22:43 +00002055 /*
Paul Bakker65a19092013-06-06 21:14:58 +02002056 * This function parses the RSAPrivateKey (PKCS#1)
Paul Bakkered56b222011-07-13 11:26:43 +00002057 *
Paul Bakker5121ce52009-01-03 21:22:43 +00002058 * RSAPrivateKey ::= SEQUENCE {
2059 * version Version,
2060 * modulus INTEGER, -- n
2061 * publicExponent INTEGER, -- e
2062 * privateExponent INTEGER, -- d
2063 * prime1 INTEGER, -- p
2064 * prime2 INTEGER, -- q
2065 * exponent1 INTEGER, -- d mod (p-1)
2066 * exponent2 INTEGER, -- d mod (q-1)
2067 * coefficient INTEGER, -- (inverse of q) mod p
2068 * otherPrimeInfos OtherPrimeInfos OPTIONAL
2069 * }
2070 */
2071 if( ( ret = asn1_get_tag( &p, end, &len,
2072 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2073 {
Paul Bakker9d781402011-05-09 16:17:09 +00002074 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002075 }
2076
2077 end = p + len;
2078
2079 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2080 {
Paul Bakker9d781402011-05-09 16:17:09 +00002081 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002082 }
2083
2084 if( rsa->ver != 0 )
2085 {
Paul Bakker9d781402011-05-09 16:17:09 +00002086 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002087 }
2088
2089 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
2090 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
2091 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
2092 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
2093 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
2094 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
2095 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
2096 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
2097 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002098 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002099 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002100 }
2101
2102 rsa->len = mpi_size( &rsa->N );
2103
2104 if( p != end )
2105 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002106 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002107 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00002108 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002109 }
2110
2111 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2112 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002113 rsa_free( rsa );
2114 return( ret );
2115 }
2116
Paul Bakker65a19092013-06-06 21:14:58 +02002117 return( 0 );
2118}
2119
2120/*
2121 * Parse an unencrypted PKCS#8 encoded private RSA key
2122 */
2123static int x509parse_key_pkcs8_unencrypted_der(
2124 rsa_context *rsa,
2125 const unsigned char *key,
2126 size_t keylen )
2127{
2128 int ret;
2129 size_t len;
2130 unsigned char *p, *end;
2131 x509_buf pk_alg_oid;
2132
2133 p = (unsigned char *) key;
2134 end = p + keylen;
2135
2136 /*
2137 * This function parses the PrivatKeyInfo object (PKCS#8)
2138 *
2139 * PrivateKeyInfo ::= SEQUENCE {
2140 * version Version,
2141 * algorithm AlgorithmIdentifier,
2142 * PrivateKey BIT STRING
2143 * }
2144 *
2145 * AlgorithmIdentifier ::= SEQUENCE {
2146 * algorithm OBJECT IDENTIFIER,
2147 * parameters ANY DEFINED BY algorithm OPTIONAL
2148 * }
2149 *
2150 * The PrivateKey BIT STRING is a PKCS#1 RSAPrivateKey
2151 */
2152 if( ( ret = asn1_get_tag( &p, end, &len,
2153 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2154 {
2155 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2156 }
2157
2158 end = p + len;
2159
2160 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2161 {
2162 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2163 }
2164
2165 if( rsa->ver != 0 )
2166 {
2167 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2168 }
2169
2170 if( ( ret = x509_get_alg( &p, end, &pk_alg_oid ) ) != 0 )
2171 {
2172 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2173 }
2174
2175 /*
2176 * only RSA keys handled at this time
2177 */
2178 if( pk_alg_oid.len != 9 ||
2179 memcmp( pk_alg_oid.p, OID_PKCS1_RSA, 9 ) != 0 )
2180 {
2181 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
2182 }
2183
2184 /*
2185 * Get the OCTET STRING and parse the PKCS#1 format inside
2186 */
2187 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2188 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2189
2190 if( ( end - p ) < 1 )
2191 {
2192 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
2193 POLARSSL_ERR_ASN1_OUT_OF_DATA );
2194 }
2195
2196 end = p + len;
2197
2198 if( ( ret = x509parse_key_pkcs1_der( rsa, p, end - p ) ) != 0 )
2199 return( ret );
2200
2201 return( 0 );
2202}
2203
2204/*
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002205 * Parse an unencrypted PKCS#8 encoded private RSA key
2206 */
2207static int x509parse_key_pkcs8_encrypted_der(
2208 rsa_context *rsa,
2209 const unsigned char *key,
2210 size_t keylen,
2211 const unsigned char *pwd,
2212 size_t pwdlen )
2213{
2214 int ret;
2215 size_t len;
2216 unsigned char *p, *end, *end2;
2217 x509_buf pbe_alg_oid, pbe_params;
2218 unsigned char buf[2048];
2219
2220 memset(buf, 0, 2048);
2221
2222 p = (unsigned char *) key;
2223 end = p + keylen;
2224
Paul Bakker1fd43212013-06-17 15:14:42 +02002225 if( pwdlen == 0 )
2226 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
2227
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002228 /*
2229 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
2230 *
2231 * EncryptedPrivateKeyInfo ::= SEQUENCE {
2232 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
2233 * encryptedData EncryptedData
2234 * }
2235 *
2236 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
2237 *
2238 * EncryptedData ::= OCTET STRING
2239 *
2240 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
2241 */
2242 if( ( ret = asn1_get_tag( &p, end, &len,
2243 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2244 {
2245 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2246 }
2247
2248 end = p + len;
2249
2250 if( ( ret = asn1_get_tag( &p, end, &len,
2251 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2252 {
2253 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2254 }
2255
2256 end2 = p + len;
2257
2258 if( ( ret = asn1_get_tag( &p, end, &pbe_alg_oid.len, ASN1_OID ) ) != 0 )
2259 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2260
2261 pbe_alg_oid.p = p;
2262 p += pbe_alg_oid.len;
2263
2264 /*
2265 * Store the algorithm parameters
2266 */
2267 pbe_params.p = p;
2268 pbe_params.len = end2 - p;
2269 p += pbe_params.len;
2270
2271 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2272 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2273
2274 // buf has been sized to 2048 bytes
2275 if( len > 2048 )
2276 return( POLARSSL_ERR_X509_INVALID_INPUT );
2277
2278 /*
2279 * Decrypt EncryptedData with appropriate PDE
2280 */
2281 if( OID_CMP( OID_PKCS12_PBE_SHA1_DES3_EDE_CBC, &pbe_alg_oid ) )
2282 {
2283 if( ( ret = pkcs12_pbe_sha1_des3_ede_cbc( &pbe_params,
2284 PKCS12_PBE_DECRYPT,
2285 pwd, pwdlen,
2286 p, len, buf ) ) != 0 )
2287 {
2288 return( ret );
2289 }
2290 }
2291 else if( OID_CMP( OID_PKCS12_PBE_SHA1_DES2_EDE_CBC, &pbe_alg_oid ) )
2292 {
2293 if( ( ret = pkcs12_pbe_sha1_des2_ede_cbc( &pbe_params,
2294 PKCS12_PBE_DECRYPT,
2295 pwd, pwdlen,
2296 p, len, buf ) ) != 0 )
2297 {
2298 return( ret );
2299 }
2300 }
2301 else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) )
2302 {
2303 if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params,
2304 PKCS12_PBE_DECRYPT,
2305 pwd, pwdlen,
2306 p, len, buf ) ) != 0 )
2307 {
2308 return( ret );
2309 }
2310 }
Paul Bakker1fd43212013-06-17 15:14:42 +02002311#if defined(POLARSSL_PKCS5_C)
2312 else if( OID_CMP( OID_PKCS5_PBES2, &pbe_alg_oid ) )
2313 {
2314 if( ( ret = pkcs5_pbes2( &pbe_params, PKCS5_DECRYPT, pwd, pwdlen,
2315 p, len, buf ) ) != 0 )
2316 {
2317 if( ret == POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH )
2318 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2319
2320 return( ret );
2321 }
2322 }
2323#endif /* POLARSSL_PKCS5_C */
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002324 else
2325 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
2326
2327 return x509parse_key_pkcs8_unencrypted_der( rsa, buf, len );
2328}
2329
2330/*
Paul Bakker65a19092013-06-06 21:14:58 +02002331 * Parse a private RSA key
2332 */
2333int x509parse_key( rsa_context *rsa, const unsigned char *key, size_t keylen,
2334 const unsigned char *pwd, size_t pwdlen )
2335{
2336 int ret;
2337
Paul Bakker96743fc2011-02-12 14:30:57 +00002338#if defined(POLARSSL_PEM_C)
Paul Bakker65a19092013-06-06 21:14:58 +02002339 size_t len;
2340 pem_context pem;
2341
2342 pem_init( &pem );
2343 ret = pem_read_buffer( &pem,
2344 "-----BEGIN RSA PRIVATE KEY-----",
2345 "-----END RSA PRIVATE KEY-----",
2346 key, pwd, pwdlen, &len );
2347 if( ret == 0 )
2348 {
2349 if( ( ret = x509parse_key_pkcs1_der( rsa, pem.buf, pem.buflen ) ) != 0 )
2350 {
2351 rsa_free( rsa );
2352 }
2353
2354 pem_free( &pem );
2355 return( ret );
2356 }
Paul Bakkerb495d3a2013-06-17 15:58:04 +02002357 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
2358 return( POLARSSL_ERR_X509_PASSWORD_MISMATCH );
2359 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
2360 return( POLARSSL_ERR_X509_PASSWORD_REQUIRED );
Paul Bakker65a19092013-06-06 21:14:58 +02002361 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker65a19092013-06-06 21:14:58 +02002362 return( ret );
Paul Bakker65a19092013-06-06 21:14:58 +02002363
2364 ret = pem_read_buffer( &pem,
2365 "-----BEGIN PRIVATE KEY-----",
2366 "-----END PRIVATE KEY-----",
2367 key, NULL, 0, &len );
2368 if( ret == 0 )
2369 {
2370 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa,
2371 pem.buf, pem.buflen ) ) != 0 )
2372 {
2373 rsa_free( rsa );
2374 }
2375
2376 pem_free( &pem );
2377 return( ret );
2378 }
2379 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker65a19092013-06-06 21:14:58 +02002380 return( ret );
Paul Bakker65a19092013-06-06 21:14:58 +02002381
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002382 ret = pem_read_buffer( &pem,
2383 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
2384 "-----END ENCRYPTED PRIVATE KEY-----",
2385 key, NULL, 0, &len );
2386 if( ret == 0 )
2387 {
2388 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa,
2389 pem.buf, pem.buflen,
2390 pwd, pwdlen ) ) != 0 )
2391 {
2392 rsa_free( rsa );
2393 }
2394
2395 pem_free( &pem );
2396 return( ret );
2397 }
2398 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002399 return( ret );
Paul Bakker65a19092013-06-06 21:14:58 +02002400#else
2401 ((void) pwd);
2402 ((void) pwdlen);
2403#endif /* POLARSSL_PEM_C */
2404
2405 // At this point we only know it's not a PEM formatted key. Could be any
2406 // of the known DER encoded private key formats
2407 //
2408 // We try the different DER format parsers to see if one passes without
2409 // error
2410 //
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002411 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa, key, keylen,
2412 pwd, pwdlen ) ) == 0 )
Paul Bakker65a19092013-06-06 21:14:58 +02002413 {
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002414 return( 0 );
Paul Bakker65a19092013-06-06 21:14:58 +02002415 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002416
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002417 rsa_free( rsa );
Paul Bakker1fd43212013-06-17 15:14:42 +02002418
2419 if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH )
2420 {
2421 return( ret );
2422 }
2423
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002424 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa, key, keylen ) ) == 0 )
2425 return( 0 );
2426
2427 rsa_free( rsa );
Paul Bakker1fd43212013-06-17 15:14:42 +02002428
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002429 if( ( ret = x509parse_key_pkcs1_der( rsa, key, keylen ) ) == 0 )
2430 return( 0 );
2431
2432 rsa_free( rsa );
Paul Bakker1fd43212013-06-17 15:14:42 +02002433
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002434 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00002435}
2436
2437/*
Paul Bakker53019ae2011-03-25 13:58:48 +00002438 * Parse a public RSA key
2439 */
Paul Bakker23986e52011-04-24 08:57:21 +00002440int x509parse_public_key( rsa_context *rsa, const unsigned char *key, size_t keylen )
Paul Bakker53019ae2011-03-25 13:58:48 +00002441{
Paul Bakker23986e52011-04-24 08:57:21 +00002442 int ret;
2443 size_t len;
Paul Bakker53019ae2011-03-25 13:58:48 +00002444 unsigned char *p, *end;
2445 x509_buf alg_oid;
2446#if defined(POLARSSL_PEM_C)
2447 pem_context pem;
2448
2449 pem_init( &pem );
2450 ret = pem_read_buffer( &pem,
2451 "-----BEGIN PUBLIC KEY-----",
2452 "-----END PUBLIC KEY-----",
2453 key, NULL, 0, &len );
2454
2455 if( ret == 0 )
2456 {
2457 /*
2458 * Was PEM encoded
2459 */
2460 keylen = pem.buflen;
2461 }
Paul Bakker9255e832013-06-06 14:58:28 +02002462 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker53019ae2011-03-25 13:58:48 +00002463 {
2464 pem_free( &pem );
2465 return( ret );
2466 }
2467
2468 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2469#else
2470 p = (unsigned char *) key;
2471#endif
2472 end = p + keylen;
2473
2474 /*
2475 * PublicKeyInfo ::= SEQUENCE {
2476 * algorithm AlgorithmIdentifier,
2477 * PublicKey BIT STRING
2478 * }
2479 *
2480 * AlgorithmIdentifier ::= SEQUENCE {
2481 * algorithm OBJECT IDENTIFIER,
2482 * parameters ANY DEFINED BY algorithm OPTIONAL
2483 * }
2484 *
2485 * RSAPublicKey ::= SEQUENCE {
2486 * modulus INTEGER, -- n
2487 * publicExponent INTEGER -- e
2488 * }
2489 */
2490
2491 if( ( ret = asn1_get_tag( &p, end, &len,
2492 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2493 {
2494#if defined(POLARSSL_PEM_C)
2495 pem_free( &pem );
2496#endif
2497 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002498 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002499 }
2500
2501 if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
2502 {
2503#if defined(POLARSSL_PEM_C)
2504 pem_free( &pem );
2505#endif
2506 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002507 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002508 }
2509
2510 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
2511 {
2512#if defined(POLARSSL_PEM_C)
2513 pem_free( &pem );
2514#endif
2515 rsa_free( rsa );
2516 return( ret );
2517 }
2518
2519 rsa->len = mpi_size( &rsa->N );
2520
2521#if defined(POLARSSL_PEM_C)
2522 pem_free( &pem );
2523#endif
2524
2525 return( 0 );
2526}
2527
Paul Bakkereaa89f82011-04-04 21:36:15 +00002528#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00002529/*
Paul Bakker1b57b062011-01-06 15:48:19 +00002530 * Parse DHM parameters
2531 */
Paul Bakker23986e52011-04-24 08:57:21 +00002532int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
Paul Bakker1b57b062011-01-06 15:48:19 +00002533{
Paul Bakker23986e52011-04-24 08:57:21 +00002534 int ret;
2535 size_t len;
Paul Bakker1b57b062011-01-06 15:48:19 +00002536 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00002537#if defined(POLARSSL_PEM_C)
2538 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00002539
Paul Bakker96743fc2011-02-12 14:30:57 +00002540 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00002541
Paul Bakker96743fc2011-02-12 14:30:57 +00002542 ret = pem_read_buffer( &pem,
2543 "-----BEGIN DH PARAMETERS-----",
2544 "-----END DH PARAMETERS-----",
2545 dhmin, NULL, 0, &dhminlen );
2546
2547 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00002548 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002549 /*
2550 * Was PEM encoded
2551 */
2552 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00002553 }
Paul Bakker9255e832013-06-06 14:58:28 +02002554 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00002555 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002556 pem_free( &pem );
2557 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002558 }
2559
Paul Bakker96743fc2011-02-12 14:30:57 +00002560 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
2561#else
2562 p = (unsigned char *) dhmin;
2563#endif
2564 end = p + dhminlen;
2565
Paul Bakker1b57b062011-01-06 15:48:19 +00002566 memset( dhm, 0, sizeof( dhm_context ) );
2567
Paul Bakker1b57b062011-01-06 15:48:19 +00002568 /*
2569 * DHParams ::= SEQUENCE {
2570 * prime INTEGER, -- P
2571 * generator INTEGER, -- g
2572 * }
2573 */
2574 if( ( ret = asn1_get_tag( &p, end, &len,
2575 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2576 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002577#if defined(POLARSSL_PEM_C)
2578 pem_free( &pem );
2579#endif
Paul Bakker9d781402011-05-09 16:17:09 +00002580 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002581 }
2582
2583 end = p + len;
2584
2585 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
2586 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
2587 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002588#if defined(POLARSSL_PEM_C)
2589 pem_free( &pem );
2590#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002591 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002592 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002593 }
2594
2595 if( p != end )
2596 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002597#if defined(POLARSSL_PEM_C)
2598 pem_free( &pem );
2599#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002600 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002601 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker1b57b062011-01-06 15:48:19 +00002602 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
2603 }
2604
Paul Bakker96743fc2011-02-12 14:30:57 +00002605#if defined(POLARSSL_PEM_C)
2606 pem_free( &pem );
2607#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002608
2609 return( 0 );
2610}
2611
Paul Bakker335db3f2011-04-25 15:28:35 +00002612#if defined(POLARSSL_FS_IO)
Paul Bakker1b57b062011-01-06 15:48:19 +00002613/*
2614 * Load and parse a private RSA key
2615 */
2616int x509parse_dhmfile( dhm_context *dhm, const char *path )
2617{
2618 int ret;
2619 size_t n;
2620 unsigned char *buf;
2621
Paul Bakker69e095c2011-12-10 21:55:01 +00002622 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
2623 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002624
Paul Bakker27fdf462011-06-09 13:55:13 +00002625 ret = x509parse_dhm( dhm, buf, n );
Paul Bakker1b57b062011-01-06 15:48:19 +00002626
2627 memset( buf, 0, n + 1 );
2628 free( buf );
2629
2630 return( ret );
2631}
Paul Bakker335db3f2011-04-25 15:28:35 +00002632#endif /* POLARSSL_FS_IO */
Paul Bakkereaa89f82011-04-04 21:36:15 +00002633#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00002634
Paul Bakker5121ce52009-01-03 21:22:43 +00002635#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002636#include <stdarg.h>
2637
2638#if !defined vsnprintf
2639#define vsnprintf _vsnprintf
2640#endif // vsnprintf
2641
2642/*
2643 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2644 * Result value is not size of buffer needed, but -1 if no fit is possible.
2645 *
2646 * This fuction tries to 'fix' this by at least suggesting enlarging the
2647 * size by 20.
2648 */
2649int compat_snprintf(char *str, size_t size, const char *format, ...)
2650{
2651 va_list ap;
2652 int res = -1;
2653
2654 va_start( ap, format );
2655
2656 res = vsnprintf( str, size, format, ap );
2657
2658 va_end( ap );
2659
2660 // No quick fix possible
2661 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00002662 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002663
2664 return res;
2665}
2666
2667#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002668#endif
2669
Paul Bakkerd98030e2009-05-02 15:13:40 +00002670#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2671
2672#define SAFE_SNPRINTF() \
2673{ \
2674 if( ret == -1 ) \
2675 return( -1 ); \
2676 \
Paul Bakker23986e52011-04-24 08:57:21 +00002677 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002678 p[n - 1] = '\0'; \
2679 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2680 } \
2681 \
Paul Bakker23986e52011-04-24 08:57:21 +00002682 n -= (unsigned int) ret; \
2683 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002684}
2685
Paul Bakker5121ce52009-01-03 21:22:43 +00002686/*
2687 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002688 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002689 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002690int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002691{
Paul Bakker23986e52011-04-24 08:57:21 +00002692 int ret;
2693 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002694 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002695 const x509_name *name;
Paul Bakker5121ce52009-01-03 21:22:43 +00002696 char s[128], *p;
2697
2698 memset( s, 0, sizeof( s ) );
2699
2700 name = dn;
2701 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002702 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002703
2704 while( name != NULL )
2705 {
Paul Bakkercefb3962012-06-27 11:51:09 +00002706 if( !name->oid.p )
2707 {
2708 name = name->next;
2709 continue;
2710 }
2711
Paul Bakker74111d32011-01-15 16:57:55 +00002712 if( name != dn )
2713 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002714 ret = snprintf( p, n, ", " );
2715 SAFE_SNPRINTF();
2716 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002717
Paul Bakker535e97d2012-08-23 10:49:55 +00002718 if( name->oid.len == 3 &&
2719 memcmp( name->oid.p, OID_X520, 2 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002720 {
2721 switch( name->oid.p[2] )
2722 {
2723 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002724 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002725
2726 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002727 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002728
2729 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002730 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002731
2732 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002733 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002734
2735 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002736 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002737
2738 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002739 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002740
2741 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002742 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002743 name->oid.p[2] );
2744 break;
2745 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002746 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002747 }
Paul Bakker535e97d2012-08-23 10:49:55 +00002748 else if( name->oid.len == 9 &&
2749 memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002750 {
2751 switch( name->oid.p[8] )
2752 {
2753 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002754 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002755
2756 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002757 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002758 name->oid.p[8] );
2759 break;
2760 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002761 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002762 }
2763 else
Paul Bakker74111d32011-01-15 16:57:55 +00002764 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002765 ret = snprintf( p, n, "\?\?=" );
Paul Bakker74111d32011-01-15 16:57:55 +00002766 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002767 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002768
2769 for( i = 0; i < name->val.len; i++ )
2770 {
Paul Bakker27fdf462011-06-09 13:55:13 +00002771 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002772 break;
2773
2774 c = name->val.p[i];
2775 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2776 s[i] = '?';
2777 else s[i] = c;
2778 }
2779 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002780 ret = snprintf( p, n, "%s", s );
2781 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002782 name = name->next;
2783 }
2784
Paul Bakker23986e52011-04-24 08:57:21 +00002785 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002786}
2787
2788/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002789 * Store the serial in printable form into buf; no more
2790 * than size characters will be written
2791 */
2792int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2793{
Paul Bakker23986e52011-04-24 08:57:21 +00002794 int ret;
2795 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00002796 char *p;
2797
2798 p = buf;
2799 n = size;
2800
2801 nr = ( serial->len <= 32 )
Paul Bakker03c7c252011-11-25 12:37:37 +00002802 ? serial->len : 28;
Paul Bakkerdd476992011-01-16 21:34:59 +00002803
2804 for( i = 0; i < nr; i++ )
2805 {
Paul Bakker93048802011-12-05 14:38:06 +00002806 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002807 continue;
2808
Paul Bakkerdd476992011-01-16 21:34:59 +00002809 ret = snprintf( p, n, "%02X%s",
2810 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2811 SAFE_SNPRINTF();
2812 }
2813
Paul Bakker03c7c252011-11-25 12:37:37 +00002814 if( nr != serial->len )
2815 {
2816 ret = snprintf( p, n, "...." );
2817 SAFE_SNPRINTF();
2818 }
2819
Paul Bakker23986e52011-04-24 08:57:21 +00002820 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00002821}
2822
2823/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002824 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002825 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002826int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2827 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002828{
Paul Bakker23986e52011-04-24 08:57:21 +00002829 int ret;
2830 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002831 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00002832
2833 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002834 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002835
Paul Bakkerd98030e2009-05-02 15:13:40 +00002836 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002837 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002838 SAFE_SNPRINTF();
2839 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002840 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002841 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002842
Paul Bakkerdd476992011-01-16 21:34:59 +00002843 ret = x509parse_serial_gets( p, n, &crt->serial);
2844 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002845
Paul Bakkerd98030e2009-05-02 15:13:40 +00002846 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2847 SAFE_SNPRINTF();
2848 ret = x509parse_dn_gets( p, n, &crt->issuer );
2849 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002850
Paul Bakkerd98030e2009-05-02 15:13:40 +00002851 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2852 SAFE_SNPRINTF();
2853 ret = x509parse_dn_gets( p, n, &crt->subject );
2854 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002855
Paul Bakkerd98030e2009-05-02 15:13:40 +00002856 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002857 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2858 crt->valid_from.year, crt->valid_from.mon,
2859 crt->valid_from.day, crt->valid_from.hour,
2860 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002861 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002862
Paul Bakkerd98030e2009-05-02 15:13:40 +00002863 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002864 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2865 crt->valid_to.year, crt->valid_to.mon,
2866 crt->valid_to.day, crt->valid_to.hour,
2867 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002868 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002869
Paul Bakkerd98030e2009-05-02 15:13:40 +00002870 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2871 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002872
Paul Bakker27d66162010-03-17 06:56:01 +00002873 switch( crt->sig_alg )
Paul Bakker5121ce52009-01-03 21:22:43 +00002874 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002875 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2876 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2877 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2878 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2879 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2880 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2881 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2882 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2883 default: ret = snprintf( p, n, "???" ); break;
2884 }
2885 SAFE_SNPRINTF();
2886
2887 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
Paul Bakker5c2364c2012-10-01 14:41:15 +00002888 (int) crt->rsa.N.n * (int) sizeof( t_uint ) * 8 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002889 SAFE_SNPRINTF();
2890
Paul Bakker23986e52011-04-24 08:57:21 +00002891 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002892}
2893
Paul Bakker74111d32011-01-15 16:57:55 +00002894/*
2895 * Return an informational string describing the given OID
2896 */
2897const char *x509_oid_get_description( x509_buf *oid )
2898{
2899 if ( oid == NULL )
2900 return ( NULL );
2901
2902 else if( OID_CMP( OID_SERVER_AUTH, oid ) )
2903 return( STRING_SERVER_AUTH );
2904
2905 else if( OID_CMP( OID_CLIENT_AUTH, oid ) )
2906 return( STRING_CLIENT_AUTH );
2907
2908 else if( OID_CMP( OID_CODE_SIGNING, oid ) )
2909 return( STRING_CODE_SIGNING );
2910
2911 else if( OID_CMP( OID_EMAIL_PROTECTION, oid ) )
2912 return( STRING_EMAIL_PROTECTION );
2913
2914 else if( OID_CMP( OID_TIME_STAMPING, oid ) )
2915 return( STRING_TIME_STAMPING );
2916
2917 else if( OID_CMP( OID_OCSP_SIGNING, oid ) )
2918 return( STRING_OCSP_SIGNING );
2919
2920 return( NULL );
2921}
2922
2923/* Return the x.y.z.... style numeric string for the given OID */
2924int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2925{
Paul Bakker23986e52011-04-24 08:57:21 +00002926 int ret;
2927 size_t i, n;
Paul Bakker74111d32011-01-15 16:57:55 +00002928 unsigned int value;
2929 char *p;
2930
2931 p = buf;
2932 n = size;
2933
2934 /* First byte contains first two dots */
2935 if( oid->len > 0 )
2936 {
2937 ret = snprintf( p, n, "%d.%d", oid->p[0]/40, oid->p[0]%40 );
2938 SAFE_SNPRINTF();
2939 }
2940
2941 /* TODO: value can overflow in value. */
2942 value = 0;
Paul Bakker23986e52011-04-24 08:57:21 +00002943 for( i = 1; i < oid->len; i++ )
Paul Bakker74111d32011-01-15 16:57:55 +00002944 {
2945 value <<= 7;
2946 value += oid->p[i] & 0x7F;
2947
2948 if( !( oid->p[i] & 0x80 ) )
2949 {
2950 /* Last byte */
2951 ret = snprintf( p, n, ".%d", value );
2952 SAFE_SNPRINTF();
2953 value = 0;
2954 }
2955 }
2956
Paul Bakker23986e52011-04-24 08:57:21 +00002957 return( (int) ( size - n ) );
Paul Bakker74111d32011-01-15 16:57:55 +00002958}
2959
Paul Bakkerd98030e2009-05-02 15:13:40 +00002960/*
2961 * Return an informational string about the CRL.
2962 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002963int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2964 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002965{
Paul Bakker23986e52011-04-24 08:57:21 +00002966 int ret;
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002967 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002968 char *p;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002969 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002970
2971 p = buf;
2972 n = size;
2973
2974 ret = snprintf( p, n, "%sCRL version : %d",
2975 prefix, crl->version );
2976 SAFE_SNPRINTF();
2977
2978 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2979 SAFE_SNPRINTF();
2980 ret = x509parse_dn_gets( p, n, &crl->issuer );
2981 SAFE_SNPRINTF();
2982
2983 ret = snprintf( p, n, "\n%sthis update : " \
2984 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2985 crl->this_update.year, crl->this_update.mon,
2986 crl->this_update.day, crl->this_update.hour,
2987 crl->this_update.min, crl->this_update.sec );
2988 SAFE_SNPRINTF();
2989
2990 ret = snprintf( p, n, "\n%snext update : " \
2991 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2992 crl->next_update.year, crl->next_update.mon,
2993 crl->next_update.day, crl->next_update.hour,
2994 crl->next_update.min, crl->next_update.sec );
2995 SAFE_SNPRINTF();
2996
2997 entry = &crl->entry;
2998
2999 ret = snprintf( p, n, "\n%sRevoked certificates:",
3000 prefix );
3001 SAFE_SNPRINTF();
3002
Paul Bakker9be19372009-07-27 20:21:53 +00003003 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003004 {
3005 ret = snprintf( p, n, "\n%sserial number: ",
3006 prefix );
3007 SAFE_SNPRINTF();
3008
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003009 ret = x509parse_serial_gets( p, n, &entry->serial);
3010 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003011
Paul Bakkerd98030e2009-05-02 15:13:40 +00003012 ret = snprintf( p, n, " revocation date: " \
3013 "%04d-%02d-%02d %02d:%02d:%02d",
3014 entry->revocation_date.year, entry->revocation_date.mon,
3015 entry->revocation_date.day, entry->revocation_date.hour,
3016 entry->revocation_date.min, entry->revocation_date.sec );
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003017 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003018
3019 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003020 }
3021
Paul Bakkerd98030e2009-05-02 15:13:40 +00003022 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
3023 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003024
Paul Bakker27d66162010-03-17 06:56:01 +00003025 switch( crl->sig_alg )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003026 {
3027 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
3028 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
3029 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
3030 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
3031 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
3032 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
3033 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
3034 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
3035 default: ret = snprintf( p, n, "???" ); break;
3036 }
3037 SAFE_SNPRINTF();
3038
Paul Bakker1e27bb22009-07-19 20:25:25 +00003039 ret = snprintf( p, n, "\n" );
3040 SAFE_SNPRINTF();
3041
Paul Bakker23986e52011-04-24 08:57:21 +00003042 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003043}
3044
3045/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00003046 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00003047 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003048int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00003049{
Paul Bakkercce9d772011-11-18 14:26:47 +00003050 int year, mon, day;
3051 int hour, min, sec;
3052
3053#if defined(_WIN32)
3054 SYSTEMTIME st;
3055
3056 GetLocalTime(&st);
3057
3058 year = st.wYear;
3059 mon = st.wMonth;
3060 day = st.wDay;
3061 hour = st.wHour;
3062 min = st.wMinute;
3063 sec = st.wSecond;
3064#else
Paul Bakker5121ce52009-01-03 21:22:43 +00003065 struct tm *lt;
3066 time_t tt;
3067
3068 tt = time( NULL );
3069 lt = localtime( &tt );
3070
Paul Bakkercce9d772011-11-18 14:26:47 +00003071 year = lt->tm_year + 1900;
3072 mon = lt->tm_mon + 1;
3073 day = lt->tm_mday;
3074 hour = lt->tm_hour;
3075 min = lt->tm_min;
3076 sec = lt->tm_sec;
3077#endif
3078
3079 if( year > to->year )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003080 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003081
Paul Bakkercce9d772011-11-18 14:26:47 +00003082 if( year == to->year &&
3083 mon > to->mon )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003084 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003085
Paul Bakkercce9d772011-11-18 14:26:47 +00003086 if( year == to->year &&
3087 mon == to->mon &&
3088 day > to->day )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003089 return( 1 );
3090
Paul Bakkercce9d772011-11-18 14:26:47 +00003091 if( year == to->year &&
3092 mon == to->mon &&
3093 day == to->day &&
3094 hour > to->hour )
Paul Bakkerb6194992011-01-16 21:40:22 +00003095 return( 1 );
3096
Paul Bakkercce9d772011-11-18 14:26:47 +00003097 if( year == to->year &&
3098 mon == to->mon &&
3099 day == to->day &&
3100 hour == to->hour &&
3101 min > to->min )
Paul Bakkerb6194992011-01-16 21:40:22 +00003102 return( 1 );
3103
Paul Bakkercce9d772011-11-18 14:26:47 +00003104 if( year == to->year &&
3105 mon == to->mon &&
3106 day == to->day &&
3107 hour == to->hour &&
3108 min == to->min &&
3109 sec > to->sec )
Paul Bakkerb6194992011-01-16 21:40:22 +00003110 return( 1 );
3111
Paul Bakker40ea7de2009-05-03 10:18:48 +00003112 return( 0 );
3113}
3114
3115/*
3116 * Return 1 if the certificate is revoked, or 0 otherwise.
3117 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003118int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003119{
Paul Bakkerff60ee62010-03-16 21:09:09 +00003120 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00003121
3122 while( cur != NULL && cur->serial.len != 0 )
3123 {
Paul Bakkera056efc2011-01-16 21:38:35 +00003124 if( crt->serial.len == cur->serial.len &&
3125 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003126 {
3127 if( x509parse_time_expired( &cur->revocation_date ) )
3128 return( 1 );
3129 }
3130
3131 cur = cur->next;
3132 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003133
3134 return( 0 );
3135}
3136
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003137/*
3138 * Wrapper for x509 hashes.
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003139 */
Paul Bakker23986e52011-04-24 08:57:21 +00003140static void x509_hash( const unsigned char *in, size_t len, int alg,
Paul Bakker5121ce52009-01-03 21:22:43 +00003141 unsigned char *out )
3142{
3143 switch( alg )
3144 {
Paul Bakker40e46942009-01-03 21:51:57 +00003145#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003146 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003147#endif
Paul Bakker40e46942009-01-03 21:51:57 +00003148#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003149 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003150#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003151#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003152 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003153#endif
3154#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003155 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003156#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00003157#if defined(POLARSSL_SHA2_C)
3158 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
3159 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
3160#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00003161#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003162 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
3163 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
3164#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003165 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003166 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003167 break;
3168 }
3169}
3170
3171/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00003172 * Check that the given certificate is valid accoring to the CRL.
3173 */
3174static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
3175 x509_crl *crl_list)
3176{
3177 int flags = 0;
3178 int hash_id;
3179 unsigned char hash[64];
3180
Paul Bakker915275b2012-09-28 07:10:55 +00003181 if( ca == NULL )
3182 return( flags );
3183
Paul Bakker76fd75a2011-01-16 21:12:10 +00003184 /*
3185 * TODO: What happens if no CRL is present?
3186 * Suggestion: Revocation state should be unknown if no CRL is present.
3187 * For backwards compatibility this is not yet implemented.
3188 */
3189
Paul Bakker915275b2012-09-28 07:10:55 +00003190 while( crl_list != NULL )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003191 {
Paul Bakker915275b2012-09-28 07:10:55 +00003192 if( crl_list->version == 0 ||
3193 crl_list->issuer_raw.len != ca->subject_raw.len ||
Paul Bakker76fd75a2011-01-16 21:12:10 +00003194 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
3195 crl_list->issuer_raw.len ) != 0 )
3196 {
3197 crl_list = crl_list->next;
3198 continue;
3199 }
3200
3201 /*
3202 * Check if CRL is correctly signed by the trusted CA
3203 */
3204 hash_id = crl_list->sig_alg;
3205
3206 x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
3207
3208 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, hash_id,
3209 0, hash, crl_list->sig.p ) == 0 )
3210 {
3211 /*
3212 * CRL is not trusted
3213 */
3214 flags |= BADCRL_NOT_TRUSTED;
3215 break;
3216 }
3217
3218 /*
3219 * Check for validity of CRL (Do not drop out)
3220 */
3221 if( x509parse_time_expired( &crl_list->next_update ) )
3222 flags |= BADCRL_EXPIRED;
3223
3224 /*
3225 * Check if certificate is revoked
3226 */
3227 if( x509parse_revoked(crt, crl_list) )
3228 {
3229 flags |= BADCERT_REVOKED;
3230 break;
3231 }
3232
3233 crl_list = crl_list->next;
3234 }
3235 return flags;
3236}
3237
Paul Bakker57b12982012-02-11 17:38:38 +00003238int x509_wildcard_verify( const char *cn, x509_buf *name )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003239{
3240 size_t i;
3241 size_t cn_idx = 0;
3242
Paul Bakker57b12982012-02-11 17:38:38 +00003243 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003244 return( 0 );
3245
3246 for( i = 0; i < strlen( cn ); ++i )
3247 {
3248 if( cn[i] == '.' )
3249 {
3250 cn_idx = i;
3251 break;
3252 }
3253 }
3254
3255 if( cn_idx == 0 )
3256 return( 0 );
3257
Paul Bakker535e97d2012-08-23 10:49:55 +00003258 if( strlen( cn ) - cn_idx == name->len - 1 &&
3259 memcmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003260 {
3261 return( 1 );
3262 }
3263
3264 return( 0 );
3265}
3266
Paul Bakker915275b2012-09-28 07:10:55 +00003267static int x509parse_verify_top(
3268 x509_cert *child, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003269 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003270 int (*f_vrfy)(void *, x509_cert *, int, int *),
3271 void *p_vrfy )
3272{
3273 int hash_id, ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003274 int ca_flags = 0, check_path_cnt = path_cnt + 1;
Paul Bakker915275b2012-09-28 07:10:55 +00003275 unsigned char hash[64];
3276
3277 if( x509parse_time_expired( &child->valid_to ) )
3278 *flags |= BADCERT_EXPIRED;
3279
3280 /*
3281 * Child is the top of the chain. Check against the trust_ca list.
3282 */
3283 *flags |= BADCERT_NOT_TRUSTED;
3284
3285 while( trust_ca != NULL )
3286 {
3287 if( trust_ca->version == 0 ||
3288 child->issuer_raw.len != trust_ca->subject_raw.len ||
3289 memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
3290 child->issuer_raw.len ) != 0 )
3291 {
3292 trust_ca = trust_ca->next;
3293 continue;
3294 }
3295
Paul Bakker9a736322012-11-14 12:39:52 +00003296 /*
3297 * Reduce path_len to check against if top of the chain is
3298 * the same as the trusted CA
3299 */
3300 if( child->subject_raw.len == trust_ca->subject_raw.len &&
3301 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3302 child->issuer_raw.len ) == 0 )
3303 {
3304 check_path_cnt--;
3305 }
3306
Paul Bakker915275b2012-09-28 07:10:55 +00003307 if( trust_ca->max_pathlen > 0 &&
Paul Bakker9a736322012-11-14 12:39:52 +00003308 trust_ca->max_pathlen < check_path_cnt )
Paul Bakker915275b2012-09-28 07:10:55 +00003309 {
3310 trust_ca = trust_ca->next;
3311 continue;
3312 }
3313
3314 hash_id = child->sig_alg;
3315
3316 x509_hash( child->tbs.p, child->tbs.len, hash_id, hash );
3317
3318 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
3319 0, hash, child->sig.p ) != 0 )
3320 {
3321 trust_ca = trust_ca->next;
3322 continue;
3323 }
3324
3325 /*
3326 * Top of chain is signed by a trusted CA
3327 */
3328 *flags &= ~BADCERT_NOT_TRUSTED;
3329 break;
3330 }
3331
Paul Bakker9a736322012-11-14 12:39:52 +00003332 /*
Paul Bakker3497d8c2012-11-24 11:53:17 +01003333 * If top of chain is not the same as the trusted CA send a verify request
3334 * to the callback for any issues with validity and CRL presence for the
3335 * trusted CA certificate.
Paul Bakker9a736322012-11-14 12:39:52 +00003336 */
3337 if( trust_ca != NULL &&
3338 ( child->subject_raw.len != trust_ca->subject_raw.len ||
3339 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3340 child->issuer_raw.len ) != 0 ) )
Paul Bakker915275b2012-09-28 07:10:55 +00003341 {
3342 /* Check trusted CA's CRL for then chain's top crt */
3343 *flags |= x509parse_verifycrl( child, trust_ca, ca_crl );
3344
3345 if( x509parse_time_expired( &trust_ca->valid_to ) )
3346 ca_flags |= BADCERT_EXPIRED;
3347
Paul Bakker915275b2012-09-28 07:10:55 +00003348 if( NULL != f_vrfy )
3349 {
Paul Bakker9a736322012-11-14 12:39:52 +00003350 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003351 return( ret );
3352 }
3353 }
3354
3355 /* Call callback on top cert */
3356 if( NULL != f_vrfy )
3357 {
Paul Bakker9a736322012-11-14 12:39:52 +00003358 if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003359 return( ret );
3360 }
3361
Paul Bakker915275b2012-09-28 07:10:55 +00003362 *flags |= ca_flags;
3363
3364 return( 0 );
3365}
3366
3367static int x509parse_verify_child(
3368 x509_cert *child, x509_cert *parent, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003369 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003370 int (*f_vrfy)(void *, x509_cert *, int, int *),
3371 void *p_vrfy )
3372{
3373 int hash_id, ret;
3374 int parent_flags = 0;
3375 unsigned char hash[64];
3376 x509_cert *grandparent;
3377
3378 if( x509parse_time_expired( &child->valid_to ) )
3379 *flags |= BADCERT_EXPIRED;
3380
3381 hash_id = child->sig_alg;
3382
3383 x509_hash( child->tbs.p, child->tbs.len, hash_id, hash );
3384
3385 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, hash_id, 0, hash,
3386 child->sig.p ) != 0 )
3387 *flags |= BADCERT_NOT_TRUSTED;
3388
3389 /* Check trusted CA's CRL for the given crt */
3390 *flags |= x509parse_verifycrl(child, parent, ca_crl);
3391
3392 grandparent = parent->next;
3393
3394 while( grandparent != NULL )
3395 {
3396 if( grandparent->version == 0 ||
3397 grandparent->ca_istrue == 0 ||
3398 parent->issuer_raw.len != grandparent->subject_raw.len ||
3399 memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
3400 parent->issuer_raw.len ) != 0 )
3401 {
3402 grandparent = grandparent->next;
3403 continue;
3404 }
3405 break;
3406 }
3407
Paul Bakker915275b2012-09-28 07:10:55 +00003408 if( grandparent != NULL )
3409 {
3410 /*
3411 * Part of the chain
3412 */
Paul Bakker9a736322012-11-14 12:39:52 +00003413 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 +00003414 if( ret != 0 )
3415 return( ret );
3416 }
3417 else
3418 {
Paul Bakker9a736322012-11-14 12:39:52 +00003419 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 +00003420 if( ret != 0 )
3421 return( ret );
3422 }
3423
3424 /* child is verified to be a child of the parent, call verify callback */
3425 if( NULL != f_vrfy )
Paul Bakker9a736322012-11-14 12:39:52 +00003426 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003427 return( ret );
Paul Bakker915275b2012-09-28 07:10:55 +00003428
3429 *flags |= parent_flags;
3430
3431 return( 0 );
3432}
3433
Paul Bakker76fd75a2011-01-16 21:12:10 +00003434/*
Paul Bakker5121ce52009-01-03 21:22:43 +00003435 * Verify the certificate validity
3436 */
3437int x509parse_verify( x509_cert *crt,
3438 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00003439 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003440 const char *cn, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003441 int (*f_vrfy)(void *, x509_cert *, int, int *),
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003442 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00003443{
Paul Bakker23986e52011-04-24 08:57:21 +00003444 size_t cn_len;
Paul Bakker915275b2012-09-28 07:10:55 +00003445 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003446 int pathlen = 0;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003447 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00003448 x509_name *name;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003449 x509_sequence *cur = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003450
Paul Bakker40ea7de2009-05-03 10:18:48 +00003451 *flags = 0;
3452
Paul Bakker5121ce52009-01-03 21:22:43 +00003453 if( cn != NULL )
3454 {
3455 name = &crt->subject;
3456 cn_len = strlen( cn );
3457
Paul Bakker4d2c1242012-05-10 14:12:46 +00003458 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
Paul Bakker5121ce52009-01-03 21:22:43 +00003459 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00003460 cur = &crt->subject_alt_names;
3461
3462 while( cur != NULL )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003463 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003464 if( cur->buf.len == cn_len &&
3465 memcmp( cn, cur->buf.p, cn_len ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003466 break;
3467
Paul Bakker535e97d2012-08-23 10:49:55 +00003468 if( cur->buf.len > 2 &&
3469 memcmp( cur->buf.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003470 x509_wildcard_verify( cn, &cur->buf ) )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003471 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003472
Paul Bakker4d2c1242012-05-10 14:12:46 +00003473 cur = cur->next;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003474 }
3475
3476 if( cur == NULL )
3477 *flags |= BADCERT_CN_MISMATCH;
3478 }
Paul Bakker4d2c1242012-05-10 14:12:46 +00003479 else
3480 {
3481 while( name != NULL )
3482 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003483 if( name->oid.len == 3 &&
3484 memcmp( name->oid.p, OID_CN, 3 ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003485 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003486 if( name->val.len == cn_len &&
3487 memcmp( name->val.p, cn, cn_len ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003488 break;
3489
Paul Bakker535e97d2012-08-23 10:49:55 +00003490 if( name->val.len > 2 &&
3491 memcmp( name->val.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003492 x509_wildcard_verify( cn, &name->val ) )
3493 break;
3494 }
3495
3496 name = name->next;
3497 }
3498
3499 if( name == NULL )
3500 *flags |= BADCERT_CN_MISMATCH;
3501 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003502 }
3503
Paul Bakker5121ce52009-01-03 21:22:43 +00003504 /*
Paul Bakker915275b2012-09-28 07:10:55 +00003505 * Iterate upwards in the given cert chain, to find our crt parent.
3506 * Ignore any upper cert with CA != TRUE.
Paul Bakker5121ce52009-01-03 21:22:43 +00003507 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003508 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003509
Paul Bakker76fd75a2011-01-16 21:12:10 +00003510 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003511 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003512 if( parent->ca_istrue == 0 ||
3513 crt->issuer_raw.len != parent->subject_raw.len ||
3514 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00003515 crt->issuer_raw.len ) != 0 )
3516 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003517 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003518 continue;
3519 }
Paul Bakker915275b2012-09-28 07:10:55 +00003520 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003521 }
3522
Paul Bakker915275b2012-09-28 07:10:55 +00003523 if( parent != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003524 {
Paul Bakker915275b2012-09-28 07:10:55 +00003525 /*
3526 * Part of the chain
3527 */
Paul Bakker9a736322012-11-14 12:39:52 +00003528 ret = x509parse_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003529 if( ret != 0 )
3530 return( ret );
3531 }
3532 else
Paul Bakker74111d32011-01-15 16:57:55 +00003533 {
Paul Bakker9a736322012-11-14 12:39:52 +00003534 ret = x509parse_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003535 if( ret != 0 )
3536 return( ret );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003537 }
Paul Bakker915275b2012-09-28 07:10:55 +00003538
3539 if( *flags != 0 )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003540 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003541
Paul Bakker5121ce52009-01-03 21:22:43 +00003542 return( 0 );
3543}
3544
3545/*
3546 * Unallocate all certificate data
3547 */
3548void x509_free( x509_cert *crt )
3549{
3550 x509_cert *cert_cur = crt;
3551 x509_cert *cert_prv;
3552 x509_name *name_cur;
3553 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00003554 x509_sequence *seq_cur;
3555 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00003556
3557 if( crt == NULL )
3558 return;
3559
3560 do
3561 {
3562 rsa_free( &cert_cur->rsa );
3563
3564 name_cur = cert_cur->issuer.next;
3565 while( name_cur != NULL )
3566 {
3567 name_prv = name_cur;
3568 name_cur = name_cur->next;
3569 memset( name_prv, 0, sizeof( x509_name ) );
3570 free( name_prv );
3571 }
3572
3573 name_cur = cert_cur->subject.next;
3574 while( name_cur != NULL )
3575 {
3576 name_prv = name_cur;
3577 name_cur = name_cur->next;
3578 memset( name_prv, 0, sizeof( x509_name ) );
3579 free( name_prv );
3580 }
3581
Paul Bakker74111d32011-01-15 16:57:55 +00003582 seq_cur = cert_cur->ext_key_usage.next;
3583 while( seq_cur != NULL )
3584 {
3585 seq_prv = seq_cur;
3586 seq_cur = seq_cur->next;
3587 memset( seq_prv, 0, sizeof( x509_sequence ) );
3588 free( seq_prv );
3589 }
3590
Paul Bakker8afa70d2012-02-11 18:42:45 +00003591 seq_cur = cert_cur->subject_alt_names.next;
3592 while( seq_cur != NULL )
3593 {
3594 seq_prv = seq_cur;
3595 seq_cur = seq_cur->next;
3596 memset( seq_prv, 0, sizeof( x509_sequence ) );
3597 free( seq_prv );
3598 }
3599
Paul Bakker5121ce52009-01-03 21:22:43 +00003600 if( cert_cur->raw.p != NULL )
3601 {
3602 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
3603 free( cert_cur->raw.p );
3604 }
3605
3606 cert_cur = cert_cur->next;
3607 }
3608 while( cert_cur != NULL );
3609
3610 cert_cur = crt;
3611 do
3612 {
3613 cert_prv = cert_cur;
3614 cert_cur = cert_cur->next;
3615
3616 memset( cert_prv, 0, sizeof( x509_cert ) );
3617 if( cert_prv != crt )
3618 free( cert_prv );
3619 }
3620 while( cert_cur != NULL );
3621}
3622
Paul Bakkerd98030e2009-05-02 15:13:40 +00003623/*
3624 * Unallocate all CRL data
3625 */
3626void x509_crl_free( x509_crl *crl )
3627{
3628 x509_crl *crl_cur = crl;
3629 x509_crl *crl_prv;
3630 x509_name *name_cur;
3631 x509_name *name_prv;
3632 x509_crl_entry *entry_cur;
3633 x509_crl_entry *entry_prv;
3634
3635 if( crl == NULL )
3636 return;
3637
3638 do
3639 {
3640 name_cur = crl_cur->issuer.next;
3641 while( name_cur != NULL )
3642 {
3643 name_prv = name_cur;
3644 name_cur = name_cur->next;
3645 memset( name_prv, 0, sizeof( x509_name ) );
3646 free( name_prv );
3647 }
3648
3649 entry_cur = crl_cur->entry.next;
3650 while( entry_cur != NULL )
3651 {
3652 entry_prv = entry_cur;
3653 entry_cur = entry_cur->next;
3654 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
3655 free( entry_prv );
3656 }
3657
3658 if( crl_cur->raw.p != NULL )
3659 {
3660 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
3661 free( crl_cur->raw.p );
3662 }
3663
3664 crl_cur = crl_cur->next;
3665 }
3666 while( crl_cur != NULL );
3667
3668 crl_cur = crl;
3669 do
3670 {
3671 crl_prv = crl_cur;
3672 crl_cur = crl_cur->next;
3673
3674 memset( crl_prv, 0, sizeof( x509_crl ) );
3675 if( crl_prv != crl )
3676 free( crl_prv );
3677 }
3678 while( crl_cur != NULL );
3679}
3680
Paul Bakker40e46942009-01-03 21:51:57 +00003681#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00003682
Paul Bakker40e46942009-01-03 21:51:57 +00003683#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00003684
3685/*
3686 * Checkup routine
3687 */
3688int x509_self_test( int verbose )
3689{
Paul Bakker5690efc2011-05-26 13:16:06 +00003690#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00003691 int ret;
3692 int flags;
3693 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00003694 x509_cert cacert;
3695 x509_cert clicert;
3696 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00003697#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003698 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00003699#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003700
3701 if( verbose != 0 )
3702 printf( " X.509 certificate load: " );
3703
3704 memset( &clicert, 0, sizeof( x509_cert ) );
3705
Paul Bakkereae09db2013-06-06 12:35:54 +02003706 ret = x509parse_crt( &clicert, (const unsigned char *) test_cli_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003707 strlen( test_cli_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003708 if( ret != 0 )
3709 {
3710 if( verbose != 0 )
3711 printf( "failed\n" );
3712
3713 return( ret );
3714 }
3715
3716 memset( &cacert, 0, sizeof( x509_cert ) );
3717
Paul Bakkereae09db2013-06-06 12:35:54 +02003718 ret = x509parse_crt( &cacert, (const unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003719 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003720 if( ret != 0 )
3721 {
3722 if( verbose != 0 )
3723 printf( "failed\n" );
3724
3725 return( ret );
3726 }
3727
3728 if( verbose != 0 )
3729 printf( "passed\n X.509 private key load: " );
3730
3731 i = strlen( test_ca_key );
3732 j = strlen( test_ca_pwd );
3733
Paul Bakker66b78b22011-03-25 14:22:50 +00003734 rsa_init( &rsa, RSA_PKCS_V15, 0 );
3735
Paul Bakker5121ce52009-01-03 21:22:43 +00003736 if( ( ret = x509parse_key( &rsa,
Paul Bakkereae09db2013-06-06 12:35:54 +02003737 (const unsigned char *) test_ca_key, i,
3738 (const unsigned char *) test_ca_pwd, j ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003739 {
3740 if( verbose != 0 )
3741 printf( "failed\n" );
3742
3743 return( ret );
3744 }
3745
3746 if( verbose != 0 )
3747 printf( "passed\n X.509 signature verify: ");
3748
Paul Bakker23986e52011-04-24 08:57:21 +00003749 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003750 if( ret != 0 )
3751 {
Paul Bakker23986e52011-04-24 08:57:21 +00003752 printf("%02x", flags);
Paul Bakker5121ce52009-01-03 21:22:43 +00003753 if( verbose != 0 )
3754 printf( "failed\n" );
3755
3756 return( ret );
3757 }
3758
Paul Bakker5690efc2011-05-26 13:16:06 +00003759#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003760 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003761 printf( "passed\n X.509 DHM parameter load: " );
3762
3763 i = strlen( test_dhm_params );
3764 j = strlen( test_ca_pwd );
3765
Paul Bakkereae09db2013-06-06 12:35:54 +02003766 if( ( ret = x509parse_dhm( &dhm, (const unsigned char *) test_dhm_params, i ) ) != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003767 {
3768 if( verbose != 0 )
3769 printf( "failed\n" );
3770
3771 return( ret );
3772 }
3773
3774 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003775 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00003776#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003777
3778 x509_free( &cacert );
3779 x509_free( &clicert );
3780 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00003781#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003782 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00003783#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003784
3785 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003786#else
3787 ((void) verbose);
3788 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3789#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003790}
3791
3792#endif
3793
3794#endif