blob: a4de9025260ca3d5a989fea979c9a09723ac0e52 [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 )
Paul Bakker65a19092013-06-06 21:14:58 +02002358 return( ret );
Paul Bakker65a19092013-06-06 21:14:58 +02002359
2360 ret = pem_read_buffer( &pem,
2361 "-----BEGIN PRIVATE KEY-----",
2362 "-----END PRIVATE KEY-----",
2363 key, NULL, 0, &len );
2364 if( ret == 0 )
2365 {
2366 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa,
2367 pem.buf, pem.buflen ) ) != 0 )
2368 {
2369 rsa_free( rsa );
2370 }
2371
2372 pem_free( &pem );
2373 return( ret );
2374 }
2375 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker65a19092013-06-06 21:14:58 +02002376 return( ret );
Paul Bakker65a19092013-06-06 21:14:58 +02002377
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002378 ret = pem_read_buffer( &pem,
2379 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
2380 "-----END ENCRYPTED PRIVATE KEY-----",
2381 key, NULL, 0, &len );
2382 if( ret == 0 )
2383 {
2384 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa,
2385 pem.buf, pem.buflen,
2386 pwd, pwdlen ) ) != 0 )
2387 {
2388 rsa_free( rsa );
2389 }
2390
2391 pem_free( &pem );
2392 return( ret );
2393 }
2394 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002395 return( ret );
Paul Bakker65a19092013-06-06 21:14:58 +02002396#else
2397 ((void) pwd);
2398 ((void) pwdlen);
2399#endif /* POLARSSL_PEM_C */
2400
2401 // At this point we only know it's not a PEM formatted key. Could be any
2402 // of the known DER encoded private key formats
2403 //
2404 // We try the different DER format parsers to see if one passes without
2405 // error
2406 //
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002407 if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa, key, keylen,
2408 pwd, pwdlen ) ) == 0 )
Paul Bakker65a19092013-06-06 21:14:58 +02002409 {
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002410 return( 0 );
Paul Bakker65a19092013-06-06 21:14:58 +02002411 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002412
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002413 rsa_free( rsa );
Paul Bakker1fd43212013-06-17 15:14:42 +02002414
2415 if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH )
2416 {
2417 return( ret );
2418 }
2419
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002420 if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa, key, keylen ) ) == 0 )
2421 return( 0 );
2422
2423 rsa_free( rsa );
Paul Bakker1fd43212013-06-17 15:14:42 +02002424
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002425 if( ( ret = x509parse_key_pkcs1_der( rsa, key, keylen ) ) == 0 )
2426 return( 0 );
2427
2428 rsa_free( rsa );
Paul Bakker1fd43212013-06-17 15:14:42 +02002429
Paul Bakkercf6e95d2013-06-12 13:18:15 +02002430 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00002431}
2432
2433/*
Paul Bakker53019ae2011-03-25 13:58:48 +00002434 * Parse a public RSA key
2435 */
Paul Bakker23986e52011-04-24 08:57:21 +00002436int x509parse_public_key( rsa_context *rsa, const unsigned char *key, size_t keylen )
Paul Bakker53019ae2011-03-25 13:58:48 +00002437{
Paul Bakker23986e52011-04-24 08:57:21 +00002438 int ret;
2439 size_t len;
Paul Bakker53019ae2011-03-25 13:58:48 +00002440 unsigned char *p, *end;
2441 x509_buf alg_oid;
2442#if defined(POLARSSL_PEM_C)
2443 pem_context pem;
2444
2445 pem_init( &pem );
2446 ret = pem_read_buffer( &pem,
2447 "-----BEGIN PUBLIC KEY-----",
2448 "-----END PUBLIC KEY-----",
2449 key, NULL, 0, &len );
2450
2451 if( ret == 0 )
2452 {
2453 /*
2454 * Was PEM encoded
2455 */
2456 keylen = pem.buflen;
2457 }
Paul Bakker9255e832013-06-06 14:58:28 +02002458 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker53019ae2011-03-25 13:58:48 +00002459 {
2460 pem_free( &pem );
2461 return( ret );
2462 }
2463
2464 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2465#else
2466 p = (unsigned char *) key;
2467#endif
2468 end = p + keylen;
2469
2470 /*
2471 * PublicKeyInfo ::= SEQUENCE {
2472 * algorithm AlgorithmIdentifier,
2473 * PublicKey BIT STRING
2474 * }
2475 *
2476 * AlgorithmIdentifier ::= SEQUENCE {
2477 * algorithm OBJECT IDENTIFIER,
2478 * parameters ANY DEFINED BY algorithm OPTIONAL
2479 * }
2480 *
2481 * RSAPublicKey ::= SEQUENCE {
2482 * modulus INTEGER, -- n
2483 * publicExponent INTEGER -- e
2484 * }
2485 */
2486
2487 if( ( ret = asn1_get_tag( &p, end, &len,
2488 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2489 {
2490#if defined(POLARSSL_PEM_C)
2491 pem_free( &pem );
2492#endif
2493 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002494 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002495 }
2496
2497 if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 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_KEY_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002504 }
2505
2506 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
2507 {
2508#if defined(POLARSSL_PEM_C)
2509 pem_free( &pem );
2510#endif
2511 rsa_free( rsa );
2512 return( ret );
2513 }
2514
2515 rsa->len = mpi_size( &rsa->N );
2516
2517#if defined(POLARSSL_PEM_C)
2518 pem_free( &pem );
2519#endif
2520
2521 return( 0 );
2522}
2523
Paul Bakkereaa89f82011-04-04 21:36:15 +00002524#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00002525/*
Paul Bakker1b57b062011-01-06 15:48:19 +00002526 * Parse DHM parameters
2527 */
Paul Bakker23986e52011-04-24 08:57:21 +00002528int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
Paul Bakker1b57b062011-01-06 15:48:19 +00002529{
Paul Bakker23986e52011-04-24 08:57:21 +00002530 int ret;
2531 size_t len;
Paul Bakker1b57b062011-01-06 15:48:19 +00002532 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00002533#if defined(POLARSSL_PEM_C)
2534 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00002535
Paul Bakker96743fc2011-02-12 14:30:57 +00002536 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00002537
Paul Bakker96743fc2011-02-12 14:30:57 +00002538 ret = pem_read_buffer( &pem,
2539 "-----BEGIN DH PARAMETERS-----",
2540 "-----END DH PARAMETERS-----",
2541 dhmin, NULL, 0, &dhminlen );
2542
2543 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00002544 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002545 /*
2546 * Was PEM encoded
2547 */
2548 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00002549 }
Paul Bakker9255e832013-06-06 14:58:28 +02002550 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00002551 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002552 pem_free( &pem );
2553 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002554 }
2555
Paul Bakker96743fc2011-02-12 14:30:57 +00002556 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
2557#else
2558 p = (unsigned char *) dhmin;
2559#endif
2560 end = p + dhminlen;
2561
Paul Bakker1b57b062011-01-06 15:48:19 +00002562 memset( dhm, 0, sizeof( dhm_context ) );
2563
Paul Bakker1b57b062011-01-06 15:48:19 +00002564 /*
2565 * DHParams ::= SEQUENCE {
2566 * prime INTEGER, -- P
2567 * generator INTEGER, -- g
2568 * }
2569 */
2570 if( ( ret = asn1_get_tag( &p, end, &len,
2571 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2572 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002573#if defined(POLARSSL_PEM_C)
2574 pem_free( &pem );
2575#endif
Paul Bakker9d781402011-05-09 16:17:09 +00002576 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002577 }
2578
2579 end = p + len;
2580
2581 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
2582 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
2583 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002584#if defined(POLARSSL_PEM_C)
2585 pem_free( &pem );
2586#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002587 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002588 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002589 }
2590
2591 if( p != end )
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 +
Paul Bakker1b57b062011-01-06 15:48:19 +00002598 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
2599 }
2600
Paul Bakker96743fc2011-02-12 14:30:57 +00002601#if defined(POLARSSL_PEM_C)
2602 pem_free( &pem );
2603#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002604
2605 return( 0 );
2606}
2607
Paul Bakker335db3f2011-04-25 15:28:35 +00002608#if defined(POLARSSL_FS_IO)
Paul Bakker1b57b062011-01-06 15:48:19 +00002609/*
2610 * Load and parse a private RSA key
2611 */
2612int x509parse_dhmfile( dhm_context *dhm, const char *path )
2613{
2614 int ret;
2615 size_t n;
2616 unsigned char *buf;
2617
Paul Bakker69e095c2011-12-10 21:55:01 +00002618 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
2619 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002620
Paul Bakker27fdf462011-06-09 13:55:13 +00002621 ret = x509parse_dhm( dhm, buf, n );
Paul Bakker1b57b062011-01-06 15:48:19 +00002622
2623 memset( buf, 0, n + 1 );
2624 free( buf );
2625
2626 return( ret );
2627}
Paul Bakker335db3f2011-04-25 15:28:35 +00002628#endif /* POLARSSL_FS_IO */
Paul Bakkereaa89f82011-04-04 21:36:15 +00002629#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00002630
Paul Bakker5121ce52009-01-03 21:22:43 +00002631#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002632#include <stdarg.h>
2633
2634#if !defined vsnprintf
2635#define vsnprintf _vsnprintf
2636#endif // vsnprintf
2637
2638/*
2639 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2640 * Result value is not size of buffer needed, but -1 if no fit is possible.
2641 *
2642 * This fuction tries to 'fix' this by at least suggesting enlarging the
2643 * size by 20.
2644 */
2645int compat_snprintf(char *str, size_t size, const char *format, ...)
2646{
2647 va_list ap;
2648 int res = -1;
2649
2650 va_start( ap, format );
2651
2652 res = vsnprintf( str, size, format, ap );
2653
2654 va_end( ap );
2655
2656 // No quick fix possible
2657 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00002658 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002659
2660 return res;
2661}
2662
2663#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002664#endif
2665
Paul Bakkerd98030e2009-05-02 15:13:40 +00002666#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2667
2668#define SAFE_SNPRINTF() \
2669{ \
2670 if( ret == -1 ) \
2671 return( -1 ); \
2672 \
Paul Bakker23986e52011-04-24 08:57:21 +00002673 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002674 p[n - 1] = '\0'; \
2675 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2676 } \
2677 \
Paul Bakker23986e52011-04-24 08:57:21 +00002678 n -= (unsigned int) ret; \
2679 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002680}
2681
Paul Bakker5121ce52009-01-03 21:22:43 +00002682/*
2683 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002684 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002685 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002686int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002687{
Paul Bakker23986e52011-04-24 08:57:21 +00002688 int ret;
2689 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002690 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002691 const x509_name *name;
Paul Bakker5121ce52009-01-03 21:22:43 +00002692 char s[128], *p;
2693
2694 memset( s, 0, sizeof( s ) );
2695
2696 name = dn;
2697 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002698 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002699
2700 while( name != NULL )
2701 {
Paul Bakkercefb3962012-06-27 11:51:09 +00002702 if( !name->oid.p )
2703 {
2704 name = name->next;
2705 continue;
2706 }
2707
Paul Bakker74111d32011-01-15 16:57:55 +00002708 if( name != dn )
2709 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002710 ret = snprintf( p, n, ", " );
2711 SAFE_SNPRINTF();
2712 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002713
Paul Bakker535e97d2012-08-23 10:49:55 +00002714 if( name->oid.len == 3 &&
2715 memcmp( name->oid.p, OID_X520, 2 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002716 {
2717 switch( name->oid.p[2] )
2718 {
2719 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002720 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002721
2722 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002723 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002724
2725 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002726 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002727
2728 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002729 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002730
2731 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002732 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002733
2734 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002735 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002736
2737 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002738 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002739 name->oid.p[2] );
2740 break;
2741 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002742 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002743 }
Paul Bakker535e97d2012-08-23 10:49:55 +00002744 else if( name->oid.len == 9 &&
2745 memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002746 {
2747 switch( name->oid.p[8] )
2748 {
2749 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002750 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002751
2752 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002753 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002754 name->oid.p[8] );
2755 break;
2756 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002757 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002758 }
2759 else
Paul Bakker74111d32011-01-15 16:57:55 +00002760 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002761 ret = snprintf( p, n, "\?\?=" );
Paul Bakker74111d32011-01-15 16:57:55 +00002762 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002763 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002764
2765 for( i = 0; i < name->val.len; i++ )
2766 {
Paul Bakker27fdf462011-06-09 13:55:13 +00002767 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002768 break;
2769
2770 c = name->val.p[i];
2771 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2772 s[i] = '?';
2773 else s[i] = c;
2774 }
2775 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002776 ret = snprintf( p, n, "%s", s );
2777 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002778 name = name->next;
2779 }
2780
Paul Bakker23986e52011-04-24 08:57:21 +00002781 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002782}
2783
2784/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002785 * Store the serial in printable form into buf; no more
2786 * than size characters will be written
2787 */
2788int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2789{
Paul Bakker23986e52011-04-24 08:57:21 +00002790 int ret;
2791 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00002792 char *p;
2793
2794 p = buf;
2795 n = size;
2796
2797 nr = ( serial->len <= 32 )
Paul Bakker03c7c252011-11-25 12:37:37 +00002798 ? serial->len : 28;
Paul Bakkerdd476992011-01-16 21:34:59 +00002799
2800 for( i = 0; i < nr; i++ )
2801 {
Paul Bakker93048802011-12-05 14:38:06 +00002802 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002803 continue;
2804
Paul Bakkerdd476992011-01-16 21:34:59 +00002805 ret = snprintf( p, n, "%02X%s",
2806 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2807 SAFE_SNPRINTF();
2808 }
2809
Paul Bakker03c7c252011-11-25 12:37:37 +00002810 if( nr != serial->len )
2811 {
2812 ret = snprintf( p, n, "...." );
2813 SAFE_SNPRINTF();
2814 }
2815
Paul Bakker23986e52011-04-24 08:57:21 +00002816 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00002817}
2818
2819/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002820 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002821 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002822int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2823 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002824{
Paul Bakker23986e52011-04-24 08:57:21 +00002825 int ret;
2826 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002827 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00002828
2829 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002830 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002831
Paul Bakkerd98030e2009-05-02 15:13:40 +00002832 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002833 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002834 SAFE_SNPRINTF();
2835 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002836 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002837 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002838
Paul Bakkerdd476992011-01-16 21:34:59 +00002839 ret = x509parse_serial_gets( p, n, &crt->serial);
2840 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002841
Paul Bakkerd98030e2009-05-02 15:13:40 +00002842 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2843 SAFE_SNPRINTF();
2844 ret = x509parse_dn_gets( p, n, &crt->issuer );
2845 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002846
Paul Bakkerd98030e2009-05-02 15:13:40 +00002847 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2848 SAFE_SNPRINTF();
2849 ret = x509parse_dn_gets( p, n, &crt->subject );
2850 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002851
Paul Bakkerd98030e2009-05-02 15:13:40 +00002852 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002853 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2854 crt->valid_from.year, crt->valid_from.mon,
2855 crt->valid_from.day, crt->valid_from.hour,
2856 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002857 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002858
Paul Bakkerd98030e2009-05-02 15:13:40 +00002859 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002860 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2861 crt->valid_to.year, crt->valid_to.mon,
2862 crt->valid_to.day, crt->valid_to.hour,
2863 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002864 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002865
Paul Bakkerd98030e2009-05-02 15:13:40 +00002866 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2867 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002868
Paul Bakker27d66162010-03-17 06:56:01 +00002869 switch( crt->sig_alg )
Paul Bakker5121ce52009-01-03 21:22:43 +00002870 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002871 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2872 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2873 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2874 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2875 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2876 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2877 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2878 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2879 default: ret = snprintf( p, n, "???" ); break;
2880 }
2881 SAFE_SNPRINTF();
2882
2883 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
Paul Bakker5c2364c2012-10-01 14:41:15 +00002884 (int) crt->rsa.N.n * (int) sizeof( t_uint ) * 8 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002885 SAFE_SNPRINTF();
2886
Paul Bakker23986e52011-04-24 08:57:21 +00002887 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002888}
2889
Paul Bakker74111d32011-01-15 16:57:55 +00002890/*
2891 * Return an informational string describing the given OID
2892 */
2893const char *x509_oid_get_description( x509_buf *oid )
2894{
2895 if ( oid == NULL )
2896 return ( NULL );
2897
2898 else if( OID_CMP( OID_SERVER_AUTH, oid ) )
2899 return( STRING_SERVER_AUTH );
2900
2901 else if( OID_CMP( OID_CLIENT_AUTH, oid ) )
2902 return( STRING_CLIENT_AUTH );
2903
2904 else if( OID_CMP( OID_CODE_SIGNING, oid ) )
2905 return( STRING_CODE_SIGNING );
2906
2907 else if( OID_CMP( OID_EMAIL_PROTECTION, oid ) )
2908 return( STRING_EMAIL_PROTECTION );
2909
2910 else if( OID_CMP( OID_TIME_STAMPING, oid ) )
2911 return( STRING_TIME_STAMPING );
2912
2913 else if( OID_CMP( OID_OCSP_SIGNING, oid ) )
2914 return( STRING_OCSP_SIGNING );
2915
2916 return( NULL );
2917}
2918
2919/* Return the x.y.z.... style numeric string for the given OID */
2920int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2921{
Paul Bakker23986e52011-04-24 08:57:21 +00002922 int ret;
2923 size_t i, n;
Paul Bakker74111d32011-01-15 16:57:55 +00002924 unsigned int value;
2925 char *p;
2926
2927 p = buf;
2928 n = size;
2929
2930 /* First byte contains first two dots */
2931 if( oid->len > 0 )
2932 {
2933 ret = snprintf( p, n, "%d.%d", oid->p[0]/40, oid->p[0]%40 );
2934 SAFE_SNPRINTF();
2935 }
2936
2937 /* TODO: value can overflow in value. */
2938 value = 0;
Paul Bakker23986e52011-04-24 08:57:21 +00002939 for( i = 1; i < oid->len; i++ )
Paul Bakker74111d32011-01-15 16:57:55 +00002940 {
2941 value <<= 7;
2942 value += oid->p[i] & 0x7F;
2943
2944 if( !( oid->p[i] & 0x80 ) )
2945 {
2946 /* Last byte */
2947 ret = snprintf( p, n, ".%d", value );
2948 SAFE_SNPRINTF();
2949 value = 0;
2950 }
2951 }
2952
Paul Bakker23986e52011-04-24 08:57:21 +00002953 return( (int) ( size - n ) );
Paul Bakker74111d32011-01-15 16:57:55 +00002954}
2955
Paul Bakkerd98030e2009-05-02 15:13:40 +00002956/*
2957 * Return an informational string about the CRL.
2958 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002959int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2960 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002961{
Paul Bakker23986e52011-04-24 08:57:21 +00002962 int ret;
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002963 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002964 char *p;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002965 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002966
2967 p = buf;
2968 n = size;
2969
2970 ret = snprintf( p, n, "%sCRL version : %d",
2971 prefix, crl->version );
2972 SAFE_SNPRINTF();
2973
2974 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2975 SAFE_SNPRINTF();
2976 ret = x509parse_dn_gets( p, n, &crl->issuer );
2977 SAFE_SNPRINTF();
2978
2979 ret = snprintf( p, n, "\n%sthis update : " \
2980 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2981 crl->this_update.year, crl->this_update.mon,
2982 crl->this_update.day, crl->this_update.hour,
2983 crl->this_update.min, crl->this_update.sec );
2984 SAFE_SNPRINTF();
2985
2986 ret = snprintf( p, n, "\n%snext update : " \
2987 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2988 crl->next_update.year, crl->next_update.mon,
2989 crl->next_update.day, crl->next_update.hour,
2990 crl->next_update.min, crl->next_update.sec );
2991 SAFE_SNPRINTF();
2992
2993 entry = &crl->entry;
2994
2995 ret = snprintf( p, n, "\n%sRevoked certificates:",
2996 prefix );
2997 SAFE_SNPRINTF();
2998
Paul Bakker9be19372009-07-27 20:21:53 +00002999 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003000 {
3001 ret = snprintf( p, n, "\n%sserial number: ",
3002 prefix );
3003 SAFE_SNPRINTF();
3004
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003005 ret = x509parse_serial_gets( p, n, &entry->serial);
3006 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003007
Paul Bakkerd98030e2009-05-02 15:13:40 +00003008 ret = snprintf( p, n, " revocation date: " \
3009 "%04d-%02d-%02d %02d:%02d:%02d",
3010 entry->revocation_date.year, entry->revocation_date.mon,
3011 entry->revocation_date.day, entry->revocation_date.hour,
3012 entry->revocation_date.min, entry->revocation_date.sec );
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00003013 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00003014
3015 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003016 }
3017
Paul Bakkerd98030e2009-05-02 15:13:40 +00003018 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
3019 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00003020
Paul Bakker27d66162010-03-17 06:56:01 +00003021 switch( crl->sig_alg )
Paul Bakkerd98030e2009-05-02 15:13:40 +00003022 {
3023 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
3024 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
3025 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
3026 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
3027 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
3028 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
3029 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
3030 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
3031 default: ret = snprintf( p, n, "???" ); break;
3032 }
3033 SAFE_SNPRINTF();
3034
Paul Bakker1e27bb22009-07-19 20:25:25 +00003035 ret = snprintf( p, n, "\n" );
3036 SAFE_SNPRINTF();
3037
Paul Bakker23986e52011-04-24 08:57:21 +00003038 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003039}
3040
3041/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00003042 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00003043 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003044int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00003045{
Paul Bakkercce9d772011-11-18 14:26:47 +00003046 int year, mon, day;
3047 int hour, min, sec;
3048
3049#if defined(_WIN32)
3050 SYSTEMTIME st;
3051
3052 GetLocalTime(&st);
3053
3054 year = st.wYear;
3055 mon = st.wMonth;
3056 day = st.wDay;
3057 hour = st.wHour;
3058 min = st.wMinute;
3059 sec = st.wSecond;
3060#else
Paul Bakker5121ce52009-01-03 21:22:43 +00003061 struct tm *lt;
3062 time_t tt;
3063
3064 tt = time( NULL );
3065 lt = localtime( &tt );
3066
Paul Bakkercce9d772011-11-18 14:26:47 +00003067 year = lt->tm_year + 1900;
3068 mon = lt->tm_mon + 1;
3069 day = lt->tm_mday;
3070 hour = lt->tm_hour;
3071 min = lt->tm_min;
3072 sec = lt->tm_sec;
3073#endif
3074
3075 if( year > to->year )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003076 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003077
Paul Bakkercce9d772011-11-18 14:26:47 +00003078 if( year == to->year &&
3079 mon > to->mon )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003080 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003081
Paul Bakkercce9d772011-11-18 14:26:47 +00003082 if( year == to->year &&
3083 mon == to->mon &&
3084 day > to->day )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003085 return( 1 );
3086
Paul Bakkercce9d772011-11-18 14:26:47 +00003087 if( year == to->year &&
3088 mon == to->mon &&
3089 day == to->day &&
3090 hour > to->hour )
Paul Bakkerb6194992011-01-16 21:40:22 +00003091 return( 1 );
3092
Paul Bakkercce9d772011-11-18 14:26:47 +00003093 if( year == to->year &&
3094 mon == to->mon &&
3095 day == to->day &&
3096 hour == to->hour &&
3097 min > to->min )
Paul Bakkerb6194992011-01-16 21:40:22 +00003098 return( 1 );
3099
Paul Bakkercce9d772011-11-18 14:26:47 +00003100 if( year == to->year &&
3101 mon == to->mon &&
3102 day == to->day &&
3103 hour == to->hour &&
3104 min == to->min &&
3105 sec > to->sec )
Paul Bakkerb6194992011-01-16 21:40:22 +00003106 return( 1 );
3107
Paul Bakker40ea7de2009-05-03 10:18:48 +00003108 return( 0 );
3109}
3110
3111/*
3112 * Return 1 if the certificate is revoked, or 0 otherwise.
3113 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00003114int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003115{
Paul Bakkerff60ee62010-03-16 21:09:09 +00003116 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00003117
3118 while( cur != NULL && cur->serial.len != 0 )
3119 {
Paul Bakkera056efc2011-01-16 21:38:35 +00003120 if( crt->serial.len == cur->serial.len &&
3121 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00003122 {
3123 if( x509parse_time_expired( &cur->revocation_date ) )
3124 return( 1 );
3125 }
3126
3127 cur = cur->next;
3128 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003129
3130 return( 0 );
3131}
3132
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003133/*
3134 * Wrapper for x509 hashes.
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003135 */
Paul Bakker23986e52011-04-24 08:57:21 +00003136static void x509_hash( const unsigned char *in, size_t len, int alg,
Paul Bakker5121ce52009-01-03 21:22:43 +00003137 unsigned char *out )
3138{
3139 switch( alg )
3140 {
Paul Bakker40e46942009-01-03 21:51:57 +00003141#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003142 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003143#endif
Paul Bakker40e46942009-01-03 21:51:57 +00003144#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003145 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003146#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003147#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003148 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003149#endif
3150#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003151 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003152#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00003153#if defined(POLARSSL_SHA2_C)
3154 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
3155 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
3156#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00003157#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00003158 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
3159 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
3160#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003161 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003162 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003163 break;
3164 }
3165}
3166
3167/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00003168 * Check that the given certificate is valid accoring to the CRL.
3169 */
3170static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
3171 x509_crl *crl_list)
3172{
3173 int flags = 0;
3174 int hash_id;
3175 unsigned char hash[64];
3176
Paul Bakker915275b2012-09-28 07:10:55 +00003177 if( ca == NULL )
3178 return( flags );
3179
Paul Bakker76fd75a2011-01-16 21:12:10 +00003180 /*
3181 * TODO: What happens if no CRL is present?
3182 * Suggestion: Revocation state should be unknown if no CRL is present.
3183 * For backwards compatibility this is not yet implemented.
3184 */
3185
Paul Bakker915275b2012-09-28 07:10:55 +00003186 while( crl_list != NULL )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003187 {
Paul Bakker915275b2012-09-28 07:10:55 +00003188 if( crl_list->version == 0 ||
3189 crl_list->issuer_raw.len != ca->subject_raw.len ||
Paul Bakker76fd75a2011-01-16 21:12:10 +00003190 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
3191 crl_list->issuer_raw.len ) != 0 )
3192 {
3193 crl_list = crl_list->next;
3194 continue;
3195 }
3196
3197 /*
3198 * Check if CRL is correctly signed by the trusted CA
3199 */
3200 hash_id = crl_list->sig_alg;
3201
3202 x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
3203
3204 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, hash_id,
3205 0, hash, crl_list->sig.p ) == 0 )
3206 {
3207 /*
3208 * CRL is not trusted
3209 */
3210 flags |= BADCRL_NOT_TRUSTED;
3211 break;
3212 }
3213
3214 /*
3215 * Check for validity of CRL (Do not drop out)
3216 */
3217 if( x509parse_time_expired( &crl_list->next_update ) )
3218 flags |= BADCRL_EXPIRED;
3219
3220 /*
3221 * Check if certificate is revoked
3222 */
3223 if( x509parse_revoked(crt, crl_list) )
3224 {
3225 flags |= BADCERT_REVOKED;
3226 break;
3227 }
3228
3229 crl_list = crl_list->next;
3230 }
3231 return flags;
3232}
3233
Paul Bakker57b12982012-02-11 17:38:38 +00003234int x509_wildcard_verify( const char *cn, x509_buf *name )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003235{
3236 size_t i;
3237 size_t cn_idx = 0;
3238
Paul Bakker57b12982012-02-11 17:38:38 +00003239 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003240 return( 0 );
3241
3242 for( i = 0; i < strlen( cn ); ++i )
3243 {
3244 if( cn[i] == '.' )
3245 {
3246 cn_idx = i;
3247 break;
3248 }
3249 }
3250
3251 if( cn_idx == 0 )
3252 return( 0 );
3253
Paul Bakker535e97d2012-08-23 10:49:55 +00003254 if( strlen( cn ) - cn_idx == name->len - 1 &&
3255 memcmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003256 {
3257 return( 1 );
3258 }
3259
3260 return( 0 );
3261}
3262
Paul Bakker915275b2012-09-28 07:10:55 +00003263static int x509parse_verify_top(
3264 x509_cert *child, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003265 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003266 int (*f_vrfy)(void *, x509_cert *, int, int *),
3267 void *p_vrfy )
3268{
3269 int hash_id, ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003270 int ca_flags = 0, check_path_cnt = path_cnt + 1;
Paul Bakker915275b2012-09-28 07:10:55 +00003271 unsigned char hash[64];
3272
3273 if( x509parse_time_expired( &child->valid_to ) )
3274 *flags |= BADCERT_EXPIRED;
3275
3276 /*
3277 * Child is the top of the chain. Check against the trust_ca list.
3278 */
3279 *flags |= BADCERT_NOT_TRUSTED;
3280
3281 while( trust_ca != NULL )
3282 {
3283 if( trust_ca->version == 0 ||
3284 child->issuer_raw.len != trust_ca->subject_raw.len ||
3285 memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
3286 child->issuer_raw.len ) != 0 )
3287 {
3288 trust_ca = trust_ca->next;
3289 continue;
3290 }
3291
Paul Bakker9a736322012-11-14 12:39:52 +00003292 /*
3293 * Reduce path_len to check against if top of the chain is
3294 * the same as the trusted CA
3295 */
3296 if( child->subject_raw.len == trust_ca->subject_raw.len &&
3297 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3298 child->issuer_raw.len ) == 0 )
3299 {
3300 check_path_cnt--;
3301 }
3302
Paul Bakker915275b2012-09-28 07:10:55 +00003303 if( trust_ca->max_pathlen > 0 &&
Paul Bakker9a736322012-11-14 12:39:52 +00003304 trust_ca->max_pathlen < check_path_cnt )
Paul Bakker915275b2012-09-28 07:10:55 +00003305 {
3306 trust_ca = trust_ca->next;
3307 continue;
3308 }
3309
3310 hash_id = child->sig_alg;
3311
3312 x509_hash( child->tbs.p, child->tbs.len, hash_id, hash );
3313
3314 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
3315 0, hash, child->sig.p ) != 0 )
3316 {
3317 trust_ca = trust_ca->next;
3318 continue;
3319 }
3320
3321 /*
3322 * Top of chain is signed by a trusted CA
3323 */
3324 *flags &= ~BADCERT_NOT_TRUSTED;
3325 break;
3326 }
3327
Paul Bakker9a736322012-11-14 12:39:52 +00003328 /*
Paul Bakker3497d8c2012-11-24 11:53:17 +01003329 * If top of chain is not the same as the trusted CA send a verify request
3330 * to the callback for any issues with validity and CRL presence for the
3331 * trusted CA certificate.
Paul Bakker9a736322012-11-14 12:39:52 +00003332 */
3333 if( trust_ca != NULL &&
3334 ( child->subject_raw.len != trust_ca->subject_raw.len ||
3335 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
3336 child->issuer_raw.len ) != 0 ) )
Paul Bakker915275b2012-09-28 07:10:55 +00003337 {
3338 /* Check trusted CA's CRL for then chain's top crt */
3339 *flags |= x509parse_verifycrl( child, trust_ca, ca_crl );
3340
3341 if( x509parse_time_expired( &trust_ca->valid_to ) )
3342 ca_flags |= BADCERT_EXPIRED;
3343
Paul Bakker915275b2012-09-28 07:10:55 +00003344 if( NULL != f_vrfy )
3345 {
Paul Bakker9a736322012-11-14 12:39:52 +00003346 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003347 return( ret );
3348 }
3349 }
3350
3351 /* Call callback on top cert */
3352 if( NULL != f_vrfy )
3353 {
Paul Bakker9a736322012-11-14 12:39:52 +00003354 if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003355 return( ret );
3356 }
3357
Paul Bakker915275b2012-09-28 07:10:55 +00003358 *flags |= ca_flags;
3359
3360 return( 0 );
3361}
3362
3363static int x509parse_verify_child(
3364 x509_cert *child, x509_cert *parent, x509_cert *trust_ca,
Paul Bakker9a736322012-11-14 12:39:52 +00003365 x509_crl *ca_crl, int path_cnt, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003366 int (*f_vrfy)(void *, x509_cert *, int, int *),
3367 void *p_vrfy )
3368{
3369 int hash_id, ret;
3370 int parent_flags = 0;
3371 unsigned char hash[64];
3372 x509_cert *grandparent;
3373
3374 if( x509parse_time_expired( &child->valid_to ) )
3375 *flags |= BADCERT_EXPIRED;
3376
3377 hash_id = child->sig_alg;
3378
3379 x509_hash( child->tbs.p, child->tbs.len, hash_id, hash );
3380
3381 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, hash_id, 0, hash,
3382 child->sig.p ) != 0 )
3383 *flags |= BADCERT_NOT_TRUSTED;
3384
3385 /* Check trusted CA's CRL for the given crt */
3386 *flags |= x509parse_verifycrl(child, parent, ca_crl);
3387
3388 grandparent = parent->next;
3389
3390 while( grandparent != NULL )
3391 {
3392 if( grandparent->version == 0 ||
3393 grandparent->ca_istrue == 0 ||
3394 parent->issuer_raw.len != grandparent->subject_raw.len ||
3395 memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
3396 parent->issuer_raw.len ) != 0 )
3397 {
3398 grandparent = grandparent->next;
3399 continue;
3400 }
3401 break;
3402 }
3403
Paul Bakker915275b2012-09-28 07:10:55 +00003404 if( grandparent != NULL )
3405 {
3406 /*
3407 * Part of the chain
3408 */
Paul Bakker9a736322012-11-14 12:39:52 +00003409 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 +00003410 if( ret != 0 )
3411 return( ret );
3412 }
3413 else
3414 {
Paul Bakker9a736322012-11-14 12:39:52 +00003415 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 +00003416 if( ret != 0 )
3417 return( ret );
3418 }
3419
3420 /* child is verified to be a child of the parent, call verify callback */
3421 if( NULL != f_vrfy )
Paul Bakker9a736322012-11-14 12:39:52 +00003422 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
Paul Bakker915275b2012-09-28 07:10:55 +00003423 return( ret );
Paul Bakker915275b2012-09-28 07:10:55 +00003424
3425 *flags |= parent_flags;
3426
3427 return( 0 );
3428}
3429
Paul Bakker76fd75a2011-01-16 21:12:10 +00003430/*
Paul Bakker5121ce52009-01-03 21:22:43 +00003431 * Verify the certificate validity
3432 */
3433int x509parse_verify( x509_cert *crt,
3434 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00003435 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003436 const char *cn, int *flags,
Paul Bakker915275b2012-09-28 07:10:55 +00003437 int (*f_vrfy)(void *, x509_cert *, int, int *),
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003438 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00003439{
Paul Bakker23986e52011-04-24 08:57:21 +00003440 size_t cn_len;
Paul Bakker915275b2012-09-28 07:10:55 +00003441 int ret;
Paul Bakker9a736322012-11-14 12:39:52 +00003442 int pathlen = 0;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003443 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00003444 x509_name *name;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003445 x509_sequence *cur = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003446
Paul Bakker40ea7de2009-05-03 10:18:48 +00003447 *flags = 0;
3448
Paul Bakker5121ce52009-01-03 21:22:43 +00003449 if( cn != NULL )
3450 {
3451 name = &crt->subject;
3452 cn_len = strlen( cn );
3453
Paul Bakker4d2c1242012-05-10 14:12:46 +00003454 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
Paul Bakker5121ce52009-01-03 21:22:43 +00003455 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00003456 cur = &crt->subject_alt_names;
3457
3458 while( cur != NULL )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003459 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003460 if( cur->buf.len == cn_len &&
3461 memcmp( cn, cur->buf.p, cn_len ) == 0 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003462 break;
3463
Paul Bakker535e97d2012-08-23 10:49:55 +00003464 if( cur->buf.len > 2 &&
3465 memcmp( cur->buf.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003466 x509_wildcard_verify( cn, &cur->buf ) )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003467 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003468
Paul Bakker4d2c1242012-05-10 14:12:46 +00003469 cur = cur->next;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003470 }
3471
3472 if( cur == NULL )
3473 *flags |= BADCERT_CN_MISMATCH;
3474 }
Paul Bakker4d2c1242012-05-10 14:12:46 +00003475 else
3476 {
3477 while( name != NULL )
3478 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003479 if( name->oid.len == 3 &&
3480 memcmp( name->oid.p, OID_CN, 3 ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003481 {
Paul Bakker535e97d2012-08-23 10:49:55 +00003482 if( name->val.len == cn_len &&
3483 memcmp( name->val.p, cn, cn_len ) == 0 )
Paul Bakker4d2c1242012-05-10 14:12:46 +00003484 break;
3485
Paul Bakker535e97d2012-08-23 10:49:55 +00003486 if( name->val.len > 2 &&
3487 memcmp( name->val.p, "*.", 2 ) == 0 &&
Paul Bakker4d2c1242012-05-10 14:12:46 +00003488 x509_wildcard_verify( cn, &name->val ) )
3489 break;
3490 }
3491
3492 name = name->next;
3493 }
3494
3495 if( name == NULL )
3496 *flags |= BADCERT_CN_MISMATCH;
3497 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003498 }
3499
Paul Bakker5121ce52009-01-03 21:22:43 +00003500 /*
Paul Bakker915275b2012-09-28 07:10:55 +00003501 * Iterate upwards in the given cert chain, to find our crt parent.
3502 * Ignore any upper cert with CA != TRUE.
Paul Bakker5121ce52009-01-03 21:22:43 +00003503 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003504 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003505
Paul Bakker76fd75a2011-01-16 21:12:10 +00003506 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003507 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003508 if( parent->ca_istrue == 0 ||
3509 crt->issuer_raw.len != parent->subject_raw.len ||
3510 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00003511 crt->issuer_raw.len ) != 0 )
3512 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003513 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003514 continue;
3515 }
Paul Bakker915275b2012-09-28 07:10:55 +00003516 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003517 }
3518
Paul Bakker915275b2012-09-28 07:10:55 +00003519 if( parent != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003520 {
Paul Bakker915275b2012-09-28 07:10:55 +00003521 /*
3522 * Part of the chain
3523 */
Paul Bakker9a736322012-11-14 12:39:52 +00003524 ret = x509parse_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003525 if( ret != 0 )
3526 return( ret );
3527 }
3528 else
Paul Bakker74111d32011-01-15 16:57:55 +00003529 {
Paul Bakker9a736322012-11-14 12:39:52 +00003530 ret = x509parse_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
Paul Bakker915275b2012-09-28 07:10:55 +00003531 if( ret != 0 )
3532 return( ret );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003533 }
Paul Bakker915275b2012-09-28 07:10:55 +00003534
3535 if( *flags != 0 )
Paul Bakker76fd75a2011-01-16 21:12:10 +00003536 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003537
Paul Bakker5121ce52009-01-03 21:22:43 +00003538 return( 0 );
3539}
3540
3541/*
3542 * Unallocate all certificate data
3543 */
3544void x509_free( x509_cert *crt )
3545{
3546 x509_cert *cert_cur = crt;
3547 x509_cert *cert_prv;
3548 x509_name *name_cur;
3549 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00003550 x509_sequence *seq_cur;
3551 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00003552
3553 if( crt == NULL )
3554 return;
3555
3556 do
3557 {
3558 rsa_free( &cert_cur->rsa );
3559
3560 name_cur = cert_cur->issuer.next;
3561 while( name_cur != NULL )
3562 {
3563 name_prv = name_cur;
3564 name_cur = name_cur->next;
3565 memset( name_prv, 0, sizeof( x509_name ) );
3566 free( name_prv );
3567 }
3568
3569 name_cur = cert_cur->subject.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
Paul Bakker74111d32011-01-15 16:57:55 +00003578 seq_cur = cert_cur->ext_key_usage.next;
3579 while( seq_cur != NULL )
3580 {
3581 seq_prv = seq_cur;
3582 seq_cur = seq_cur->next;
3583 memset( seq_prv, 0, sizeof( x509_sequence ) );
3584 free( seq_prv );
3585 }
3586
Paul Bakker8afa70d2012-02-11 18:42:45 +00003587 seq_cur = cert_cur->subject_alt_names.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 Bakker5121ce52009-01-03 21:22:43 +00003596 if( cert_cur->raw.p != NULL )
3597 {
3598 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
3599 free( cert_cur->raw.p );
3600 }
3601
3602 cert_cur = cert_cur->next;
3603 }
3604 while( cert_cur != NULL );
3605
3606 cert_cur = crt;
3607 do
3608 {
3609 cert_prv = cert_cur;
3610 cert_cur = cert_cur->next;
3611
3612 memset( cert_prv, 0, sizeof( x509_cert ) );
3613 if( cert_prv != crt )
3614 free( cert_prv );
3615 }
3616 while( cert_cur != NULL );
3617}
3618
Paul Bakkerd98030e2009-05-02 15:13:40 +00003619/*
3620 * Unallocate all CRL data
3621 */
3622void x509_crl_free( x509_crl *crl )
3623{
3624 x509_crl *crl_cur = crl;
3625 x509_crl *crl_prv;
3626 x509_name *name_cur;
3627 x509_name *name_prv;
3628 x509_crl_entry *entry_cur;
3629 x509_crl_entry *entry_prv;
3630
3631 if( crl == NULL )
3632 return;
3633
3634 do
3635 {
3636 name_cur = crl_cur->issuer.next;
3637 while( name_cur != NULL )
3638 {
3639 name_prv = name_cur;
3640 name_cur = name_cur->next;
3641 memset( name_prv, 0, sizeof( x509_name ) );
3642 free( name_prv );
3643 }
3644
3645 entry_cur = crl_cur->entry.next;
3646 while( entry_cur != NULL )
3647 {
3648 entry_prv = entry_cur;
3649 entry_cur = entry_cur->next;
3650 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
3651 free( entry_prv );
3652 }
3653
3654 if( crl_cur->raw.p != NULL )
3655 {
3656 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
3657 free( crl_cur->raw.p );
3658 }
3659
3660 crl_cur = crl_cur->next;
3661 }
3662 while( crl_cur != NULL );
3663
3664 crl_cur = crl;
3665 do
3666 {
3667 crl_prv = crl_cur;
3668 crl_cur = crl_cur->next;
3669
3670 memset( crl_prv, 0, sizeof( x509_crl ) );
3671 if( crl_prv != crl )
3672 free( crl_prv );
3673 }
3674 while( crl_cur != NULL );
3675}
3676
Paul Bakker40e46942009-01-03 21:51:57 +00003677#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00003678
Paul Bakker40e46942009-01-03 21:51:57 +00003679#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00003680
3681/*
3682 * Checkup routine
3683 */
3684int x509_self_test( int verbose )
3685{
Paul Bakker5690efc2011-05-26 13:16:06 +00003686#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00003687 int ret;
3688 int flags;
3689 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00003690 x509_cert cacert;
3691 x509_cert clicert;
3692 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00003693#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003694 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00003695#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003696
3697 if( verbose != 0 )
3698 printf( " X.509 certificate load: " );
3699
3700 memset( &clicert, 0, sizeof( x509_cert ) );
3701
Paul Bakkereae09db2013-06-06 12:35:54 +02003702 ret = x509parse_crt( &clicert, (const unsigned char *) test_cli_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003703 strlen( test_cli_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003704 if( ret != 0 )
3705 {
3706 if( verbose != 0 )
3707 printf( "failed\n" );
3708
3709 return( ret );
3710 }
3711
3712 memset( &cacert, 0, sizeof( x509_cert ) );
3713
Paul Bakkereae09db2013-06-06 12:35:54 +02003714 ret = x509parse_crt( &cacert, (const unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003715 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003716 if( ret != 0 )
3717 {
3718 if( verbose != 0 )
3719 printf( "failed\n" );
3720
3721 return( ret );
3722 }
3723
3724 if( verbose != 0 )
3725 printf( "passed\n X.509 private key load: " );
3726
3727 i = strlen( test_ca_key );
3728 j = strlen( test_ca_pwd );
3729
Paul Bakker66b78b22011-03-25 14:22:50 +00003730 rsa_init( &rsa, RSA_PKCS_V15, 0 );
3731
Paul Bakker5121ce52009-01-03 21:22:43 +00003732 if( ( ret = x509parse_key( &rsa,
Paul Bakkereae09db2013-06-06 12:35:54 +02003733 (const unsigned char *) test_ca_key, i,
3734 (const unsigned char *) test_ca_pwd, j ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003735 {
3736 if( verbose != 0 )
3737 printf( "failed\n" );
3738
3739 return( ret );
3740 }
3741
3742 if( verbose != 0 )
3743 printf( "passed\n X.509 signature verify: ");
3744
Paul Bakker23986e52011-04-24 08:57:21 +00003745 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003746 if( ret != 0 )
3747 {
Paul Bakker23986e52011-04-24 08:57:21 +00003748 printf("%02x", flags);
Paul Bakker5121ce52009-01-03 21:22:43 +00003749 if( verbose != 0 )
3750 printf( "failed\n" );
3751
3752 return( ret );
3753 }
3754
Paul Bakker5690efc2011-05-26 13:16:06 +00003755#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003756 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003757 printf( "passed\n X.509 DHM parameter load: " );
3758
3759 i = strlen( test_dhm_params );
3760 j = strlen( test_ca_pwd );
3761
Paul Bakkereae09db2013-06-06 12:35:54 +02003762 if( ( ret = x509parse_dhm( &dhm, (const unsigned char *) test_dhm_params, i ) ) != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003763 {
3764 if( verbose != 0 )
3765 printf( "failed\n" );
3766
3767 return( ret );
3768 }
3769
3770 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003771 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00003772#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003773
3774 x509_free( &cacert );
3775 x509_free( &clicert );
3776 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00003777#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003778 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00003779#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003780
3781 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003782#else
3783 ((void) verbose);
3784 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3785#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003786}
3787
3788#endif
3789
3790#endif