blob: 25e3b45a44c25515d9a1bf6dabc26fba70932d01 [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 }
2357 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2358 {
2359 pem_free( &pem );
2360 return( ret );
2361 }
2362
2363 ret = pem_read_buffer( &pem,
2364 "-----BEGIN PRIVATE KEY-----",
2365 "-----END PRIVATE KEY-----",
2366 key, NULL, 0, &len );
2367 if( ret == 0 )
2368 {
2369 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa,
2370 pem.buf, pem.buflen ) ) != 0 )
2371 {
2372 rsa_free( rsa );
2373 }
2374
2375 pem_free( &pem );
2376 return( ret );
2377 }
2378 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2379 {
2380 pem_free( &pem );
2381 return( ret );
2382 }
2383
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002384 ret = pem_read_buffer( &pem,
2385 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
2386 "-----END ENCRYPTED PRIVATE KEY-----",
2387 key, NULL, 0, &len );
2388 if( ret == 0 )
2389 {
2390 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa,
2391 pem.buf, pem.buflen,
2392 pwd, pwdlen ) ) != 0 )
2393 {
2394 rsa_free( rsa );
2395 }
2396
2397 pem_free( &pem );
2398 return( ret );
2399 }
2400 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
2401 {
2402 pem_free( &pem );
2403 return( ret );
2404 }
Paul Bakker65a19092013-06-06 21:14:58 +02002405#else
2406 ((void) pwd);
2407 ((void) pwdlen);
2408#endif /* POLARSSL_PEM_C */
2409
2410 // At this point we only know it's not a PEM formatted key. Could be any
2411 // of the known DER encoded private key formats
2412 //
2413 // We try the different DER format parsers to see if one passes without
2414 // error
2415 //
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002416 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa, key, keylen,
2417 pwd, pwdlen ) ) == 0 )
Paul Bakker65a19092013-06-06 21:14:58 +02002418 {
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002419 return( 0 );
Paul Bakker65a19092013-06-06 21:14:58 +02002420 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002421
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002422 rsa_free( rsa );
Paul Bakker1fd43212013-06-17 15:14:42 +02002423
2424 if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH )
2425 {
2426 return( ret );
2427 }
2428
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002429 if( ( ret = x509parse_key_pkcs8_unencrypted_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 if( ( ret = x509parse_key_pkcs1_der( rsa, key, keylen ) ) == 0 )
2435 return( 0 );
2436
2437 rsa_free( rsa );
Paul Bakker1fd43212013-06-17 15:14:42 +02002438
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002439 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00002440}
2441
2442/*
Paul Bakker53019ae2011-03-25 13:58:48 +00002443 * Parse a public RSA key
2444 */
Paul Bakker23986e52011-04-24 08:57:21 +00002445int x509parse_public_key( rsa_context *rsa, const unsigned char *key, size_t keylen )
Paul Bakker53019ae2011-03-25 13:58:48 +00002446{
Paul Bakker23986e52011-04-24 08:57:21 +00002447 int ret;
2448 size_t len;
Paul Bakker53019ae2011-03-25 13:58:48 +00002449 unsigned char *p, *end;
2450 x509_buf alg_oid;
2451#if defined(POLARSSL_PEM_C)
2452 pem_context pem;
2453
2454 pem_init( &pem );
2455 ret = pem_read_buffer( &pem,
2456 "-----BEGIN PUBLIC KEY-----",
2457 "-----END PUBLIC KEY-----",
2458 key, NULL, 0, &len );
2459
2460 if( ret == 0 )
2461 {
2462 /*
2463 * Was PEM encoded
2464 */
2465 keylen = pem.buflen;
2466 }
Paul Bakker9255e832013-06-06 14:58:28 +02002467 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker53019ae2011-03-25 13:58:48 +00002468 {
2469 pem_free( &pem );
2470 return( ret );
2471 }
2472
2473 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2474#else
2475 p = (unsigned char *) key;
2476#endif
2477 end = p + keylen;
2478
2479 /*
2480 * PublicKeyInfo ::= SEQUENCE {
2481 * algorithm AlgorithmIdentifier,
2482 * PublicKey BIT STRING
2483 * }
2484 *
2485 * AlgorithmIdentifier ::= SEQUENCE {
2486 * algorithm OBJECT IDENTIFIER,
2487 * parameters ANY DEFINED BY algorithm OPTIONAL
2488 * }
2489 *
2490 * RSAPublicKey ::= SEQUENCE {
2491 * modulus INTEGER, -- n
2492 * publicExponent INTEGER -- e
2493 * }
2494 */
2495
2496 if( ( ret = asn1_get_tag( &p, end, &len,
2497 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2498 {
2499#if defined(POLARSSL_PEM_C)
2500 pem_free( &pem );
2501#endif
2502 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002503 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002504 }
2505
2506 if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
2507 {
2508#if defined(POLARSSL_PEM_C)
2509 pem_free( &pem );
2510#endif
2511 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002512 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002513 }
2514
2515 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
2516 {
2517#if defined(POLARSSL_PEM_C)
2518 pem_free( &pem );
2519#endif
2520 rsa_free( rsa );
2521 return( ret );
2522 }
2523
2524 rsa->len = mpi_size( &rsa->N );
2525
2526#if defined(POLARSSL_PEM_C)
2527 pem_free( &pem );
2528#endif
2529
2530 return( 0 );
2531}
2532
Paul Bakkereaa89f82011-04-04 21:36:15 +00002533#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00002534/*
Paul Bakker1b57b062011-01-06 15:48:19 +00002535 * Parse DHM parameters
2536 */
Paul Bakker23986e52011-04-24 08:57:21 +00002537int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
Paul Bakker1b57b062011-01-06 15:48:19 +00002538{
Paul Bakker23986e52011-04-24 08:57:21 +00002539 int ret;
2540 size_t len;
Paul Bakker1b57b062011-01-06 15:48:19 +00002541 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00002542#if defined(POLARSSL_PEM_C)
2543 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00002544
Paul Bakker96743fc2011-02-12 14:30:57 +00002545 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00002546
Paul Bakker96743fc2011-02-12 14:30:57 +00002547 ret = pem_read_buffer( &pem,
2548 "-----BEGIN DH PARAMETERS-----",
2549 "-----END DH PARAMETERS-----",
2550 dhmin, NULL, 0, &dhminlen );
2551
2552 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00002553 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002554 /*
2555 * Was PEM encoded
2556 */
2557 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00002558 }
Paul Bakker9255e832013-06-06 14:58:28 +02002559 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00002560 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002561 pem_free( &pem );
2562 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002563 }
2564
Paul Bakker96743fc2011-02-12 14:30:57 +00002565 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
2566#else
2567 p = (unsigned char *) dhmin;
2568#endif
2569 end = p + dhminlen;
2570
Paul Bakker1b57b062011-01-06 15:48:19 +00002571 memset( dhm, 0, sizeof( dhm_context ) );
2572
Paul Bakker1b57b062011-01-06 15:48:19 +00002573 /*
2574 * DHParams ::= SEQUENCE {
2575 * prime INTEGER, -- P
2576 * generator INTEGER, -- g
2577 * }
2578 */
2579 if( ( ret = asn1_get_tag( &p, end, &len,
2580 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2581 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002582#if defined(POLARSSL_PEM_C)
2583 pem_free( &pem );
2584#endif
Paul Bakker9d781402011-05-09 16:17:09 +00002585 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002586 }
2587
2588 end = p + len;
2589
2590 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
2591 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
2592 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002593#if defined(POLARSSL_PEM_C)
2594 pem_free( &pem );
2595#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002596 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002597 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002598 }
2599
2600 if( p != end )
2601 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002602#if defined(POLARSSL_PEM_C)
2603 pem_free( &pem );
2604#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002605 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002606 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker1b57b062011-01-06 15:48:19 +00002607 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
2608 }
2609
Paul Bakker96743fc2011-02-12 14:30:57 +00002610#if defined(POLARSSL_PEM_C)
2611 pem_free( &pem );
2612#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002613
2614 return( 0 );
2615}
2616
Paul Bakker335db3f2011-04-25 15:28:35 +00002617#if defined(POLARSSL_FS_IO)
Paul Bakker1b57b062011-01-06 15:48:19 +00002618/*
2619 * Load and parse a private RSA key
2620 */
2621int x509parse_dhmfile( dhm_context *dhm, const char *path )
2622{
2623 int ret;
2624 size_t n;
2625 unsigned char *buf;
2626
Paul Bakker69e095c2011-12-10 21:55:01 +00002627 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
2628 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002629
Paul Bakker27fdf462011-06-09 13:55:13 +00002630 ret = x509parse_dhm( dhm, buf, n );
Paul Bakker1b57b062011-01-06 15:48:19 +00002631
2632 memset( buf, 0, n + 1 );
2633 free( buf );
2634
2635 return( ret );
2636}
Paul Bakker335db3f2011-04-25 15:28:35 +00002637#endif /* POLARSSL_FS_IO */
Paul Bakkereaa89f82011-04-04 21:36:15 +00002638#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00002639
Paul Bakker5121ce52009-01-03 21:22:43 +00002640#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002641#include <stdarg.h>
2642
2643#if !defined vsnprintf
2644#define vsnprintf _vsnprintf
2645#endif // vsnprintf
2646
2647/*
2648 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2649 * Result value is not size of buffer needed, but -1 if no fit is possible.
2650 *
2651 * This fuction tries to 'fix' this by at least suggesting enlarging the
2652 * size by 20.
2653 */
2654int compat_snprintf(char *str, size_t size, const char *format, ...)
2655{
2656 va_list ap;
2657 int res = -1;
2658
2659 va_start( ap, format );
2660
2661 res = vsnprintf( str, size, format, ap );
2662
2663 va_end( ap );
2664
2665 // No quick fix possible
2666 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00002667 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002668
2669 return res;
2670}
2671
2672#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002673#endif
2674
Paul Bakkerd98030e2009-05-02 15:13:40 +00002675#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2676
2677#define SAFE_SNPRINTF() \
2678{ \
2679 if( ret == -1 ) \
2680 return( -1 ); \
2681 \
Paul Bakker23986e52011-04-24 08:57:21 +00002682 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002683 p[n - 1] = '\0'; \
2684 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2685 } \
2686 \
Paul Bakker23986e52011-04-24 08:57:21 +00002687 n -= (unsigned int) ret; \
2688 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002689}
2690
Paul Bakker5121ce52009-01-03 21:22:43 +00002691/*
2692 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002693 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002694 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002695int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002696{
Paul Bakker23986e52011-04-24 08:57:21 +00002697 int ret;
2698 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002699 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002700 const x509_name *name;
Paul Bakker5121ce52009-01-03 21:22:43 +00002701 char s[128], *p;
2702
2703 memset( s, 0, sizeof( s ) );
2704
2705 name = dn;
2706 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002707 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002708
2709 while( name != NULL )
2710 {
Paul Bakkercefb3962012-06-27 11:51:09 +00002711 if( !name->oid.p )
2712 {
2713 name = name->next;
2714 continue;
2715 }
2716
Paul Bakker74111d32011-01-15 16:57:55 +00002717 if( name != dn )
2718 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002719 ret = snprintf( p, n, ", " );
2720 SAFE_SNPRINTF();
2721 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002722
Paul Bakker535e97d2012-08-23 10:49:55 +00002723 if( name->oid.len == 3 &&
2724 memcmp( name->oid.p, OID_X520, 2 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002725 {
2726 switch( name->oid.p[2] )
2727 {
2728 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002729 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002730
2731 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002732 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002733
2734 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002735 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002736
2737 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002738 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002739
2740 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002741 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002742
2743 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002744 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002745
2746 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002747 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002748 name->oid.p[2] );
2749 break;
2750 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002751 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002752 }
Paul Bakker535e97d2012-08-23 10:49:55 +00002753 else if( name->oid.len == 9 &&
2754 memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002755 {
2756 switch( name->oid.p[8] )
2757 {
2758 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002759 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002760
2761 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002762 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002763 name->oid.p[8] );
2764 break;
2765 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002766 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002767 }
2768 else
Paul Bakker74111d32011-01-15 16:57:55 +00002769 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002770 ret = snprintf( p, n, "\?\?=" );
Paul Bakker74111d32011-01-15 16:57:55 +00002771 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002772 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002773
2774 for( i = 0; i < name->val.len; i++ )
2775 {
Paul Bakker27fdf462011-06-09 13:55:13 +00002776 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002777 break;
2778
2779 c = name->val.p[i];
2780 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2781 s[i] = '?';
2782 else s[i] = c;
2783 }
2784 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002785 ret = snprintf( p, n, "%s", s );
2786 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002787 name = name->next;
2788 }
2789
Paul Bakker23986e52011-04-24 08:57:21 +00002790 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002791}
2792
2793/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002794 * Store the serial in printable form into buf; no more
2795 * than size characters will be written
2796 */
2797int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2798{
Paul Bakker23986e52011-04-24 08:57:21 +00002799 int ret;
2800 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00002801 char *p;
2802
2803 p = buf;
2804 n = size;
2805
2806 nr = ( serial->len <= 32 )
Paul Bakker03c7c252011-11-25 12:37:37 +00002807 ? serial->len : 28;
Paul Bakkerdd476992011-01-16 21:34:59 +00002808
2809 for( i = 0; i < nr; i++ )
2810 {
Paul Bakker93048802011-12-05 14:38:06 +00002811 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002812 continue;
2813
Paul Bakkerdd476992011-01-16 21:34:59 +00002814 ret = snprintf( p, n, "%02X%s",
2815 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2816 SAFE_SNPRINTF();
2817 }
2818
Paul Bakker03c7c252011-11-25 12:37:37 +00002819 if( nr != serial->len )
2820 {
2821 ret = snprintf( p, n, "...." );
2822 SAFE_SNPRINTF();
2823 }
2824
Paul Bakker23986e52011-04-24 08:57:21 +00002825 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00002826}
2827
2828/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002829 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002830 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002831int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2832 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002833{
Paul Bakker23986e52011-04-24 08:57:21 +00002834 int ret;
2835 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002836 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00002837
2838 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002839 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002840
Paul Bakkerd98030e2009-05-02 15:13:40 +00002841 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002842 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002843 SAFE_SNPRINTF();
2844 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002845 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002846 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002847
Paul Bakkerdd476992011-01-16 21:34:59 +00002848 ret = x509parse_serial_gets( p, n, &crt->serial);
2849 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002850
Paul Bakkerd98030e2009-05-02 15:13:40 +00002851 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2852 SAFE_SNPRINTF();
2853 ret = x509parse_dn_gets( p, n, &crt->issuer );
2854 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002855
Paul Bakkerd98030e2009-05-02 15:13:40 +00002856 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2857 SAFE_SNPRINTF();
2858 ret = x509parse_dn_gets( p, n, &crt->subject );
2859 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002860
Paul Bakkerd98030e2009-05-02 15:13:40 +00002861 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002862 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2863 crt->valid_from.year, crt->valid_from.mon,
2864 crt->valid_from.day, crt->valid_from.hour,
2865 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002866 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002867
Paul Bakkerd98030e2009-05-02 15:13:40 +00002868 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002869 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2870 crt->valid_to.year, crt->valid_to.mon,
2871 crt->valid_to.day, crt->valid_to.hour,
2872 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002873 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002874
Paul Bakkerd98030e2009-05-02 15:13:40 +00002875 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2876 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002877
Paul Bakker27d66162010-03-17 06:56:01 +00002878 switch( crt->sig_alg )
Paul Bakker5121ce52009-01-03 21:22:43 +00002879 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002880 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2881 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2882 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2883 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2884 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2885 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2886 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2887 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2888 default: ret = snprintf( p, n, "???" ); break;
2889 }
2890 SAFE_SNPRINTF();
2891
2892 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
Paul Bakker5c2364c2012-10-01 14:41:15 +00002893 (int) crt->rsa.N.n * (int) sizeof( t_uint ) * 8 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002894 SAFE_SNPRINTF();
2895
Paul Bakker23986e52011-04-24 08:57:21 +00002896 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002897}
2898
Paul Bakker74111d32011-01-15 16:57:55 +00002899/*
2900 * Return an informational string describing the given OID
2901 */
2902const char *x509_oid_get_description( x509_buf *oid )
2903{
2904 if ( oid == NULL )
2905 return ( NULL );
2906
2907 else if( OID_CMP( OID_SERVER_AUTH, oid ) )
2908 return( STRING_SERVER_AUTH );
2909
2910 else if( OID_CMP( OID_CLIENT_AUTH, oid ) )
2911 return( STRING_CLIENT_AUTH );
2912
2913 else if( OID_CMP( OID_CODE_SIGNING, oid ) )
2914 return( STRING_CODE_SIGNING );
2915
2916 else if( OID_CMP( OID_EMAIL_PROTECTION, oid ) )
2917 return( STRING_EMAIL_PROTECTION );
2918
2919 else if( OID_CMP( OID_TIME_STAMPING, oid ) )
2920 return( STRING_TIME_STAMPING );
2921
2922 else if( OID_CMP( OID_OCSP_SIGNING, oid ) )
2923 return( STRING_OCSP_SIGNING );
2924
2925 return( NULL );
2926}
2927
2928/* Return the x.y.z.... style numeric string for the given OID */
2929int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2930{
Paul Bakker23986e52011-04-24 08:57:21 +00002931 int ret;
2932 size_t i, n;
Paul Bakker74111d32011-01-15 16:57:55 +00002933 unsigned int value;
2934 char *p;
2935
2936 p = buf;
2937 n = size;
2938
2939 /* First byte contains first two dots */
2940 if( oid->len > 0 )
2941 {
2942 ret = snprintf( p, n, "%d.%d", oid->p[0]/40, oid->p[0]%40 );
2943 SAFE_SNPRINTF();
2944 }
2945
2946 /* TODO: value can overflow in value. */
2947 value = 0;
Paul Bakker23986e52011-04-24 08:57:21 +00002948 for( i = 1; i < oid->len; i++ )
Paul Bakker74111d32011-01-15 16:57:55 +00002949 {
2950 value <<= 7;
2951 value += oid->p[i] & 0x7F;
2952
2953 if( !( oid->p[i] & 0x80 ) )
2954 {
2955 /* Last byte */
2956 ret = snprintf( p, n, ".%d", value );
2957 SAFE_SNPRINTF();
2958 value = 0;
2959 }
2960 }
2961
Paul Bakker23986e52011-04-24 08:57:21 +00002962 return( (int) ( size - n ) );
Paul Bakker74111d32011-01-15 16:57:55 +00002963}
2964
Paul Bakkerd98030e2009-05-02 15:13:40 +00002965/*
2966 * Return an informational string about the CRL.
2967 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002968int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2969 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002970{
Paul Bakker23986e52011-04-24 08:57:21 +00002971 int ret;
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002972 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002973 char *p;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002974 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002975
2976 p = buf;
2977 n = size;
2978
2979 ret = snprintf( p, n, "%sCRL version : %d",
2980 prefix, crl->version );
2981 SAFE_SNPRINTF();
2982
2983 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2984 SAFE_SNPRINTF();
2985 ret = x509parse_dn_gets( p, n, &crl->issuer );
2986 SAFE_SNPRINTF();
2987
2988 ret = snprintf( p, n, "\n%sthis update : " \
2989 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2990 crl->this_update.year, crl->this_update.mon,
2991 crl->this_update.day, crl->this_update.hour,
2992 crl->this_update.min, crl->this_update.sec );
2993 SAFE_SNPRINTF();
2994
2995 ret = snprintf( p, n, "\n%snext update : " \
2996 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2997 crl->next_update.year, crl->next_update.mon,
2998 crl->next_update.day, crl->next_update.hour,
2999 crl->next_update.min, crl->next_update.sec );
3000 SAFE_SNPRINTF();
3001
3002 entry = &crl->entry;
3003
3004 ret = snprintf( p, n, "\n%sRevoked certificates:",
3005 prefix );
3006 SAFE_SNPRINTF();
3007
Paul Bakker9be19372009-07-27 20:21:53 +00003008 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003009 {
3010 ret = snprintf( p, n, "\n%sserial number: ",
3011 prefix );
3012 SAFE_SNPRINTF();
3013
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003014 ret = x509parse_serial_gets( p, n, &entry->serial);
3015 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003016
Paul Bakkerd98030e2009-05-02 15:13:40 +00003017 ret = snprintf( p, n, " revocation date: " \
3018 "%04d-%02d-%02d %02d:%02d:%02d",
3019 entry->revocation_date.year, entry->revocation_date.mon,
3020 entry->revocation_date.day, entry->revocation_date.hour,
3021 entry->revocation_date.min, entry->revocation_date.sec );
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003022 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003023
3024 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003025 }
3026
Paul Bakkerd98030e2009-05-02 15:13:40 +00003027 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
3028 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003029
Paul Bakker27d66162010-03-17 06:56:01 +00003030 switch( crl->sig_alg )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003031 {
3032 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
3033 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
3034 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
3035 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
3036 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
3037 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
3038 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
3039 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
3040 default: ret = snprintf( p, n, "???" ); break;
3041 }
3042 SAFE_SNPRINTF();
3043
Paul Bakker1e27bb22009-07-19 20:25:25 +00003044 ret = snprintf( p, n, "\n" );
3045 SAFE_SNPRINTF();
3046
Paul Bakker23986e52011-04-24 08:57:21 +00003047 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003048}
3049
3050/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00003051 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00003052 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003053int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00003054{
Paul Bakkercce9d772011-11-18 14:26:47 +00003055 int year, mon, day;
3056 int hour, min, sec;
3057
3058#if defined(_WIN32)
3059 SYSTEMTIME st;
3060
3061 GetLocalTime(&st);
3062
3063 year = st.wYear;
3064 mon = st.wMonth;
3065 day = st.wDay;
3066 hour = st.wHour;
3067 min = st.wMinute;
3068 sec = st.wSecond;
3069#else
Paul Bakker5121ce52009-01-03 21:22:43 +00003070 struct tm *lt;
3071 time_t tt;
3072
3073 tt = time( NULL );
3074 lt = localtime( &tt );
3075
Paul Bakkercce9d772011-11-18 14:26:47 +00003076 year = lt->tm_year + 1900;
3077 mon = lt->tm_mon + 1;
3078 day = lt->tm_mday;
3079 hour = lt->tm_hour;
3080 min = lt->tm_min;
3081 sec = lt->tm_sec;
3082#endif
3083
3084 if( year > to->year )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003085 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003086
Paul Bakkercce9d772011-11-18 14:26:47 +00003087 if( year == to->year &&
3088 mon > to->mon )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003089 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003090
Paul Bakkercce9d772011-11-18 14:26:47 +00003091 if( year == to->year &&
3092 mon == to->mon &&
3093 day > to->day )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003094 return( 1 );
3095
Paul Bakkercce9d772011-11-18 14:26:47 +00003096 if( year == to->year &&
3097 mon == to->mon &&
3098 day == to->day &&
3099 hour > to->hour )
Paul Bakkerb6194992011-01-16 21:40:22 +00003100 return( 1 );
3101
Paul Bakkercce9d772011-11-18 14:26:47 +00003102 if( year == to->year &&
3103 mon == to->mon &&
3104 day == to->day &&
3105 hour == to->hour &&
3106 min > to->min )
Paul Bakkerb6194992011-01-16 21:40:22 +00003107 return( 1 );
3108
Paul Bakkercce9d772011-11-18 14:26:47 +00003109 if( year == to->year &&
3110 mon == to->mon &&
3111 day == to->day &&
3112 hour == to->hour &&
3113 min == to->min &&
3114 sec > to->sec )
Paul Bakkerb6194992011-01-16 21:40:22 +00003115 return( 1 );
3116
Paul Bakker40ea7de2009-05-03 10:18:48 +00003117 return( 0 );
3118}
3119
3120/*
3121 * Return 1 if the certificate is revoked, or 0 otherwise.
3122 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003123int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003124{
Paul Bakkerff60ee62010-03-16 21:09:09 +00003125 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00003126
3127 while( cur != NULL && cur->serial.len != 0 )
3128 {
Paul Bakkera056efc2011-01-16 21:38:35 +00003129 if( crt->serial.len == cur->serial.len &&
3130 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003131 {
3132 if( x509parse_time_expired( &cur->revocation_date ) )
3133 return( 1 );
3134 }
3135
3136 cur = cur->next;
3137 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003138
3139 return( 0 );
3140}
3141
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003142/*
3143 * Wrapper for x509 hashes.
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003144 */
Paul Bakker23986e52011-04-24 08:57:21 +00003145static void x509_hash( const unsigned char *in, size_t len, int alg,
Paul Bakker5121ce52009-01-03 21:22:43 +00003146 unsigned char *out )
3147{
3148 switch( alg )
3149 {
Paul Bakker40e46942009-01-03 21:51:57 +00003150#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003151 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003152#endif
Paul Bakker40e46942009-01-03 21:51:57 +00003153#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003154 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003155#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003156#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003157 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003158#endif
3159#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003160 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003161#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00003162#if defined(POLARSSL_SHA2_C)
3163 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
3164 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
3165#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00003166#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003167 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
3168 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
3169#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003170 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003171 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003172 break;
3173 }
3174}
3175
3176/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00003177 * Check that the given certificate is valid accoring to the CRL.
3178 */
3179static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
3180 x509_crl *crl_list)
3181{
3182 int flags = 0;
3183 int hash_id;
3184 unsigned char hash[64];
3185
Paul Bakker915275b2012-09-28 07:10:55 +00003186 if( ca == NULL )
3187 return( flags );
3188
Paul Bakker76fd75a2011-01-16 21:12:10 +00003189 /*
3190 * TODO: What happens if no CRL is present?
3191 * Suggestion: Revocation state should be unknown if no CRL is present.
3192 * For backwards compatibility this is not yet implemented.
3193 */
3194
Paul Bakker915275b2012-09-28 07:10:55 +00003195 while( crl_list != NULL )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003196 {
Paul Bakker915275b2012-09-28 07:10:55 +00003197 if( crl_list->version == 0 ||
3198 crl_list->issuer_raw.len != ca->subject_raw.len ||
Paul Bakker76fd75a2011-01-16 21:12:10 +00003199 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
3200 crl_list->issuer_raw.len ) != 0 )
3201 {
3202 crl_list = crl_list->next;
3203 continue;
3204 }
3205
3206 /*
3207 * Check if CRL is correctly signed by the trusted CA
3208 */
3209 hash_id = crl_list->sig_alg;
3210
3211 x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
3212
3213 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, hash_id,
3214 0, hash, crl_list->sig.p ) == 0 )
3215 {
3216 /*
3217 * CRL is not trusted
3218 */
3219 flags |= BADCRL_NOT_TRUSTED;
3220 break;
3221 }
3222
3223 /*
3224 * Check for validity of CRL (Do not drop out)
3225 */
3226 if( x509parse_time_expired( &crl_list->next_update ) )
3227 flags |= BADCRL_EXPIRED;
3228
3229 /*
3230 * Check if certificate is revoked
3231 */
3232 if( x509parse_revoked(crt, crl_list) )
3233 {
3234 flags |= BADCERT_REVOKED;
3235 break;
3236 }
3237
3238 crl_list = crl_list->next;
3239 }
3240 return flags;
3241}
3242
Paul Bakker57b12982012-02-11 17:38:38 +00003243int x509_wildcard_verify( const char *cn, x509_buf *name )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003244{
3245 size_t i;
3246 size_t cn_idx = 0;
3247
Paul Bakker57b12982012-02-11 17:38:38 +00003248 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003249 return( 0 );
3250
3251 for( i = 0; i < strlen( cn ); ++i )
3252 {
3253 if( cn[i] == '.' )
3254 {
3255 cn_idx = i;
3256 break;
3257 }
3258 }
3259
3260 if( cn_idx == 0 )
3261 return( 0 );
3262
Paul Bakker535e97d2012-08-23 10:49:55 +00003263 if( strlen( cn ) - cn_idx == name->len - 1 &&
3264 memcmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003265 {
3266 return( 1 );
3267 }
3268
3269 return( 0 );
3270}
3271
Paul Bakker915275b2012-09-28 07:10:55 +00003272static int x509parse_verify_top(
3273 x509_cert *child, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003274 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003275 int (*f_vrfy)(void *, x509_cert *, int, int *),
3276 void *p_vrfy )
3277{
3278 int hash_id, ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003279 int ca_flags = 0, check_path_cnt = path_cnt + 1;
Paul Bakker915275b2012-09-28 07:10:55 +00003280 unsigned char hash[64];
3281
3282 if( x509parse_time_expired( &child->valid_to ) )
3283 *flags |= BADCERT_EXPIRED;
3284
3285 /*
3286 * Child is the top of the chain. Check against the trust_ca list.
3287 */
3288 *flags |= BADCERT_NOT_TRUSTED;
3289
3290 while( trust_ca != NULL )
3291 {
3292 if( trust_ca->version == 0 ||
3293 child->issuer_raw.len != trust_ca->subject_raw.len ||
3294 memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
3295 child->issuer_raw.len ) != 0 )
3296 {
3297 trust_ca = trust_ca->next;
3298 continue;
3299 }
3300
Paul Bakker9a736322012-11-14 12:39:52 +00003301 /*
3302 * Reduce path_len to check against if top of the chain is
3303 * the same as the trusted CA
3304 */
3305 if( child->subject_raw.len == trust_ca->subject_raw.len &&
3306 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3307 child->issuer_raw.len ) == 0 )
3308 {
3309 check_path_cnt--;
3310 }
3311
Paul Bakker915275b2012-09-28 07:10:55 +00003312 if( trust_ca->max_pathlen > 0 &&
Paul Bakker9a736322012-11-14 12:39:52 +00003313 trust_ca->max_pathlen < check_path_cnt )
Paul Bakker915275b2012-09-28 07:10:55 +00003314 {
3315 trust_ca = trust_ca->next;
3316 continue;
3317 }
3318
3319 hash_id = child->sig_alg;
3320
3321 x509_hash( child->tbs.p, child->tbs.len, hash_id, hash );
3322
3323 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
3324 0, hash, child->sig.p ) != 0 )
3325 {
3326 trust_ca = trust_ca->next;
3327 continue;
3328 }
3329
3330 /*
3331 * Top of chain is signed by a trusted CA
3332 */
3333 *flags &= ~BADCERT_NOT_TRUSTED;
3334 break;
3335 }
3336
Paul Bakker9a736322012-11-14 12:39:52 +00003337 /*
Paul Bakker3497d8c2012-11-24 11:53:17 +01003338 * If top of chain is not the same as the trusted CA send a verify request
3339 * to the callback for any issues with validity and CRL presence for the
3340 * trusted CA certificate.
Paul Bakker9a736322012-11-14 12:39:52 +00003341 */
3342 if( trust_ca != NULL &&
3343 ( child->subject_raw.len != trust_ca->subject_raw.len ||
3344 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3345 child->issuer_raw.len ) != 0 ) )
Paul Bakker915275b2012-09-28 07:10:55 +00003346 {
3347 /* Check trusted CA's CRL for then chain's top crt */
3348 *flags |= x509parse_verifycrl( child, trust_ca, ca_crl );
3349
3350 if( x509parse_time_expired( &trust_ca->valid_to ) )
3351 ca_flags |= BADCERT_EXPIRED;
3352
Paul Bakker915275b2012-09-28 07:10:55 +00003353 if( NULL != f_vrfy )
3354 {
Paul Bakker9a736322012-11-14 12:39:52 +00003355 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003356 return( ret );
3357 }
3358 }
3359
3360 /* Call callback on top cert */
3361 if( NULL != f_vrfy )
3362 {
Paul Bakker9a736322012-11-14 12:39:52 +00003363 if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003364 return( ret );
3365 }
3366
Paul Bakker915275b2012-09-28 07:10:55 +00003367 *flags |= ca_flags;
3368
3369 return( 0 );
3370}
3371
3372static int x509parse_verify_child(
3373 x509_cert *child, x509_cert *parent, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003374 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003375 int (*f_vrfy)(void *, x509_cert *, int, int *),
3376 void *p_vrfy )
3377{
3378 int hash_id, ret;
3379 int parent_flags = 0;
3380 unsigned char hash[64];
3381 x509_cert *grandparent;
3382
3383 if( x509parse_time_expired( &child->valid_to ) )
3384 *flags |= BADCERT_EXPIRED;
3385
3386 hash_id = child->sig_alg;
3387
3388 x509_hash( child->tbs.p, child->tbs.len, hash_id, hash );
3389
3390 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, hash_id, 0, hash,
3391 child->sig.p ) != 0 )
3392 *flags |= BADCERT_NOT_TRUSTED;
3393
3394 /* Check trusted CA's CRL for the given crt */
3395 *flags |= x509parse_verifycrl(child, parent, ca_crl);
3396
3397 grandparent = parent->next;
3398
3399 while( grandparent != NULL )
3400 {
3401 if( grandparent->version == 0 ||
3402 grandparent->ca_istrue == 0 ||
3403 parent->issuer_raw.len != grandparent->subject_raw.len ||
3404 memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
3405 parent->issuer_raw.len ) != 0 )
3406 {
3407 grandparent = grandparent->next;
3408 continue;
3409 }
3410 break;
3411 }
3412
Paul Bakker915275b2012-09-28 07:10:55 +00003413 if( grandparent != NULL )
3414 {
3415 /*
3416 * Part of the chain
3417 */
Paul Bakker9a736322012-11-14 12:39:52 +00003418 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 +00003419 if( ret != 0 )
3420 return( ret );
3421 }
3422 else
3423 {
Paul Bakker9a736322012-11-14 12:39:52 +00003424 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 +00003425 if( ret != 0 )
3426 return( ret );
3427 }
3428
3429 /* child is verified to be a child of the parent, call verify callback */
3430 if( NULL != f_vrfy )
Paul Bakker9a736322012-11-14 12:39:52 +00003431 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003432 return( ret );
Paul Bakker915275b2012-09-28 07:10:55 +00003433
3434 *flags |= parent_flags;
3435
3436 return( 0 );
3437}
3438
Paul Bakker76fd75a2011-01-16 21:12:10 +00003439/*
Paul Bakker5121ce52009-01-03 21:22:43 +00003440 * Verify the certificate validity
3441 */
3442int x509parse_verify( x509_cert *crt,
3443 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00003444 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003445 const char *cn, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003446 int (*f_vrfy)(void *, x509_cert *, int, int *),
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003447 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00003448{
Paul Bakker23986e52011-04-24 08:57:21 +00003449 size_t cn_len;
Paul Bakker915275b2012-09-28 07:10:55 +00003450 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003451 int pathlen = 0;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003452 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00003453 x509_name *name;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003454 x509_sequence *cur = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003455
Paul Bakker40ea7de2009-05-03 10:18:48 +00003456 *flags = 0;
3457
Paul Bakker5121ce52009-01-03 21:22:43 +00003458 if( cn != NULL )
3459 {
3460 name = &crt->subject;
3461 cn_len = strlen( cn );
3462
Paul Bakker4d2c1242012-05-10 14:12:46 +00003463 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
Paul Bakker5121ce52009-01-03 21:22:43 +00003464 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00003465 cur = &crt->subject_alt_names;
3466
3467 while( cur != NULL )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003468 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003469 if( cur->buf.len == cn_len &&
3470 memcmp( cn, cur->buf.p, cn_len ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003471 break;
3472
Paul Bakker535e97d2012-08-23 10:49:55 +00003473 if( cur->buf.len > 2 &&
3474 memcmp( cur->buf.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003475 x509_wildcard_verify( cn, &cur->buf ) )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003476 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003477
Paul Bakker4d2c1242012-05-10 14:12:46 +00003478 cur = cur->next;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003479 }
3480
3481 if( cur == NULL )
3482 *flags |= BADCERT_CN_MISMATCH;
3483 }
Paul Bakker4d2c1242012-05-10 14:12:46 +00003484 else
3485 {
3486 while( name != NULL )
3487 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003488 if( name->oid.len == 3 &&
3489 memcmp( name->oid.p, OID_CN, 3 ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003490 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003491 if( name->val.len == cn_len &&
3492 memcmp( name->val.p, cn, cn_len ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003493 break;
3494
Paul Bakker535e97d2012-08-23 10:49:55 +00003495 if( name->val.len > 2 &&
3496 memcmp( name->val.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003497 x509_wildcard_verify( cn, &name->val ) )
3498 break;
3499 }
3500
3501 name = name->next;
3502 }
3503
3504 if( name == NULL )
3505 *flags |= BADCERT_CN_MISMATCH;
3506 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003507 }
3508
Paul Bakker5121ce52009-01-03 21:22:43 +00003509 /*
Paul Bakker915275b2012-09-28 07:10:55 +00003510 * Iterate upwards in the given cert chain, to find our crt parent.
3511 * Ignore any upper cert with CA != TRUE.
Paul Bakker5121ce52009-01-03 21:22:43 +00003512 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003513 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003514
Paul Bakker76fd75a2011-01-16 21:12:10 +00003515 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003516 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003517 if( parent->ca_istrue == 0 ||
3518 crt->issuer_raw.len != parent->subject_raw.len ||
3519 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00003520 crt->issuer_raw.len ) != 0 )
3521 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003522 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003523 continue;
3524 }
Paul Bakker915275b2012-09-28 07:10:55 +00003525 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003526 }
3527
Paul Bakker915275b2012-09-28 07:10:55 +00003528 if( parent != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003529 {
Paul Bakker915275b2012-09-28 07:10:55 +00003530 /*
3531 * Part of the chain
3532 */
Paul Bakker9a736322012-11-14 12:39:52 +00003533 ret = x509parse_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003534 if( ret != 0 )
3535 return( ret );
3536 }
3537 else
Paul Bakker74111d32011-01-15 16:57:55 +00003538 {
Paul Bakker9a736322012-11-14 12:39:52 +00003539 ret = x509parse_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003540 if( ret != 0 )
3541 return( ret );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003542 }
Paul Bakker915275b2012-09-28 07:10:55 +00003543
3544 if( *flags != 0 )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003545 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003546
Paul Bakker5121ce52009-01-03 21:22:43 +00003547 return( 0 );
3548}
3549
3550/*
3551 * Unallocate all certificate data
3552 */
3553void x509_free( x509_cert *crt )
3554{
3555 x509_cert *cert_cur = crt;
3556 x509_cert *cert_prv;
3557 x509_name *name_cur;
3558 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00003559 x509_sequence *seq_cur;
3560 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00003561
3562 if( crt == NULL )
3563 return;
3564
3565 do
3566 {
3567 rsa_free( &cert_cur->rsa );
3568
3569 name_cur = cert_cur->issuer.next;
3570 while( name_cur != NULL )
3571 {
3572 name_prv = name_cur;
3573 name_cur = name_cur->next;
3574 memset( name_prv, 0, sizeof( x509_name ) );
3575 free( name_prv );
3576 }
3577
3578 name_cur = cert_cur->subject.next;
3579 while( name_cur != NULL )
3580 {
3581 name_prv = name_cur;
3582 name_cur = name_cur->next;
3583 memset( name_prv, 0, sizeof( x509_name ) );
3584 free( name_prv );
3585 }
3586
Paul Bakker74111d32011-01-15 16:57:55 +00003587 seq_cur = cert_cur->ext_key_usage.next;
3588 while( seq_cur != NULL )
3589 {
3590 seq_prv = seq_cur;
3591 seq_cur = seq_cur->next;
3592 memset( seq_prv, 0, sizeof( x509_sequence ) );
3593 free( seq_prv );
3594 }
3595
Paul Bakker8afa70d2012-02-11 18:42:45 +00003596 seq_cur = cert_cur->subject_alt_names.next;
3597 while( seq_cur != NULL )
3598 {
3599 seq_prv = seq_cur;
3600 seq_cur = seq_cur->next;
3601 memset( seq_prv, 0, sizeof( x509_sequence ) );
3602 free( seq_prv );
3603 }
3604
Paul Bakker5121ce52009-01-03 21:22:43 +00003605 if( cert_cur->raw.p != NULL )
3606 {
3607 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
3608 free( cert_cur->raw.p );
3609 }
3610
3611 cert_cur = cert_cur->next;
3612 }
3613 while( cert_cur != NULL );
3614
3615 cert_cur = crt;
3616 do
3617 {
3618 cert_prv = cert_cur;
3619 cert_cur = cert_cur->next;
3620
3621 memset( cert_prv, 0, sizeof( x509_cert ) );
3622 if( cert_prv != crt )
3623 free( cert_prv );
3624 }
3625 while( cert_cur != NULL );
3626}
3627
Paul Bakkerd98030e2009-05-02 15:13:40 +00003628/*
3629 * Unallocate all CRL data
3630 */
3631void x509_crl_free( x509_crl *crl )
3632{
3633 x509_crl *crl_cur = crl;
3634 x509_crl *crl_prv;
3635 x509_name *name_cur;
3636 x509_name *name_prv;
3637 x509_crl_entry *entry_cur;
3638 x509_crl_entry *entry_prv;
3639
3640 if( crl == NULL )
3641 return;
3642
3643 do
3644 {
3645 name_cur = crl_cur->issuer.next;
3646 while( name_cur != NULL )
3647 {
3648 name_prv = name_cur;
3649 name_cur = name_cur->next;
3650 memset( name_prv, 0, sizeof( x509_name ) );
3651 free( name_prv );
3652 }
3653
3654 entry_cur = crl_cur->entry.next;
3655 while( entry_cur != NULL )
3656 {
3657 entry_prv = entry_cur;
3658 entry_cur = entry_cur->next;
3659 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
3660 free( entry_prv );
3661 }
3662
3663 if( crl_cur->raw.p != NULL )
3664 {
3665 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
3666 free( crl_cur->raw.p );
3667 }
3668
3669 crl_cur = crl_cur->next;
3670 }
3671 while( crl_cur != NULL );
3672
3673 crl_cur = crl;
3674 do
3675 {
3676 crl_prv = crl_cur;
3677 crl_cur = crl_cur->next;
3678
3679 memset( crl_prv, 0, sizeof( x509_crl ) );
3680 if( crl_prv != crl )
3681 free( crl_prv );
3682 }
3683 while( crl_cur != NULL );
3684}
3685
Paul Bakker40e46942009-01-03 21:51:57 +00003686#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00003687
Paul Bakker40e46942009-01-03 21:51:57 +00003688#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00003689
3690/*
3691 * Checkup routine
3692 */
3693int x509_self_test( int verbose )
3694{
Paul Bakker5690efc2011-05-26 13:16:06 +00003695#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00003696 int ret;
3697 int flags;
3698 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00003699 x509_cert cacert;
3700 x509_cert clicert;
3701 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00003702#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003703 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00003704#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003705
3706 if( verbose != 0 )
3707 printf( " X.509 certificate load: " );
3708
3709 memset( &clicert, 0, sizeof( x509_cert ) );
3710
Paul Bakkereae09db2013-06-06 12:35:54 +02003711 ret = x509parse_crt( &clicert, (const unsigned char *) test_cli_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003712 strlen( test_cli_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003713 if( ret != 0 )
3714 {
3715 if( verbose != 0 )
3716 printf( "failed\n" );
3717
3718 return( ret );
3719 }
3720
3721 memset( &cacert, 0, sizeof( x509_cert ) );
3722
Paul Bakkereae09db2013-06-06 12:35:54 +02003723 ret = x509parse_crt( &cacert, (const unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003724 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003725 if( ret != 0 )
3726 {
3727 if( verbose != 0 )
3728 printf( "failed\n" );
3729
3730 return( ret );
3731 }
3732
3733 if( verbose != 0 )
3734 printf( "passed\n X.509 private key load: " );
3735
3736 i = strlen( test_ca_key );
3737 j = strlen( test_ca_pwd );
3738
Paul Bakker66b78b22011-03-25 14:22:50 +00003739 rsa_init( &rsa, RSA_PKCS_V15, 0 );
3740
Paul Bakker5121ce52009-01-03 21:22:43 +00003741 if( ( ret = x509parse_key( &rsa,
Paul Bakkereae09db2013-06-06 12:35:54 +02003742 (const unsigned char *) test_ca_key, i,
3743 (const unsigned char *) test_ca_pwd, j ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003744 {
3745 if( verbose != 0 )
3746 printf( "failed\n" );
3747
3748 return( ret );
3749 }
3750
3751 if( verbose != 0 )
3752 printf( "passed\n X.509 signature verify: ");
3753
Paul Bakker23986e52011-04-24 08:57:21 +00003754 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003755 if( ret != 0 )
3756 {
Paul Bakker23986e52011-04-24 08:57:21 +00003757 printf("%02x", flags);
Paul Bakker5121ce52009-01-03 21:22:43 +00003758 if( verbose != 0 )
3759 printf( "failed\n" );
3760
3761 return( ret );
3762 }
3763
Paul Bakker5690efc2011-05-26 13:16:06 +00003764#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003765 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003766 printf( "passed\n X.509 DHM parameter load: " );
3767
3768 i = strlen( test_dhm_params );
3769 j = strlen( test_ca_pwd );
3770
Paul Bakkereae09db2013-06-06 12:35:54 +02003771 if( ( ret = x509parse_dhm( &dhm, (const unsigned char *) test_dhm_params, i ) ) != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003772 {
3773 if( verbose != 0 )
3774 printf( "failed\n" );
3775
3776 return( ret );
3777 }
3778
3779 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003780 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00003781#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003782
3783 x509_free( &cacert );
3784 x509_free( &clicert );
3785 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00003786#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003787 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00003788#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003789
3790 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003791#else
3792 ((void) verbose);
3793 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3794#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003795}
3796
3797#endif
3798
3799#endif