blob: 4234dfc06a0865bc627db80637fa37e0140f2c73 [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"
45#include "polarssl/md2.h"
46#include "polarssl/md4.h"
47#include "polarssl/md5.h"
48#include "polarssl/sha1.h"
Paul Bakker026c03b2009-03-28 17:53:03 +000049#include "polarssl/sha2.h"
50#include "polarssl/sha4.h"
Paul Bakker1b57b062011-01-06 15:48:19 +000051#include "polarssl/dhm.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000052
53#include <string.h>
54#include <stdlib.h>
Paul Bakker4f229e52011-12-04 22:11:35 +000055#if defined(_WIN32)
Paul Bakkercce9d772011-11-18 14:26:47 +000056#include <windows.h>
57#else
Paul Bakker5121ce52009-01-03 21:22:43 +000058#include <time.h>
Paul Bakkercce9d772011-11-18 14:26:47 +000059#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000060
Paul Bakker335db3f2011-04-25 15:28:35 +000061#if defined(POLARSSL_FS_IO)
62#include <stdio.h>
Paul Bakker8d914582012-06-04 12:46:42 +000063#if !defined(_WIN32)
64#include <sys/types.h>
65#include <dirent.h>
66#endif
Paul Bakker335db3f2011-04-25 15:28:35 +000067#endif
68
Paul Bakker5121ce52009-01-03 21:22:43 +000069/*
Paul Bakker5121ce52009-01-03 21:22:43 +000070 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
71 */
72static int x509_get_version( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +000073 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +000074 int *ver )
75{
Paul Bakker23986e52011-04-24 08:57:21 +000076 int ret;
77 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +000078
79 if( ( ret = asn1_get_tag( p, end, &len,
80 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
81 {
Paul Bakker40e46942009-01-03 21:51:57 +000082 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +000083 {
84 *ver = 0;
85 return( 0 );
86 }
Paul Bakker5121ce52009-01-03 21:22:43 +000087
88 return( ret );
89 }
90
91 end = *p + len;
92
93 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +000094 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +000095
96 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +000097 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION +
Paul Bakker40e46942009-01-03 21:51:57 +000098 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +000099
100 return( 0 );
101}
102
103/*
Paul Bakkerfae618f2011-10-12 11:53:52 +0000104 * Version ::= INTEGER { v1(0), v2(1) }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000105 */
106static int x509_crl_get_version( unsigned char **p,
107 const unsigned char *end,
108 int *ver )
109{
110 int ret;
111
112 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
113 {
114 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +0000115 {
116 *ver = 0;
117 return( 0 );
118 }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000119
120 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
121 }
122
123 return( 0 );
124}
125
126/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000127 * CertificateSerialNumber ::= INTEGER
128 */
129static int x509_get_serial( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000130 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000131 x509_buf *serial )
132{
133 int ret;
134
135 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000136 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000137 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000138
139 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
140 **p != ASN1_INTEGER )
Paul Bakker9d781402011-05-09 16:17:09 +0000141 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000142 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000143
144 serial->tag = *(*p)++;
145
146 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000147 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000148
149 serial->p = *p;
150 *p += serial->len;
151
152 return( 0 );
153}
154
155/*
156 * AlgorithmIdentifier ::= SEQUENCE {
157 * algorithm OBJECT IDENTIFIER,
158 * parameters ANY DEFINED BY algorithm OPTIONAL }
159 */
160static int x509_get_alg( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000161 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000162 x509_buf *alg )
163{
Paul Bakker23986e52011-04-24 08:57:21 +0000164 int ret;
165 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000166
167 if( ( ret = asn1_get_tag( p, end, &len,
168 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000169 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000170
171 end = *p + len;
172 alg->tag = **p;
173
174 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000175 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000176
177 alg->p = *p;
178 *p += alg->len;
179
180 if( *p == end )
181 return( 0 );
182
183 /*
184 * assume the algorithm parameters must be NULL
185 */
186 if( ( ret = asn1_get_tag( p, end, &len, ASN1_NULL ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000187 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000188
189 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000190 return( POLARSSL_ERR_X509_CERT_INVALID_ALG +
Paul Bakker40e46942009-01-03 21:51:57 +0000191 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000192
193 return( 0 );
194}
195
196/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000197 * AttributeTypeAndValue ::= SEQUENCE {
198 * type AttributeType,
199 * value AttributeValue }
200 *
201 * AttributeType ::= OBJECT IDENTIFIER
202 *
203 * AttributeValue ::= ANY DEFINED BY AttributeType
204 */
Paul Bakker400ff6f2011-02-20 10:40:16 +0000205static int x509_get_attr_type_value( unsigned char **p,
206 const unsigned char *end,
207 x509_name *cur )
Paul Bakker5121ce52009-01-03 21:22:43 +0000208{
Paul Bakker23986e52011-04-24 08:57:21 +0000209 int ret;
210 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000211 x509_buf *oid;
212 x509_buf *val;
213
214 if( ( ret = asn1_get_tag( p, end, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000215 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000216 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000217
Paul Bakker5121ce52009-01-03 21:22:43 +0000218 oid = &cur->oid;
219 oid->tag = **p;
220
221 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000222 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000223
224 oid->p = *p;
225 *p += oid->len;
226
227 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000228 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000229 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000230
231 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
232 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
233 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker9d781402011-05-09 16:17:09 +0000234 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000235 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000236
237 val = &cur->val;
238 val->tag = *(*p)++;
239
240 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000241 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000242
243 val->p = *p;
244 *p += val->len;
245
246 cur->next = NULL;
247
Paul Bakker400ff6f2011-02-20 10:40:16 +0000248 return( 0 );
249}
250
251/*
252 * RelativeDistinguishedName ::=
253 * SET OF AttributeTypeAndValue
254 *
255 * AttributeTypeAndValue ::= SEQUENCE {
256 * type AttributeType,
257 * value AttributeValue }
258 *
259 * AttributeType ::= OBJECT IDENTIFIER
260 *
261 * AttributeValue ::= ANY DEFINED BY AttributeType
262 */
263static int x509_get_name( unsigned char **p,
264 const unsigned char *end,
265 x509_name *cur )
266{
Paul Bakker23986e52011-04-24 08:57:21 +0000267 int ret;
268 size_t len;
Paul Bakker400ff6f2011-02-20 10:40:16 +0000269 const unsigned char *end2;
270 x509_name *use;
271
272 if( ( ret = asn1_get_tag( p, end, &len,
273 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000274 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000275
276 end2 = end;
277 end = *p + len;
278 use = cur;
279
280 do
281 {
282 if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
283 return( ret );
284
285 if( *p != end )
286 {
287 use->next = (x509_name *) malloc(
288 sizeof( x509_name ) );
289
290 if( use->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000291 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000292
293 memset( use->next, 0, sizeof( x509_name ) );
294
295 use = use->next;
296 }
297 }
298 while( *p != end );
Paul Bakker5121ce52009-01-03 21:22:43 +0000299
300 /*
301 * recurse until end of SEQUENCE is reached
302 */
303 if( *p == end2 )
304 return( 0 );
305
306 cur->next = (x509_name *) malloc(
307 sizeof( x509_name ) );
308
309 if( cur->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000310 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000311
Paul Bakker430ffbe2012-05-01 08:14:20 +0000312 memset( cur->next, 0, sizeof( x509_name ) );
313
Paul Bakker5121ce52009-01-03 21:22:43 +0000314 return( x509_get_name( p, end2, cur->next ) );
315}
316
317/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000318 * Time ::= CHOICE {
319 * utcTime UTCTime,
320 * generalTime GeneralizedTime }
321 */
Paul Bakker91200182010-02-18 21:26:15 +0000322static int x509_get_time( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000323 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000324 x509_time *time )
325{
Paul Bakker23986e52011-04-24 08:57:21 +0000326 int ret;
327 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000328 char date[64];
Paul Bakker91200182010-02-18 21:26:15 +0000329 unsigned char tag;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000330
Paul Bakker91200182010-02-18 21:26:15 +0000331 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000332 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
333 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000334
Paul Bakker91200182010-02-18 21:26:15 +0000335 tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000336
Paul Bakker91200182010-02-18 21:26:15 +0000337 if ( tag == ASN1_UTC_TIME )
338 {
339 (*p)++;
340 ret = asn1_get_len( p, end, &len );
341
342 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000343 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000344
Paul Bakker91200182010-02-18 21:26:15 +0000345 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000346 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
347 len : sizeof( date ) - 1 );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000348
Paul Bakker91200182010-02-18 21:26:15 +0000349 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
350 &time->year, &time->mon, &time->day,
351 &time->hour, &time->min, &time->sec ) < 5 )
352 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000353
Paul Bakker400ff6f2011-02-20 10:40:16 +0000354 time->year += 100 * ( time->year < 50 );
Paul Bakker91200182010-02-18 21:26:15 +0000355 time->year += 1900;
356
357 *p += len;
358
359 return( 0 );
360 }
361 else if ( tag == ASN1_GENERALIZED_TIME )
362 {
363 (*p)++;
364 ret = asn1_get_len( p, end, &len );
365
366 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000367 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker91200182010-02-18 21:26:15 +0000368
369 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000370 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
371 len : sizeof( date ) - 1 );
Paul Bakker91200182010-02-18 21:26:15 +0000372
373 if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
374 &time->year, &time->mon, &time->day,
375 &time->hour, &time->min, &time->sec ) < 5 )
376 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
377
378 *p += len;
379
380 return( 0 );
381 }
382 else
Paul Bakker9d781402011-05-09 16:17:09 +0000383 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000384}
385
386
387/*
388 * Validity ::= SEQUENCE {
389 * notBefore Time,
390 * notAfter Time }
391 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000392static int x509_get_dates( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000393 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000394 x509_time *from,
395 x509_time *to )
396{
Paul Bakker23986e52011-04-24 08:57:21 +0000397 int ret;
398 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000399
400 if( ( ret = asn1_get_tag( p, end, &len,
401 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000402 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000403
404 end = *p + len;
405
Paul Bakker91200182010-02-18 21:26:15 +0000406 if( ( ret = x509_get_time( p, end, from ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000407 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000408
Paul Bakker91200182010-02-18 21:26:15 +0000409 if( ( ret = x509_get_time( p, end, to ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000410 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000411
412 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000413 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker40e46942009-01-03 21:51:57 +0000414 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000415
416 return( 0 );
417}
418
419/*
420 * SubjectPublicKeyInfo ::= SEQUENCE {
421 * algorithm AlgorithmIdentifier,
422 * subjectPublicKey BIT STRING }
423 */
424static int x509_get_pubkey( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000425 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000426 x509_buf *pk_alg_oid,
427 mpi *N, mpi *E )
428{
Paul Bakker23986e52011-04-24 08:57:21 +0000429 int ret, can_handle;
430 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000431 unsigned char *end2;
432
433 if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 )
434 return( ret );
435
436 /*
437 * only RSA public keys handled at this time
438 */
Paul Bakker400ff6f2011-02-20 10:40:16 +0000439 can_handle = 0;
440
441 if( pk_alg_oid->len == 9 &&
442 memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) == 0 )
443 can_handle = 1;
444
445 if( pk_alg_oid->len == 9 &&
446 memcmp( pk_alg_oid->p, OID_PKCS1, 8 ) == 0 )
447 {
448 if( pk_alg_oid->p[8] >= 2 && pk_alg_oid->p[8] <= 5 )
449 can_handle = 1;
450
451 if ( pk_alg_oid->p[8] >= 11 && pk_alg_oid->p[8] <= 14 )
452 can_handle = 1;
453 }
454
455 if( pk_alg_oid->len == 5 &&
456 memcmp( pk_alg_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
457 can_handle = 1;
458
459 if( can_handle == 0 )
Paul Bakkered56b222011-07-13 11:26:43 +0000460 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000461
462 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000463 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000464
465 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000466 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000467 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000468
469 end2 = *p + len;
470
471 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000472 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000473
474 /*
475 * RSAPublicKey ::= SEQUENCE {
476 * modulus INTEGER, -- n
477 * publicExponent INTEGER -- e
478 * }
479 */
480 if( ( ret = asn1_get_tag( p, end2, &len,
481 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000482 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000483
484 if( *p + len != end2 )
Paul Bakker9d781402011-05-09 16:17:09 +0000485 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000486 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000487
488 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
489 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000490 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000491
492 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000493 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000494 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000495
496 return( 0 );
497}
498
499static int x509_get_sig( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000500 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000501 x509_buf *sig )
502{
Paul Bakker23986e52011-04-24 08:57:21 +0000503 int ret;
504 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000505
Paul Bakker8afa70d2012-02-11 18:42:45 +0000506 if( ( end - *p ) < 1 )
507 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE +
508 POLARSSL_ERR_ASN1_OUT_OF_DATA );
509
Paul Bakker5121ce52009-01-03 21:22:43 +0000510 sig->tag = **p;
511
512 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000513 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000514
Paul Bakker74111d32011-01-15 16:57:55 +0000515
Paul Bakker5121ce52009-01-03 21:22:43 +0000516 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000517 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000518
519 sig->len = len;
520 sig->p = *p;
521
522 *p += len;
523
524 return( 0 );
525}
526
527/*
528 * X.509 v2/v3 unique identifier (not parsed)
529 */
530static int x509_get_uid( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000531 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000532 x509_buf *uid, int n )
533{
534 int ret;
535
536 if( *p == end )
537 return( 0 );
538
539 uid->tag = **p;
540
541 if( ( ret = asn1_get_tag( p, end, &uid->len,
542 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
543 {
Paul Bakker40e46942009-01-03 21:51:57 +0000544 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000545 return( 0 );
546
547 return( ret );
548 }
549
550 uid->p = *p;
551 *p += uid->len;
552
553 return( 0 );
554}
555
556/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000557 * X.509 Extensions (No parsing of extensions, pointer should
558 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000559 */
560static int x509_get_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000561 const unsigned char *end,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000562 x509_buf *ext, int tag )
Paul Bakker5121ce52009-01-03 21:22:43 +0000563{
Paul Bakker23986e52011-04-24 08:57:21 +0000564 int ret;
565 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000566
567 if( *p == end )
568 return( 0 );
569
570 ext->tag = **p;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000571
Paul Bakker5121ce52009-01-03 21:22:43 +0000572 if( ( ret = asn1_get_tag( p, end, &ext->len,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000573 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000574 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000575
576 ext->p = *p;
577 end = *p + ext->len;
578
579 /*
580 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
581 *
582 * Extension ::= SEQUENCE {
583 * extnID OBJECT IDENTIFIER,
584 * critical BOOLEAN DEFAULT FALSE,
585 * extnValue OCTET STRING }
586 */
587 if( ( ret = asn1_get_tag( p, end, &len,
588 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000589 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000590
591 if( end != *p + len )
Paul Bakker9d781402011-05-09 16:17:09 +0000592 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +0000593 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000594
Paul Bakkerd98030e2009-05-02 15:13:40 +0000595 return( 0 );
596}
597
598/*
599 * X.509 CRL v2 extensions (no extensions parsed yet.)
600 */
601static int x509_get_crl_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000602 const unsigned char *end,
603 x509_buf *ext )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000604{
Paul Bakker23986e52011-04-24 08:57:21 +0000605 int ret;
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000606 size_t len = 0;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000607
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000608 /* Get explicit tag */
609 if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000610 {
611 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
612 return( 0 );
613
614 return( ret );
615 }
616
617 while( *p < end )
618 {
619 if( ( ret = asn1_get_tag( p, end, &len,
620 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000621 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000622
623 *p += len;
624 }
625
626 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000627 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerd98030e2009-05-02 15:13:40 +0000628 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
629
630 return( 0 );
631}
632
Paul Bakkerb5a11ab2011-10-12 09:58:41 +0000633/*
634 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
635 */
636static int x509_get_crl_entry_ext( unsigned char **p,
637 const unsigned char *end,
638 x509_buf *ext )
639{
640 int ret;
641 size_t len = 0;
642
643 /* OPTIONAL */
644 if (end <= *p)
645 return( 0 );
646
647 ext->tag = **p;
648 ext->p = *p;
649
650 /*
651 * Get CRL-entry extension sequence header
652 * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
653 */
654 if( ( ret = asn1_get_tag( p, end, &ext->len,
655 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
656 {
657 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
658 {
659 ext->p = NULL;
660 return( 0 );
661 }
662 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
663 }
664
665 end = *p + ext->len;
666
667 if( end != *p + ext->len )
668 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
669 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
670
671 while( *p < end )
672 {
673 if( ( ret = asn1_get_tag( p, end, &len,
674 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
675 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
676
677 *p += len;
678 }
679
680 if( *p != end )
681 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
682 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
683
684 return( 0 );
685}
686
Paul Bakker74111d32011-01-15 16:57:55 +0000687static int x509_get_basic_constraints( unsigned char **p,
688 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000689 int *ca_istrue,
690 int *max_pathlen )
691{
Paul Bakker23986e52011-04-24 08:57:21 +0000692 int ret;
693 size_t len;
Paul Bakker74111d32011-01-15 16:57:55 +0000694
695 /*
696 * BasicConstraints ::= SEQUENCE {
697 * cA BOOLEAN DEFAULT FALSE,
698 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
699 */
Paul Bakker3cccddb2011-01-16 21:46:31 +0000700 *ca_istrue = 0; /* DEFAULT FALSE */
Paul Bakker74111d32011-01-15 16:57:55 +0000701 *max_pathlen = 0; /* endless */
702
703 if( ( ret = asn1_get_tag( p, end, &len,
704 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000705 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000706
707 if( *p == end )
708 return 0;
709
Paul Bakker3cccddb2011-01-16 21:46:31 +0000710 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000711 {
712 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker3cccddb2011-01-16 21:46:31 +0000713 ret = asn1_get_int( p, end, ca_istrue );
Paul Bakker74111d32011-01-15 16:57:55 +0000714
715 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000716 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000717
Paul Bakker3cccddb2011-01-16 21:46:31 +0000718 if( *ca_istrue != 0 )
719 *ca_istrue = 1;
Paul Bakker74111d32011-01-15 16:57:55 +0000720 }
721
722 if( *p == end )
723 return 0;
724
725 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000726 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000727
728 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000729 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000730 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
731
732 (*max_pathlen)++;
733
Paul Bakker74111d32011-01-15 16:57:55 +0000734 return 0;
735}
736
737static int x509_get_ns_cert_type( unsigned char **p,
738 const unsigned char *end,
739 unsigned char *ns_cert_type)
740{
741 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000742 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000743
744 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000745 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000746
747 if( bs.len != 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000748 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000749 POLARSSL_ERR_ASN1_INVALID_LENGTH );
750
751 /* Get actual bitstring */
752 *ns_cert_type = *bs.p;
753 return 0;
754}
755
756static int x509_get_key_usage( unsigned char **p,
757 const unsigned char *end,
758 unsigned char *key_usage)
759{
760 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000761 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000762
763 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000764 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000765
Paul Bakkercebdf172011-11-11 15:01:31 +0000766 if( bs.len > 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000767 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000768 POLARSSL_ERR_ASN1_INVALID_LENGTH );
769
770 /* Get actual bitstring */
771 *key_usage = *bs.p;
772 return 0;
773}
774
Paul Bakkerd98030e2009-05-02 15:13:40 +0000775/*
Paul Bakker74111d32011-01-15 16:57:55 +0000776 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
777 *
778 * KeyPurposeId ::= OBJECT IDENTIFIER
779 */
780static int x509_get_ext_key_usage( unsigned char **p,
781 const unsigned char *end,
782 x509_sequence *ext_key_usage)
783{
784 int ret;
785
786 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000787 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000788
789 /* Sequence length must be >= 1 */
790 if( ext_key_usage->buf.p == NULL )
Paul Bakker9d781402011-05-09 16:17:09 +0000791 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000792 POLARSSL_ERR_ASN1_INVALID_LENGTH );
793
794 return 0;
795}
796
797/*
Paul Bakkera8cd2392012-02-11 16:09:32 +0000798 * SubjectAltName ::= GeneralNames
799 *
800 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
801 *
802 * GeneralName ::= CHOICE {
803 * otherName [0] OtherName,
804 * rfc822Name [1] IA5String,
805 * dNSName [2] IA5String,
806 * x400Address [3] ORAddress,
807 * directoryName [4] Name,
808 * ediPartyName [5] EDIPartyName,
809 * uniformResourceIdentifier [6] IA5String,
810 * iPAddress [7] OCTET STRING,
811 * registeredID [8] OBJECT IDENTIFIER }
812 *
813 * OtherName ::= SEQUENCE {
814 * type-id OBJECT IDENTIFIER,
815 * value [0] EXPLICIT ANY DEFINED BY type-id }
816 *
817 * EDIPartyName ::= SEQUENCE {
818 * nameAssigner [0] DirectoryString OPTIONAL,
819 * partyName [1] DirectoryString }
820 *
821 * NOTE: PolarSSL only parses and uses dNSName at this point.
822 */
823static int x509_get_subject_alt_name( unsigned char **p,
824 const unsigned char *end,
825 x509_sequence *subject_alt_name )
826{
827 int ret;
828 size_t len, tag_len;
829 asn1_buf *buf;
830 unsigned char tag;
831 asn1_sequence *cur = subject_alt_name;
832
833 /* Get main sequence tag */
834 if( ( ret = asn1_get_tag( p, end, &len,
835 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
836 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
837
838 if( *p + len != end )
839 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
840 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
841
842 while( *p < end )
843 {
844 if( ( end - *p ) < 1 )
845 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
846 POLARSSL_ERR_ASN1_OUT_OF_DATA );
847
848 tag = **p;
849 (*p)++;
850 if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 )
851 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
852
853 if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC )
854 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
855 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
856
857 if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) )
858 {
859 *p += tag_len;
860 continue;
861 }
862
863 buf = &(cur->buf);
864 buf->tag = tag;
865 buf->p = *p;
866 buf->len = tag_len;
867 *p += buf->len;
868
869 /* Allocate and assign next pointer */
870 if (*p < end)
871 {
872 cur->next = (asn1_sequence *) malloc(
873 sizeof( asn1_sequence ) );
874
875 if( cur->next == NULL )
876 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
877 POLARSSL_ERR_ASN1_MALLOC_FAILED );
878
879 cur = cur->next;
880 }
881 }
882
883 /* Set final sequence entry's next pointer to NULL */
884 cur->next = NULL;
885
886 if( *p != end )
887 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
888 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
889
890 return( 0 );
891}
892
893/*
Paul Bakker74111d32011-01-15 16:57:55 +0000894 * X.509 v3 extensions
895 *
896 * TODO: Perform all of the basic constraints tests required by the RFC
897 * TODO: Set values for undetected extensions to a sane default?
898 *
Paul Bakkerd98030e2009-05-02 15:13:40 +0000899 */
900static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000901 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000902 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000903{
Paul Bakker23986e52011-04-24 08:57:21 +0000904 int ret;
905 size_t len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000906 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000907
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000908 if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000909 {
910 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
911 return( 0 );
912
913 return( ret );
914 }
915
Paul Bakker5121ce52009-01-03 21:22:43 +0000916 while( *p < end )
917 {
Paul Bakker74111d32011-01-15 16:57:55 +0000918 /*
919 * Extension ::= SEQUENCE {
920 * extnID OBJECT IDENTIFIER,
921 * critical BOOLEAN DEFAULT FALSE,
922 * extnValue OCTET STRING }
923 */
924 x509_buf extn_oid = {0, 0, NULL};
925 int is_critical = 0; /* DEFAULT FALSE */
926
Paul Bakker5121ce52009-01-03 21:22:43 +0000927 if( ( ret = asn1_get_tag( p, end, &len,
928 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000929 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000930
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000931 end_ext_data = *p + len;
932
Paul Bakker74111d32011-01-15 16:57:55 +0000933 /* Get extension ID */
934 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000935
Paul Bakker74111d32011-01-15 16:57:55 +0000936 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000937 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000938
Paul Bakker74111d32011-01-15 16:57:55 +0000939 extn_oid.p = *p;
940 *p += extn_oid.len;
941
942 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000943 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000944 POLARSSL_ERR_ASN1_OUT_OF_DATA );
945
946 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000947 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000948 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
Paul Bakker9d781402011-05-09 16:17:09 +0000949 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000950
Paul Bakker74111d32011-01-15 16:57:55 +0000951 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000952 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000953 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000954 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000955
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000956 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000957
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000958 if( end_ext_octet != end_ext_data )
Paul Bakker9d781402011-05-09 16:17:09 +0000959 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000960 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000961
Paul Bakker74111d32011-01-15 16:57:55 +0000962 /*
963 * Detect supported extensions
964 */
965 if( ( OID_SIZE( OID_BASIC_CONSTRAINTS ) == extn_oid.len ) &&
966 memcmp( extn_oid.p, OID_BASIC_CONSTRAINTS, extn_oid.len ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000967 {
Paul Bakker74111d32011-01-15 16:57:55 +0000968 /* Parse basic constraints */
969 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
Paul Bakker3cccddb2011-01-16 21:46:31 +0000970 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000971 return ( ret );
972 crt->ext_types |= EXT_BASIC_CONSTRAINTS;
Paul Bakker5121ce52009-01-03 21:22:43 +0000973 }
Paul Bakker74111d32011-01-15 16:57:55 +0000974 else if( ( OID_SIZE( OID_NS_CERT_TYPE ) == extn_oid.len ) &&
975 memcmp( extn_oid.p, OID_NS_CERT_TYPE, extn_oid.len ) == 0 )
976 {
977 /* Parse netscape certificate type */
978 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
979 &crt->ns_cert_type ) ) != 0 )
980 return ( ret );
981 crt->ext_types |= EXT_NS_CERT_TYPE;
982 }
983 else if( ( OID_SIZE( OID_KEY_USAGE ) == extn_oid.len ) &&
984 memcmp( extn_oid.p, OID_KEY_USAGE, extn_oid.len ) == 0 )
985 {
986 /* Parse key usage */
987 if( ( ret = x509_get_key_usage( p, end_ext_octet,
988 &crt->key_usage ) ) != 0 )
989 return ( ret );
990 crt->ext_types |= EXT_KEY_USAGE;
991 }
992 else if( ( OID_SIZE( OID_EXTENDED_KEY_USAGE ) == extn_oid.len ) &&
993 memcmp( extn_oid.p, OID_EXTENDED_KEY_USAGE, extn_oid.len ) == 0 )
994 {
995 /* Parse extended key usage */
996 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
997 &crt->ext_key_usage ) ) != 0 )
998 return ( ret );
999 crt->ext_types |= EXT_EXTENDED_KEY_USAGE;
1000 }
Paul Bakkera8cd2392012-02-11 16:09:32 +00001001 else if( ( OID_SIZE( OID_SUBJECT_ALT_NAME ) == extn_oid.len ) &&
1002 memcmp( extn_oid.p, OID_SUBJECT_ALT_NAME, extn_oid.len ) == 0 )
1003 {
1004 /* Parse extended key usage */
1005 if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
1006 &crt->subject_alt_names ) ) != 0 )
1007 return ( ret );
1008 crt->ext_types |= EXT_SUBJECT_ALT_NAME;
1009 }
Paul Bakker74111d32011-01-15 16:57:55 +00001010 else
1011 {
1012 /* No parser found, skip extension */
1013 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +00001014
Paul Bakker5c721f92011-07-27 16:51:09 +00001015#if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
Paul Bakker74111d32011-01-15 16:57:55 +00001016 if( is_critical )
1017 {
1018 /* Data is marked as critical: fail */
Paul Bakker9d781402011-05-09 16:17:09 +00001019 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +00001020 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
1021 }
Paul Bakker5c721f92011-07-27 16:51:09 +00001022#endif
Paul Bakker74111d32011-01-15 16:57:55 +00001023 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001024 }
1025
1026 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +00001027 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +00001028 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001029
Paul Bakker5121ce52009-01-03 21:22:43 +00001030 return( 0 );
1031}
1032
1033/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001034 * X.509 CRL Entries
1035 */
1036static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001037 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001038 x509_crl_entry *entry )
1039{
Paul Bakker23986e52011-04-24 08:57:21 +00001040 int ret;
1041 size_t entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001042 x509_crl_entry *cur_entry = entry;
1043
1044 if( *p == end )
1045 return( 0 );
1046
Paul Bakker9be19372009-07-27 20:21:53 +00001047 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001048 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1049 {
1050 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
1051 return( 0 );
1052
1053 return( ret );
1054 }
1055
Paul Bakker9be19372009-07-27 20:21:53 +00001056 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001057
1058 while( *p < end )
1059 {
Paul Bakker23986e52011-04-24 08:57:21 +00001060 size_t len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001061 const unsigned char *end2;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001062
1063 if( ( ret = asn1_get_tag( p, end, &len2,
1064 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1065 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001066 return( ret );
1067 }
1068
Paul Bakker9be19372009-07-27 20:21:53 +00001069 cur_entry->raw.tag = **p;
1070 cur_entry->raw.p = *p;
1071 cur_entry->raw.len = len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001072 end2 = *p + len2;
Paul Bakker9be19372009-07-27 20:21:53 +00001073
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001074 if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001075 return( ret );
1076
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001077 if( ( ret = x509_get_time( p, end2, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001078 return( ret );
1079
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001080 if( ( ret = x509_get_crl_entry_ext( p, end2, &cur_entry->entry_ext ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001081 return( ret );
1082
Paul Bakker74111d32011-01-15 16:57:55 +00001083 if ( *p < end )
1084 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001085 cur_entry->next = malloc( sizeof( x509_crl_entry ) );
Paul Bakkerb15b8512012-01-13 13:44:06 +00001086
1087 if( cur_entry->next == NULL )
1088 return( POLARSSL_ERR_X509_MALLOC_FAILED );
1089
Paul Bakkerd98030e2009-05-02 15:13:40 +00001090 cur_entry = cur_entry->next;
1091 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
1092 }
1093 }
1094
1095 return( 0 );
1096}
1097
Paul Bakker27d66162010-03-17 06:56:01 +00001098static int x509_get_sig_alg( const x509_buf *sig_oid, int *sig_alg )
1099{
1100 if( sig_oid->len == 9 &&
1101 memcmp( sig_oid->p, OID_PKCS1, 8 ) == 0 )
1102 {
1103 if( sig_oid->p[8] >= 2 && sig_oid->p[8] <= 5 )
1104 {
1105 *sig_alg = sig_oid->p[8];
1106 return( 0 );
1107 }
1108
1109 if ( sig_oid->p[8] >= 11 && sig_oid->p[8] <= 14 )
1110 {
1111 *sig_alg = sig_oid->p[8];
1112 return( 0 );
1113 }
1114
1115 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1116 }
Paul Bakker400ff6f2011-02-20 10:40:16 +00001117 if( sig_oid->len == 5 &&
1118 memcmp( sig_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
1119 {
1120 *sig_alg = SIG_RSA_SHA1;
1121 return( 0 );
1122 }
Paul Bakker27d66162010-03-17 06:56:01 +00001123
1124 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1125}
1126
Paul Bakkerd98030e2009-05-02 15:13:40 +00001127/*
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001128 * Parse and fill a single X.509 certificate in DER format
Paul Bakker5121ce52009-01-03 21:22:43 +00001129 */
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001130int x509parse_crt_der( x509_cert *crt, const unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001131{
Paul Bakker23986e52011-04-24 08:57:21 +00001132 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001133 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00001134 unsigned char *p, *end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001135
Paul Bakker320a4b52009-03-28 18:52:39 +00001136 /*
1137 * Check for valid input
1138 */
1139 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001140 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker320a4b52009-03-28 18:52:39 +00001141
Paul Bakker96743fc2011-02-12 14:30:57 +00001142 p = (unsigned char *) malloc( len = buflen );
1143
1144 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001145 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001146
1147 memcpy( p, buf, buflen );
1148
1149 buflen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001150
1151 crt->raw.p = p;
1152 crt->raw.len = len;
1153 end = p + len;
1154
1155 /*
1156 * Certificate ::= SEQUENCE {
1157 * tbsCertificate TBSCertificate,
1158 * signatureAlgorithm AlgorithmIdentifier,
1159 * signatureValue BIT STRING }
1160 */
1161 if( ( ret = asn1_get_tag( &p, end, &len,
1162 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1163 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001164 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001165 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001166 }
1167
Paul Bakker23986e52011-04-24 08:57:21 +00001168 if( len != (size_t) ( end - p ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001169 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001170 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001171 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001172 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001173 }
1174
1175 /*
1176 * TBSCertificate ::= SEQUENCE {
1177 */
1178 crt->tbs.p = p;
1179
1180 if( ( ret = asn1_get_tag( &p, end, &len,
1181 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1182 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001183 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001184 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001185 }
1186
1187 end = p + len;
1188 crt->tbs.len = end - crt->tbs.p;
1189
1190 /*
1191 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1192 *
1193 * CertificateSerialNumber ::= INTEGER
1194 *
1195 * signature AlgorithmIdentifier
1196 */
1197 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1198 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1199 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
1200 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001201 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001202 return( ret );
1203 }
1204
1205 crt->version++;
1206
1207 if( crt->version > 3 )
1208 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001209 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001210 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001211 }
1212
Paul Bakker27d66162010-03-17 06:56:01 +00001213 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_alg ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001214 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001215 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001216 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001217 }
1218
1219 /*
1220 * issuer Name
1221 */
1222 crt->issuer_raw.p = p;
1223
1224 if( ( ret = asn1_get_tag( &p, end, &len,
1225 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1226 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001227 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001228 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001229 }
1230
1231 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1232 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001233 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001234 return( ret );
1235 }
1236
1237 crt->issuer_raw.len = p - crt->issuer_raw.p;
1238
1239 /*
1240 * Validity ::= SEQUENCE {
1241 * notBefore Time,
1242 * notAfter Time }
1243 *
1244 */
1245 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1246 &crt->valid_to ) ) != 0 )
1247 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001248 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001249 return( ret );
1250 }
1251
1252 /*
1253 * subject Name
1254 */
1255 crt->subject_raw.p = p;
1256
1257 if( ( ret = asn1_get_tag( &p, end, &len,
1258 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1259 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001260 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001261 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001262 }
1263
1264 if( ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
1265 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001266 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001267 return( ret );
1268 }
1269
1270 crt->subject_raw.len = p - crt->subject_raw.p;
1271
1272 /*
1273 * SubjectPublicKeyInfo ::= SEQUENCE
1274 * algorithm AlgorithmIdentifier,
1275 * subjectPublicKey BIT STRING }
1276 */
1277 if( ( ret = asn1_get_tag( &p, end, &len,
1278 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1279 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001280 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001281 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001282 }
1283
1284 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1285 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1286 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001287 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001288 return( ret );
1289 }
1290
1291 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1292 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001293 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001294 return( ret );
1295 }
1296
1297 crt->rsa.len = mpi_size( &crt->rsa.N );
1298
1299 /*
1300 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1301 * -- If present, version shall be v2 or v3
1302 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1303 * -- If present, version shall be v2 or v3
1304 * extensions [3] EXPLICIT Extensions OPTIONAL
1305 * -- If present, version shall be v3
1306 */
1307 if( crt->version == 2 || crt->version == 3 )
1308 {
1309 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1310 if( ret != 0 )
1311 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001312 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001313 return( ret );
1314 }
1315 }
1316
1317 if( crt->version == 2 || crt->version == 3 )
1318 {
1319 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1320 if( ret != 0 )
1321 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001322 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001323 return( ret );
1324 }
1325 }
1326
1327 if( crt->version == 3 )
1328 {
Paul Bakker74111d32011-01-15 16:57:55 +00001329 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001330 if( ret != 0 )
1331 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001332 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001333 return( ret );
1334 }
1335 }
1336
1337 if( p != end )
1338 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001339 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001340 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001341 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001342 }
1343
1344 end = crt->raw.p + crt->raw.len;
1345
1346 /*
1347 * signatureAlgorithm AlgorithmIdentifier,
1348 * signatureValue BIT STRING
1349 */
1350 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1351 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001352 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001353 return( ret );
1354 }
1355
Paul Bakker320a4b52009-03-28 18:52:39 +00001356 if( memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001357 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001358 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001359 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001360 }
1361
1362 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1363 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001364 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001365 return( ret );
1366 }
1367
1368 if( p != end )
1369 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001370 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001371 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001372 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001373 }
1374
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001375 return( 0 );
1376}
1377
1378/*
1379 * Parse one or more PEM certificates from a buffer and add them to the chained list
1380 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001381int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001382{
Paul Bakker69e095c2011-12-10 21:55:01 +00001383 int ret, success = 0, first_error = 0, total_failed = 0;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001384 x509_cert *crt, *prev = NULL;
1385 int buf_format = X509_FORMAT_DER;
1386
1387 crt = chain;
1388
1389 /*
1390 * Check for valid input
1391 */
1392 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001393 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001394
1395 while( crt->version != 0 && crt->next != NULL )
1396 {
1397 prev = crt;
1398 crt = crt->next;
1399 }
1400
1401 /*
1402 * Add new certificate on the end of the chain if needed.
1403 */
1404 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001405 {
1406 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1407
Paul Bakker7d06ad22009-05-02 15:53:56 +00001408 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001409 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker320a4b52009-03-28 18:52:39 +00001410
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001411 prev = crt;
Paul Bakker7d06ad22009-05-02 15:53:56 +00001412 crt = crt->next;
1413 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001414 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001415
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001416 /*
1417 * Determine buffer content. Buffer contains either one DER certificate or
1418 * one or more PEM certificates.
1419 */
1420#if defined(POLARSSL_PEM_C)
1421 if( strstr( (char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
1422 buf_format = X509_FORMAT_PEM;
1423#endif
1424
1425 if( buf_format == X509_FORMAT_DER )
1426 return x509parse_crt_der( crt, buf, buflen );
1427
1428#if defined(POLARSSL_PEM_C)
1429 if( buf_format == X509_FORMAT_PEM )
1430 {
1431 pem_context pem;
1432
1433 while( buflen > 0 )
1434 {
1435 size_t use_len;
1436 pem_init( &pem );
1437
1438 ret = pem_read_buffer( &pem,
1439 "-----BEGIN CERTIFICATE-----",
1440 "-----END CERTIFICATE-----",
1441 buf, NULL, 0, &use_len );
1442
1443 if( ret == 0 )
1444 {
1445 /*
1446 * Was PEM encoded
1447 */
1448 buflen -= use_len;
1449 buf += use_len;
1450 }
1451 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
1452 {
1453 pem_free( &pem );
1454
1455 if( first_error == 0 )
1456 first_error = ret;
1457
1458 continue;
1459 }
1460 else
1461 break;
1462
1463 ret = x509parse_crt_der( crt, pem.buf, pem.buflen );
1464
1465 pem_free( &pem );
1466
1467 if( ret != 0 )
1468 {
1469 /*
Paul Bakker69e095c2011-12-10 21:55:01 +00001470 * quit parsing on a memory error
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001471 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001472 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001473 {
1474 if( prev )
1475 prev->next = NULL;
1476
1477 if( crt != chain )
1478 free( crt );
1479
1480 return( ret );
1481 }
1482
1483 if( first_error == 0 )
1484 first_error = ret;
Paul Bakker69e095c2011-12-10 21:55:01 +00001485
1486 total_failed++;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001487
1488 memset( crt, 0, sizeof( x509_cert ) );
1489 continue;
1490 }
1491
1492 success = 1;
1493
1494 /*
1495 * Add new certificate to the list
1496 */
1497 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1498
1499 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001500 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001501
1502 prev = crt;
1503 crt = crt->next;
1504 memset( crt, 0, sizeof( x509_cert ) );
1505 }
1506 }
1507#endif
1508
1509 if( crt->version == 0 )
1510 {
1511 if( prev )
1512 prev->next = NULL;
1513
1514 if( crt != chain )
1515 free( crt );
1516 }
1517
1518 if( success )
Paul Bakker69e095c2011-12-10 21:55:01 +00001519 return( total_failed );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001520 else if( first_error )
1521 return( first_error );
1522 else
1523 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001524}
1525
1526/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001527 * Parse one or more CRLs and add them to the chained list
1528 */
Paul Bakker23986e52011-04-24 08:57:21 +00001529int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001530{
Paul Bakker23986e52011-04-24 08:57:21 +00001531 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001532 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001533 unsigned char *p, *end;
1534 x509_crl *crl;
Paul Bakker96743fc2011-02-12 14:30:57 +00001535#if defined(POLARSSL_PEM_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00001536 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001537 pem_context pem;
1538#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001539
1540 crl = chain;
1541
1542 /*
1543 * Check for valid input
1544 */
1545 if( crl == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001546 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001547
1548 while( crl->version != 0 && crl->next != NULL )
1549 crl = crl->next;
1550
1551 /*
1552 * Add new CRL on the end of the chain if needed.
1553 */
1554 if ( crl->version != 0 && crl->next == NULL)
1555 {
1556 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1557
Paul Bakker7d06ad22009-05-02 15:53:56 +00001558 if( crl->next == NULL )
1559 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001560 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001561 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001562 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001563
Paul Bakker7d06ad22009-05-02 15:53:56 +00001564 crl = crl->next;
1565 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001566 }
1567
Paul Bakker96743fc2011-02-12 14:30:57 +00001568#if defined(POLARSSL_PEM_C)
1569 pem_init( &pem );
1570 ret = pem_read_buffer( &pem,
1571 "-----BEGIN X509 CRL-----",
1572 "-----END X509 CRL-----",
1573 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001574
Paul Bakker96743fc2011-02-12 14:30:57 +00001575 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001576 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001577 /*
1578 * Was PEM encoded
1579 */
1580 buflen -= use_len;
1581 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001582
1583 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001584 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001585 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001586 p = pem.buf;
1587 pem.buf = NULL;
1588 len = pem.buflen;
1589 pem_free( &pem );
1590 }
1591 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
1592 {
1593 pem_free( &pem );
1594 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001595 }
1596 else
1597 {
1598 /*
1599 * nope, copy the raw DER data
1600 */
1601 p = (unsigned char *) malloc( len = buflen );
1602
1603 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001604 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001605
1606 memcpy( p, buf, buflen );
1607
1608 buflen = 0;
1609 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001610#else
1611 p = (unsigned char *) malloc( len = buflen );
1612
1613 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001614 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001615
1616 memcpy( p, buf, buflen );
1617
1618 buflen = 0;
1619#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001620
1621 crl->raw.p = p;
1622 crl->raw.len = len;
1623 end = p + len;
1624
1625 /*
1626 * CertificateList ::= SEQUENCE {
1627 * tbsCertList TBSCertList,
1628 * signatureAlgorithm AlgorithmIdentifier,
1629 * signatureValue BIT STRING }
1630 */
1631 if( ( ret = asn1_get_tag( &p, end, &len,
1632 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1633 {
1634 x509_crl_free( crl );
1635 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1636 }
1637
Paul Bakker23986e52011-04-24 08:57:21 +00001638 if( len != (size_t) ( end - p ) )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001639 {
1640 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001641 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001642 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1643 }
1644
1645 /*
1646 * TBSCertList ::= SEQUENCE {
1647 */
1648 crl->tbs.p = p;
1649
1650 if( ( ret = asn1_get_tag( &p, end, &len,
1651 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1652 {
1653 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001654 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001655 }
1656
1657 end = p + len;
1658 crl->tbs.len = end - crl->tbs.p;
1659
1660 /*
1661 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1662 * -- if present, MUST be v2
1663 *
1664 * signature AlgorithmIdentifier
1665 */
Paul Bakker3329d1f2011-10-12 09:55:01 +00001666 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
Paul Bakkerd98030e2009-05-02 15:13:40 +00001667 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1668 {
1669 x509_crl_free( crl );
1670 return( ret );
1671 }
1672
1673 crl->version++;
1674
1675 if( crl->version > 2 )
1676 {
1677 x509_crl_free( crl );
1678 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1679 }
1680
Paul Bakker27d66162010-03-17 06:56:01 +00001681 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_alg ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001682 {
1683 x509_crl_free( crl );
1684 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1685 }
1686
1687 /*
1688 * issuer Name
1689 */
1690 crl->issuer_raw.p = p;
1691
1692 if( ( ret = asn1_get_tag( &p, end, &len,
1693 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1694 {
1695 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001696 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001697 }
1698
1699 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1700 {
1701 x509_crl_free( crl );
1702 return( ret );
1703 }
1704
1705 crl->issuer_raw.len = p - crl->issuer_raw.p;
1706
1707 /*
1708 * thisUpdate Time
1709 * nextUpdate Time OPTIONAL
1710 */
Paul Bakker91200182010-02-18 21:26:15 +00001711 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001712 {
1713 x509_crl_free( crl );
1714 return( ret );
1715 }
1716
Paul Bakker91200182010-02-18 21:26:15 +00001717 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001718 {
Paul Bakker9d781402011-05-09 16:17:09 +00001719 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001720 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker9d781402011-05-09 16:17:09 +00001721 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001722 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001723 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001724 x509_crl_free( crl );
1725 return( ret );
1726 }
1727 }
1728
1729 /*
1730 * revokedCertificates SEQUENCE OF SEQUENCE {
1731 * userCertificate CertificateSerialNumber,
1732 * revocationDate Time,
1733 * crlEntryExtensions Extensions OPTIONAL
1734 * -- if present, MUST be v2
1735 * } OPTIONAL
1736 */
1737 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1738 {
1739 x509_crl_free( crl );
1740 return( ret );
1741 }
1742
1743 /*
1744 * crlExtensions EXPLICIT Extensions OPTIONAL
1745 * -- if present, MUST be v2
1746 */
1747 if( crl->version == 2 )
1748 {
1749 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1750
1751 if( ret != 0 )
1752 {
1753 x509_crl_free( crl );
1754 return( ret );
1755 }
1756 }
1757
1758 if( p != end )
1759 {
1760 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001761 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001762 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1763 }
1764
1765 end = crl->raw.p + crl->raw.len;
1766
1767 /*
1768 * signatureAlgorithm AlgorithmIdentifier,
1769 * signatureValue BIT STRING
1770 */
1771 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1772 {
1773 x509_crl_free( crl );
1774 return( ret );
1775 }
1776
1777 if( memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
1778 {
1779 x509_crl_free( crl );
1780 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1781 }
1782
1783 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1784 {
1785 x509_crl_free( crl );
1786 return( ret );
1787 }
1788
1789 if( p != end )
1790 {
1791 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001792 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001793 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1794 }
1795
1796 if( buflen > 0 )
1797 {
1798 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1799
Paul Bakker7d06ad22009-05-02 15:53:56 +00001800 if( crl->next == NULL )
1801 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001802 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001803 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001804 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001805
Paul Bakker7d06ad22009-05-02 15:53:56 +00001806 crl = crl->next;
1807 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001808
1809 return( x509parse_crl( crl, buf, buflen ) );
1810 }
1811
1812 return( 0 );
1813}
1814
Paul Bakker335db3f2011-04-25 15:28:35 +00001815#if defined(POLARSSL_FS_IO)
Paul Bakkerd98030e2009-05-02 15:13:40 +00001816/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001817 * Load all data from a file into a given buffer.
1818 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001819int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001820{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001821 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001822
Paul Bakkerd98030e2009-05-02 15:13:40 +00001823 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001824 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001825
Paul Bakkerd98030e2009-05-02 15:13:40 +00001826 fseek( f, 0, SEEK_END );
1827 *n = (size_t) ftell( f );
1828 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001829
Paul Bakkerd98030e2009-05-02 15:13:40 +00001830 if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001831 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001832
Paul Bakkerd98030e2009-05-02 15:13:40 +00001833 if( fread( *buf, 1, *n, f ) != *n )
1834 {
1835 fclose( f );
1836 free( *buf );
Paul Bakker69e095c2011-12-10 21:55:01 +00001837 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001838 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001839
Paul Bakkerd98030e2009-05-02 15:13:40 +00001840 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001841
Paul Bakkerd98030e2009-05-02 15:13:40 +00001842 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001843
Paul Bakkerd98030e2009-05-02 15:13:40 +00001844 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001845}
1846
1847/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001848 * Load one or more certificates and add them to the chained list
1849 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001850int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001851{
1852 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001853 size_t n;
1854 unsigned char *buf;
1855
Paul Bakker69e095c2011-12-10 21:55:01 +00001856 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1857 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001858
Paul Bakker69e095c2011-12-10 21:55:01 +00001859 ret = x509parse_crt( chain, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001860
1861 memset( buf, 0, n + 1 );
1862 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001863
1864 return( ret );
1865}
1866
Paul Bakker8d914582012-06-04 12:46:42 +00001867int x509parse_crtpath( x509_cert *chain, const char *path )
1868{
1869 int ret = 0;
1870#if defined(_WIN32)
1871 int t_ret;
1872 TCHAR szDir[MAX_PATH];
1873 WIN32_FIND_DATA file_data;
1874 HANDLE hFind;
1875 DWORD dwError = 0;
1876
1877 StringCchCopy(szDir, MAX_PATH, path);
1878 StringCchCat(szDir, MAX_PATH, TEXT("\\*"));
1879
1880 hFind = FindFirstFile( szDir, &file_data );
1881 if (hFind == INVALID_HANDLE_VALUE)
1882 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1883
1884 do
1885 {
1886 if( file_data.dwAttributes & FILE_ATTRIBUTE_DIRECTORY )
1887 continue;
1888
1889 t_ret = x509parse_crtfile( chain, entry_name );
1890 if( t_ret < 0 )
1891 return( t_ret );
1892
1893 ret += t_ret;
1894 }
1895 while( FindNextFile( hFind, &file_data ) != 0 );
1896
1897 dwError = GetLastError();
1898 if (dwError != ERROR_NO_MORE_FILES)
1899 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1900
1901 FindClose( hFind );
1902#else
1903 int t_ret;
1904 struct dirent *entry;
1905 char entry_name[255];
1906 DIR *dir = opendir( path );
1907
1908 if( dir == NULL)
1909 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
1910
1911 while( ( entry = readdir( dir ) ) != NULL )
1912 {
1913 if( entry->d_type != DT_REG )
1914 continue;
1915
1916 snprintf( entry_name, sizeof(entry_name), "%s/%s", path, entry->d_name );
1917 t_ret = x509parse_crtfile( chain, entry_name );
1918 if( t_ret < 0 )
1919 return( t_ret );
1920
1921 ret += t_ret;
1922 }
1923 closedir( dir );
1924#endif
1925
1926 return( ret );
1927}
1928
Paul Bakkerd98030e2009-05-02 15:13:40 +00001929/*
1930 * Load one or more CRLs and add them to the chained list
1931 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001932int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001933{
1934 int ret;
1935 size_t n;
1936 unsigned char *buf;
1937
Paul Bakker69e095c2011-12-10 21:55:01 +00001938 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1939 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001940
Paul Bakker27fdf462011-06-09 13:55:13 +00001941 ret = x509parse_crl( chain, buf, n );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001942
1943 memset( buf, 0, n + 1 );
1944 free( buf );
1945
1946 return( ret );
1947}
1948
Paul Bakker5121ce52009-01-03 21:22:43 +00001949/*
Paul Bakker335db3f2011-04-25 15:28:35 +00001950 * Load and parse a private RSA key
1951 */
1952int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
1953{
1954 int ret;
1955 size_t n;
1956 unsigned char *buf;
1957
Paul Bakker69e095c2011-12-10 21:55:01 +00001958 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1959 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00001960
1961 if( pwd == NULL )
Paul Bakker27fdf462011-06-09 13:55:13 +00001962 ret = x509parse_key( rsa, buf, n, NULL, 0 );
Paul Bakker335db3f2011-04-25 15:28:35 +00001963 else
Paul Bakker27fdf462011-06-09 13:55:13 +00001964 ret = x509parse_key( rsa, buf, n,
Paul Bakker335db3f2011-04-25 15:28:35 +00001965 (unsigned char *) pwd, strlen( pwd ) );
1966
1967 memset( buf, 0, n + 1 );
1968 free( buf );
1969
1970 return( ret );
1971}
1972
1973/*
1974 * Load and parse a public RSA key
1975 */
1976int x509parse_public_keyfile( rsa_context *rsa, const char *path )
1977{
1978 int ret;
1979 size_t n;
1980 unsigned char *buf;
1981
Paul Bakker69e095c2011-12-10 21:55:01 +00001982 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1983 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00001984
Paul Bakker27fdf462011-06-09 13:55:13 +00001985 ret = x509parse_public_key( rsa, buf, n );
Paul Bakker335db3f2011-04-25 15:28:35 +00001986
1987 memset( buf, 0, n + 1 );
1988 free( buf );
1989
1990 return( ret );
1991}
1992#endif /* POLARSSL_FS_IO */
1993
1994/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001995 * Parse a private RSA key
1996 */
Paul Bakker23986e52011-04-24 08:57:21 +00001997int x509parse_key( rsa_context *rsa, const unsigned char *key, size_t keylen,
1998 const unsigned char *pwd, size_t pwdlen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001999{
Paul Bakker23986e52011-04-24 08:57:21 +00002000 int ret;
2001 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00002002 unsigned char *p, *end;
Paul Bakkered56b222011-07-13 11:26:43 +00002003 unsigned char *p_alt;
2004 x509_buf pk_alg_oid;
2005
Paul Bakker96743fc2011-02-12 14:30:57 +00002006#if defined(POLARSSL_PEM_C)
2007 pem_context pem;
Paul Bakker5121ce52009-01-03 21:22:43 +00002008
Paul Bakker96743fc2011-02-12 14:30:57 +00002009 pem_init( &pem );
2010 ret = pem_read_buffer( &pem,
2011 "-----BEGIN RSA PRIVATE KEY-----",
2012 "-----END RSA PRIVATE KEY-----",
2013 key, pwd, pwdlen, &len );
Paul Bakker5121ce52009-01-03 21:22:43 +00002014
Paul Bakkered56b222011-07-13 11:26:43 +00002015 if( ret == POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
2016 {
2017 ret = pem_read_buffer( &pem,
2018 "-----BEGIN PRIVATE KEY-----",
2019 "-----END PRIVATE KEY-----",
2020 key, pwd, pwdlen, &len );
2021 }
2022
Paul Bakker96743fc2011-02-12 14:30:57 +00002023 if( ret == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002024 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002025 /*
2026 * Was PEM encoded
2027 */
2028 keylen = pem.buflen;
Paul Bakker5121ce52009-01-03 21:22:43 +00002029 }
Paul Bakker96743fc2011-02-12 14:30:57 +00002030 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
Paul Bakkerff60ee62010-03-16 21:09:09 +00002031 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002032 pem_free( &pem );
2033 return( ret );
Paul Bakkerff60ee62010-03-16 21:09:09 +00002034 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002035
Paul Bakker96743fc2011-02-12 14:30:57 +00002036 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2037#else
Paul Bakker5690efc2011-05-26 13:16:06 +00002038 ((void) pwd);
2039 ((void) pwdlen);
Paul Bakker96743fc2011-02-12 14:30:57 +00002040 p = (unsigned char *) key;
2041#endif
2042 end = p + keylen;
2043
Paul Bakker5121ce52009-01-03 21:22:43 +00002044 /*
Paul Bakkered56b222011-07-13 11:26:43 +00002045 * Note: Depending on the type of private key file one can expect either a
2046 * PrivatKeyInfo object (PKCS#8) or a RSAPrivateKey (PKCS#1) directly.
2047 *
2048 * PrivateKeyInfo ::= SEQUENCE {
Paul Bakker5c721f92011-07-27 16:51:09 +00002049 * version Version,
Paul Bakkered56b222011-07-13 11:26:43 +00002050 * algorithm AlgorithmIdentifier,
2051 * PrivateKey BIT STRING
2052 * }
2053 *
2054 * AlgorithmIdentifier ::= SEQUENCE {
2055 * algorithm OBJECT IDENTIFIER,
2056 * parameters ANY DEFINED BY algorithm OPTIONAL
2057 * }
2058 *
Paul Bakker5121ce52009-01-03 21:22:43 +00002059 * RSAPrivateKey ::= SEQUENCE {
2060 * version Version,
2061 * modulus INTEGER, -- n
2062 * publicExponent INTEGER, -- e
2063 * privateExponent INTEGER, -- d
2064 * prime1 INTEGER, -- p
2065 * prime2 INTEGER, -- q
2066 * exponent1 INTEGER, -- d mod (p-1)
2067 * exponent2 INTEGER, -- d mod (q-1)
2068 * coefficient INTEGER, -- (inverse of q) mod p
2069 * otherPrimeInfos OtherPrimeInfos OPTIONAL
2070 * }
2071 */
2072 if( ( ret = asn1_get_tag( &p, end, &len,
2073 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2074 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002075#if defined(POLARSSL_PEM_C)
2076 pem_free( &pem );
2077#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002078 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002079 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002080 }
2081
2082 end = p + len;
2083
2084 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2085 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002086#if defined(POLARSSL_PEM_C)
2087 pem_free( &pem );
2088#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002089 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002090 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002091 }
2092
2093 if( rsa->ver != 0 )
2094 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002095#if defined(POLARSSL_PEM_C)
2096 pem_free( &pem );
2097#endif
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_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002100 }
2101
Paul Bakkered56b222011-07-13 11:26:43 +00002102 p_alt = p;
2103
2104 if( ( ret = x509_get_alg( &p_alt, end, &pk_alg_oid ) ) != 0 )
2105 {
2106 // Assume that we have the PKCS#1 format if wrong
2107 // tag was encountered
2108 //
2109 if( ret != POLARSSL_ERR_X509_CERT_INVALID_ALG +
2110 POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
2111 {
2112#if defined(POLARSSL_PEM_C)
2113 pem_free( &pem );
2114#endif
2115 rsa_free( rsa );
2116 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
2117 }
2118 }
2119 else
2120 {
2121 int can_handle;
2122
2123 /*
2124 * only RSA keys handled at this time
2125 */
2126 can_handle = 0;
2127
2128 if( pk_alg_oid.len == 9 &&
2129 memcmp( pk_alg_oid.p, OID_PKCS1_RSA, 9 ) == 0 )
2130 can_handle = 1;
2131
2132 if( pk_alg_oid.len == 9 &&
2133 memcmp( pk_alg_oid.p, OID_PKCS1, 8 ) == 0 )
2134 {
2135 if( pk_alg_oid.p[8] >= 2 && pk_alg_oid.p[8] <= 5 )
2136 can_handle = 1;
2137
2138 if ( pk_alg_oid.p[8] >= 11 && pk_alg_oid.p[8] <= 14 )
2139 can_handle = 1;
2140 }
2141
2142 if( pk_alg_oid.len == 5 &&
2143 memcmp( pk_alg_oid.p, OID_RSA_SHA_OBS, 5 ) == 0 )
2144 can_handle = 1;
2145
2146 if( can_handle == 0 )
2147 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
2148
2149 /*
2150 * Parse the PKCS#8 format
2151 */
2152
2153 p = p_alt;
2154 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2155 {
2156#if defined(POLARSSL_PEM_C)
2157 pem_free( &pem );
2158#endif
2159 rsa_free( rsa );
2160 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2161 }
2162
2163 if( ( end - p ) < 1 )
2164 {
2165#if defined(POLARSSL_PEM_C)
2166 pem_free( &pem );
2167#endif
2168 rsa_free( rsa );
2169 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
2170 POLARSSL_ERR_ASN1_OUT_OF_DATA );
2171 }
2172
2173 end = p + len;
2174
2175 if( ( ret = asn1_get_tag( &p, end, &len,
2176 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2177 {
2178#if defined(POLARSSL_PEM_C)
2179 pem_free( &pem );
2180#endif
2181 rsa_free( rsa );
2182 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2183 }
2184
2185 end = p + len;
2186
2187 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2188 {
2189#if defined(POLARSSL_PEM_C)
2190 pem_free( &pem );
2191#endif
2192 rsa_free( rsa );
2193 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2194 }
2195
2196 if( rsa->ver != 0 )
2197 {
2198#if defined(POLARSSL_PEM_C)
2199 pem_free( &pem );
2200#endif
2201 rsa_free( rsa );
2202 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2203 }
2204 }
2205
Paul Bakker5121ce52009-01-03 21:22:43 +00002206 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
2207 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
2208 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
2209 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
2210 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
2211 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
2212 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
2213 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
2214 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002215#if defined(POLARSSL_PEM_C)
2216 pem_free( &pem );
2217#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002218 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002219 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002220 }
2221
2222 rsa->len = mpi_size( &rsa->N );
2223
2224 if( p != end )
2225 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002226#if defined(POLARSSL_PEM_C)
2227 pem_free( &pem );
2228#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002229 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002230 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00002231 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002232 }
2233
2234 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2235 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002236#if defined(POLARSSL_PEM_C)
2237 pem_free( &pem );
2238#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002239 rsa_free( rsa );
2240 return( ret );
2241 }
2242
Paul Bakker96743fc2011-02-12 14:30:57 +00002243#if defined(POLARSSL_PEM_C)
2244 pem_free( &pem );
2245#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002246
2247 return( 0 );
2248}
2249
2250/*
Paul Bakker53019ae2011-03-25 13:58:48 +00002251 * Parse a public RSA key
2252 */
Paul Bakker23986e52011-04-24 08:57:21 +00002253int x509parse_public_key( rsa_context *rsa, const unsigned char *key, size_t keylen )
Paul Bakker53019ae2011-03-25 13:58:48 +00002254{
Paul Bakker23986e52011-04-24 08:57:21 +00002255 int ret;
2256 size_t len;
Paul Bakker53019ae2011-03-25 13:58:48 +00002257 unsigned char *p, *end;
2258 x509_buf alg_oid;
2259#if defined(POLARSSL_PEM_C)
2260 pem_context pem;
2261
2262 pem_init( &pem );
2263 ret = pem_read_buffer( &pem,
2264 "-----BEGIN PUBLIC KEY-----",
2265 "-----END PUBLIC KEY-----",
2266 key, NULL, 0, &len );
2267
2268 if( ret == 0 )
2269 {
2270 /*
2271 * Was PEM encoded
2272 */
2273 keylen = pem.buflen;
2274 }
2275 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
2276 {
2277 pem_free( &pem );
2278 return( ret );
2279 }
2280
2281 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2282#else
2283 p = (unsigned char *) key;
2284#endif
2285 end = p + keylen;
2286
2287 /*
2288 * PublicKeyInfo ::= SEQUENCE {
2289 * algorithm AlgorithmIdentifier,
2290 * PublicKey BIT STRING
2291 * }
2292 *
2293 * AlgorithmIdentifier ::= SEQUENCE {
2294 * algorithm OBJECT IDENTIFIER,
2295 * parameters ANY DEFINED BY algorithm OPTIONAL
2296 * }
2297 *
2298 * RSAPublicKey ::= SEQUENCE {
2299 * modulus INTEGER, -- n
2300 * publicExponent INTEGER -- e
2301 * }
2302 */
2303
2304 if( ( ret = asn1_get_tag( &p, end, &len,
2305 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2306 {
2307#if defined(POLARSSL_PEM_C)
2308 pem_free( &pem );
2309#endif
2310 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002311 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002312 }
2313
2314 if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
2315 {
2316#if defined(POLARSSL_PEM_C)
2317 pem_free( &pem );
2318#endif
2319 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002320 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002321 }
2322
2323 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
2324 {
2325#if defined(POLARSSL_PEM_C)
2326 pem_free( &pem );
2327#endif
2328 rsa_free( rsa );
2329 return( ret );
2330 }
2331
2332 rsa->len = mpi_size( &rsa->N );
2333
2334#if defined(POLARSSL_PEM_C)
2335 pem_free( &pem );
2336#endif
2337
2338 return( 0 );
2339}
2340
Paul Bakkereaa89f82011-04-04 21:36:15 +00002341#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00002342/*
Paul Bakker1b57b062011-01-06 15:48:19 +00002343 * Parse DHM parameters
2344 */
Paul Bakker23986e52011-04-24 08:57:21 +00002345int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
Paul Bakker1b57b062011-01-06 15:48:19 +00002346{
Paul Bakker23986e52011-04-24 08:57:21 +00002347 int ret;
2348 size_t len;
Paul Bakker1b57b062011-01-06 15:48:19 +00002349 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00002350#if defined(POLARSSL_PEM_C)
2351 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00002352
Paul Bakker96743fc2011-02-12 14:30:57 +00002353 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00002354
Paul Bakker96743fc2011-02-12 14:30:57 +00002355 ret = pem_read_buffer( &pem,
2356 "-----BEGIN DH PARAMETERS-----",
2357 "-----END DH PARAMETERS-----",
2358 dhmin, NULL, 0, &dhminlen );
2359
2360 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00002361 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002362 /*
2363 * Was PEM encoded
2364 */
2365 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00002366 }
Paul Bakker96743fc2011-02-12 14:30:57 +00002367 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00002368 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002369 pem_free( &pem );
2370 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002371 }
2372
Paul Bakker96743fc2011-02-12 14:30:57 +00002373 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
2374#else
2375 p = (unsigned char *) dhmin;
2376#endif
2377 end = p + dhminlen;
2378
Paul Bakker1b57b062011-01-06 15:48:19 +00002379 memset( dhm, 0, sizeof( dhm_context ) );
2380
Paul Bakker1b57b062011-01-06 15:48:19 +00002381 /*
2382 * DHParams ::= SEQUENCE {
2383 * prime INTEGER, -- P
2384 * generator INTEGER, -- g
2385 * }
2386 */
2387 if( ( ret = asn1_get_tag( &p, end, &len,
2388 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2389 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002390#if defined(POLARSSL_PEM_C)
2391 pem_free( &pem );
2392#endif
Paul Bakker9d781402011-05-09 16:17:09 +00002393 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002394 }
2395
2396 end = p + len;
2397
2398 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
2399 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
2400 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002401#if defined(POLARSSL_PEM_C)
2402 pem_free( &pem );
2403#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002404 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002405 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002406 }
2407
2408 if( p != end )
2409 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002410#if defined(POLARSSL_PEM_C)
2411 pem_free( &pem );
2412#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002413 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002414 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker1b57b062011-01-06 15:48:19 +00002415 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
2416 }
2417
Paul Bakker96743fc2011-02-12 14:30:57 +00002418#if defined(POLARSSL_PEM_C)
2419 pem_free( &pem );
2420#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002421
2422 return( 0 );
2423}
2424
Paul Bakker335db3f2011-04-25 15:28:35 +00002425#if defined(POLARSSL_FS_IO)
Paul Bakker1b57b062011-01-06 15:48:19 +00002426/*
2427 * Load and parse a private RSA key
2428 */
2429int x509parse_dhmfile( dhm_context *dhm, const char *path )
2430{
2431 int ret;
2432 size_t n;
2433 unsigned char *buf;
2434
Paul Bakker69e095c2011-12-10 21:55:01 +00002435 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
2436 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002437
Paul Bakker27fdf462011-06-09 13:55:13 +00002438 ret = x509parse_dhm( dhm, buf, n );
Paul Bakker1b57b062011-01-06 15:48:19 +00002439
2440 memset( buf, 0, n + 1 );
2441 free( buf );
2442
2443 return( ret );
2444}
Paul Bakker335db3f2011-04-25 15:28:35 +00002445#endif /* POLARSSL_FS_IO */
Paul Bakkereaa89f82011-04-04 21:36:15 +00002446#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00002447
Paul Bakker5121ce52009-01-03 21:22:43 +00002448#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002449#include <stdarg.h>
2450
2451#if !defined vsnprintf
2452#define vsnprintf _vsnprintf
2453#endif // vsnprintf
2454
2455/*
2456 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2457 * Result value is not size of buffer needed, but -1 if no fit is possible.
2458 *
2459 * This fuction tries to 'fix' this by at least suggesting enlarging the
2460 * size by 20.
2461 */
2462int compat_snprintf(char *str, size_t size, const char *format, ...)
2463{
2464 va_list ap;
2465 int res = -1;
2466
2467 va_start( ap, format );
2468
2469 res = vsnprintf( str, size, format, ap );
2470
2471 va_end( ap );
2472
2473 // No quick fix possible
2474 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00002475 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002476
2477 return res;
2478}
2479
2480#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002481#endif
2482
Paul Bakkerd98030e2009-05-02 15:13:40 +00002483#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2484
2485#define SAFE_SNPRINTF() \
2486{ \
2487 if( ret == -1 ) \
2488 return( -1 ); \
2489 \
Paul Bakker23986e52011-04-24 08:57:21 +00002490 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002491 p[n - 1] = '\0'; \
2492 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2493 } \
2494 \
Paul Bakker23986e52011-04-24 08:57:21 +00002495 n -= (unsigned int) ret; \
2496 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002497}
2498
Paul Bakker5121ce52009-01-03 21:22:43 +00002499/*
2500 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002501 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002502 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002503int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002504{
Paul Bakker23986e52011-04-24 08:57:21 +00002505 int ret;
2506 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002507 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002508 const x509_name *name;
Paul Bakker5121ce52009-01-03 21:22:43 +00002509 char s[128], *p;
2510
2511 memset( s, 0, sizeof( s ) );
2512
2513 name = dn;
2514 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002515 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002516
2517 while( name != NULL )
2518 {
Paul Bakker74111d32011-01-15 16:57:55 +00002519 if( name != dn )
2520 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002521 ret = snprintf( p, n, ", " );
2522 SAFE_SNPRINTF();
2523 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002524
2525 if( memcmp( name->oid.p, OID_X520, 2 ) == 0 )
2526 {
2527 switch( name->oid.p[2] )
2528 {
2529 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002530 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002531
2532 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002533 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002534
2535 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002536 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002537
2538 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002539 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002540
2541 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002542 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002543
2544 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002545 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002546
2547 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002548 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002549 name->oid.p[2] );
2550 break;
2551 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002552 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002553 }
2554 else if( memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
2555 {
2556 switch( name->oid.p[8] )
2557 {
2558 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002559 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002560
2561 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002562 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002563 name->oid.p[8] );
2564 break;
2565 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002566 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002567 }
2568 else
Paul Bakker74111d32011-01-15 16:57:55 +00002569 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002570 ret = snprintf( p, n, "\?\?=" );
Paul Bakker74111d32011-01-15 16:57:55 +00002571 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002572 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002573
2574 for( i = 0; i < name->val.len; i++ )
2575 {
Paul Bakker27fdf462011-06-09 13:55:13 +00002576 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002577 break;
2578
2579 c = name->val.p[i];
2580 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2581 s[i] = '?';
2582 else s[i] = c;
2583 }
2584 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002585 ret = snprintf( p, n, "%s", s );
2586 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002587 name = name->next;
2588 }
2589
Paul Bakker23986e52011-04-24 08:57:21 +00002590 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002591}
2592
2593/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002594 * Store the serial in printable form into buf; no more
2595 * than size characters will be written
2596 */
2597int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2598{
Paul Bakker23986e52011-04-24 08:57:21 +00002599 int ret;
2600 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00002601 char *p;
2602
2603 p = buf;
2604 n = size;
2605
2606 nr = ( serial->len <= 32 )
Paul Bakker03c7c252011-11-25 12:37:37 +00002607 ? serial->len : 28;
Paul Bakkerdd476992011-01-16 21:34:59 +00002608
2609 for( i = 0; i < nr; i++ )
2610 {
Paul Bakker93048802011-12-05 14:38:06 +00002611 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002612 continue;
2613
Paul Bakkerdd476992011-01-16 21:34:59 +00002614 ret = snprintf( p, n, "%02X%s",
2615 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2616 SAFE_SNPRINTF();
2617 }
2618
Paul Bakker03c7c252011-11-25 12:37:37 +00002619 if( nr != serial->len )
2620 {
2621 ret = snprintf( p, n, "...." );
2622 SAFE_SNPRINTF();
2623 }
2624
Paul Bakker23986e52011-04-24 08:57:21 +00002625 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00002626}
2627
2628/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002629 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002630 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002631int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2632 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002633{
Paul Bakker23986e52011-04-24 08:57:21 +00002634 int ret;
2635 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002636 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00002637
2638 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002639 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002640
Paul Bakkerd98030e2009-05-02 15:13:40 +00002641 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002642 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002643 SAFE_SNPRINTF();
2644 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002645 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002646 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002647
Paul Bakkerdd476992011-01-16 21:34:59 +00002648 ret = x509parse_serial_gets( p, n, &crt->serial);
2649 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002650
Paul Bakkerd98030e2009-05-02 15:13:40 +00002651 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2652 SAFE_SNPRINTF();
2653 ret = x509parse_dn_gets( p, n, &crt->issuer );
2654 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002655
Paul Bakkerd98030e2009-05-02 15:13:40 +00002656 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2657 SAFE_SNPRINTF();
2658 ret = x509parse_dn_gets( p, n, &crt->subject );
2659 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002660
Paul Bakkerd98030e2009-05-02 15:13:40 +00002661 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002662 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2663 crt->valid_from.year, crt->valid_from.mon,
2664 crt->valid_from.day, crt->valid_from.hour,
2665 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002666 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002667
Paul Bakkerd98030e2009-05-02 15:13:40 +00002668 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002669 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2670 crt->valid_to.year, crt->valid_to.mon,
2671 crt->valid_to.day, crt->valid_to.hour,
2672 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002673 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002674
Paul Bakkerd98030e2009-05-02 15:13:40 +00002675 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2676 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002677
Paul Bakker27d66162010-03-17 06:56:01 +00002678 switch( crt->sig_alg )
Paul Bakker5121ce52009-01-03 21:22:43 +00002679 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002680 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2681 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2682 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2683 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2684 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2685 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2686 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2687 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2688 default: ret = snprintf( p, n, "???" ); break;
2689 }
2690 SAFE_SNPRINTF();
2691
2692 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
Paul Bakkerf4f69682011-04-24 16:08:12 +00002693 (int) crt->rsa.N.n * (int) sizeof( unsigned long ) * 8 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002694 SAFE_SNPRINTF();
2695
Paul Bakker23986e52011-04-24 08:57:21 +00002696 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002697}
2698
Paul Bakker74111d32011-01-15 16:57:55 +00002699/* Compare a given OID string with an OID x509_buf * */
2700#define OID_CMP(oid_str, oid_buf) \
2701 ( ( OID_SIZE(oid_str) == (oid_buf)->len ) && \
2702 memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0)
2703
2704/*
2705 * Return an informational string describing the given OID
2706 */
2707const char *x509_oid_get_description( x509_buf *oid )
2708{
2709 if ( oid == NULL )
2710 return ( NULL );
2711
2712 else if( OID_CMP( OID_SERVER_AUTH, oid ) )
2713 return( STRING_SERVER_AUTH );
2714
2715 else if( OID_CMP( OID_CLIENT_AUTH, oid ) )
2716 return( STRING_CLIENT_AUTH );
2717
2718 else if( OID_CMP( OID_CODE_SIGNING, oid ) )
2719 return( STRING_CODE_SIGNING );
2720
2721 else if( OID_CMP( OID_EMAIL_PROTECTION, oid ) )
2722 return( STRING_EMAIL_PROTECTION );
2723
2724 else if( OID_CMP( OID_TIME_STAMPING, oid ) )
2725 return( STRING_TIME_STAMPING );
2726
2727 else if( OID_CMP( OID_OCSP_SIGNING, oid ) )
2728 return( STRING_OCSP_SIGNING );
2729
2730 return( NULL );
2731}
2732
2733/* Return the x.y.z.... style numeric string for the given OID */
2734int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2735{
Paul Bakker23986e52011-04-24 08:57:21 +00002736 int ret;
2737 size_t i, n;
Paul Bakker74111d32011-01-15 16:57:55 +00002738 unsigned int value;
2739 char *p;
2740
2741 p = buf;
2742 n = size;
2743
2744 /* First byte contains first two dots */
2745 if( oid->len > 0 )
2746 {
2747 ret = snprintf( p, n, "%d.%d", oid->p[0]/40, oid->p[0]%40 );
2748 SAFE_SNPRINTF();
2749 }
2750
2751 /* TODO: value can overflow in value. */
2752 value = 0;
Paul Bakker23986e52011-04-24 08:57:21 +00002753 for( i = 1; i < oid->len; i++ )
Paul Bakker74111d32011-01-15 16:57:55 +00002754 {
2755 value <<= 7;
2756 value += oid->p[i] & 0x7F;
2757
2758 if( !( oid->p[i] & 0x80 ) )
2759 {
2760 /* Last byte */
2761 ret = snprintf( p, n, ".%d", value );
2762 SAFE_SNPRINTF();
2763 value = 0;
2764 }
2765 }
2766
Paul Bakker23986e52011-04-24 08:57:21 +00002767 return( (int) ( size - n ) );
Paul Bakker74111d32011-01-15 16:57:55 +00002768}
2769
Paul Bakkerd98030e2009-05-02 15:13:40 +00002770/*
2771 * Return an informational string about the CRL.
2772 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002773int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2774 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002775{
Paul Bakker23986e52011-04-24 08:57:21 +00002776 int ret;
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002777 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002778 char *p;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002779 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002780
2781 p = buf;
2782 n = size;
2783
2784 ret = snprintf( p, n, "%sCRL version : %d",
2785 prefix, crl->version );
2786 SAFE_SNPRINTF();
2787
2788 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2789 SAFE_SNPRINTF();
2790 ret = x509parse_dn_gets( p, n, &crl->issuer );
2791 SAFE_SNPRINTF();
2792
2793 ret = snprintf( p, n, "\n%sthis update : " \
2794 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2795 crl->this_update.year, crl->this_update.mon,
2796 crl->this_update.day, crl->this_update.hour,
2797 crl->this_update.min, crl->this_update.sec );
2798 SAFE_SNPRINTF();
2799
2800 ret = snprintf( p, n, "\n%snext update : " \
2801 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2802 crl->next_update.year, crl->next_update.mon,
2803 crl->next_update.day, crl->next_update.hour,
2804 crl->next_update.min, crl->next_update.sec );
2805 SAFE_SNPRINTF();
2806
2807 entry = &crl->entry;
2808
2809 ret = snprintf( p, n, "\n%sRevoked certificates:",
2810 prefix );
2811 SAFE_SNPRINTF();
2812
Paul Bakker9be19372009-07-27 20:21:53 +00002813 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002814 {
2815 ret = snprintf( p, n, "\n%sserial number: ",
2816 prefix );
2817 SAFE_SNPRINTF();
2818
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002819 ret = x509parse_serial_gets( p, n, &entry->serial);
2820 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002821
Paul Bakkerd98030e2009-05-02 15:13:40 +00002822 ret = snprintf( p, n, " revocation date: " \
2823 "%04d-%02d-%02d %02d:%02d:%02d",
2824 entry->revocation_date.year, entry->revocation_date.mon,
2825 entry->revocation_date.day, entry->revocation_date.hour,
2826 entry->revocation_date.min, entry->revocation_date.sec );
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002827 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002828
2829 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002830 }
2831
Paul Bakkerd98030e2009-05-02 15:13:40 +00002832 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2833 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002834
Paul Bakker27d66162010-03-17 06:56:01 +00002835 switch( crl->sig_alg )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002836 {
2837 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2838 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2839 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2840 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2841 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2842 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2843 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2844 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2845 default: ret = snprintf( p, n, "???" ); break;
2846 }
2847 SAFE_SNPRINTF();
2848
Paul Bakker1e27bb22009-07-19 20:25:25 +00002849 ret = snprintf( p, n, "\n" );
2850 SAFE_SNPRINTF();
2851
Paul Bakker23986e52011-04-24 08:57:21 +00002852 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002853}
2854
2855/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00002856 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00002857 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002858int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00002859{
Paul Bakkercce9d772011-11-18 14:26:47 +00002860 int year, mon, day;
2861 int hour, min, sec;
2862
2863#if defined(_WIN32)
2864 SYSTEMTIME st;
2865
2866 GetLocalTime(&st);
2867
2868 year = st.wYear;
2869 mon = st.wMonth;
2870 day = st.wDay;
2871 hour = st.wHour;
2872 min = st.wMinute;
2873 sec = st.wSecond;
2874#else
Paul Bakker5121ce52009-01-03 21:22:43 +00002875 struct tm *lt;
2876 time_t tt;
2877
2878 tt = time( NULL );
2879 lt = localtime( &tt );
2880
Paul Bakkercce9d772011-11-18 14:26:47 +00002881 year = lt->tm_year + 1900;
2882 mon = lt->tm_mon + 1;
2883 day = lt->tm_mday;
2884 hour = lt->tm_hour;
2885 min = lt->tm_min;
2886 sec = lt->tm_sec;
2887#endif
2888
2889 if( year > to->year )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002890 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002891
Paul Bakkercce9d772011-11-18 14:26:47 +00002892 if( year == to->year &&
2893 mon > to->mon )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002894 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002895
Paul Bakkercce9d772011-11-18 14:26:47 +00002896 if( year == to->year &&
2897 mon == to->mon &&
2898 day > to->day )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002899 return( 1 );
2900
Paul Bakkercce9d772011-11-18 14:26:47 +00002901 if( year == to->year &&
2902 mon == to->mon &&
2903 day == to->day &&
2904 hour > to->hour )
Paul Bakkerb6194992011-01-16 21:40:22 +00002905 return( 1 );
2906
Paul Bakkercce9d772011-11-18 14:26:47 +00002907 if( year == to->year &&
2908 mon == to->mon &&
2909 day == to->day &&
2910 hour == to->hour &&
2911 min > to->min )
Paul Bakkerb6194992011-01-16 21:40:22 +00002912 return( 1 );
2913
Paul Bakkercce9d772011-11-18 14:26:47 +00002914 if( year == to->year &&
2915 mon == to->mon &&
2916 day == to->day &&
2917 hour == to->hour &&
2918 min == to->min &&
2919 sec > to->sec )
Paul Bakkerb6194992011-01-16 21:40:22 +00002920 return( 1 );
2921
Paul Bakker40ea7de2009-05-03 10:18:48 +00002922 return( 0 );
2923}
2924
2925/*
2926 * Return 1 if the certificate is revoked, or 0 otherwise.
2927 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002928int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002929{
Paul Bakkerff60ee62010-03-16 21:09:09 +00002930 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00002931
2932 while( cur != NULL && cur->serial.len != 0 )
2933 {
Paul Bakkera056efc2011-01-16 21:38:35 +00002934 if( crt->serial.len == cur->serial.len &&
2935 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002936 {
2937 if( x509parse_time_expired( &cur->revocation_date ) )
2938 return( 1 );
2939 }
2940
2941 cur = cur->next;
2942 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002943
2944 return( 0 );
2945}
2946
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002947/*
2948 * Wrapper for x509 hashes.
2949 *
Paul Bakker0f5f72e2011-01-18 14:58:55 +00002950 * \param out Buffer to receive the hash (Should be at least 64 bytes)
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002951 */
Paul Bakker23986e52011-04-24 08:57:21 +00002952static void x509_hash( const unsigned char *in, size_t len, int alg,
Paul Bakker5121ce52009-01-03 21:22:43 +00002953 unsigned char *out )
2954{
2955 switch( alg )
2956 {
Paul Bakker40e46942009-01-03 21:51:57 +00002957#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002958 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002959#endif
Paul Bakker40e46942009-01-03 21:51:57 +00002960#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002961 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002962#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002963#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002964 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002965#endif
2966#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002967 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002968#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00002969#if defined(POLARSSL_SHA2_C)
2970 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
2971 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
2972#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00002973#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002974 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
2975 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
2976#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002977 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002978 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002979 break;
2980 }
2981}
2982
2983/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00002984 * Check that the given certificate is valid accoring to the CRL.
2985 */
2986static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
2987 x509_crl *crl_list)
2988{
2989 int flags = 0;
2990 int hash_id;
2991 unsigned char hash[64];
2992
2993 /*
2994 * TODO: What happens if no CRL is present?
2995 * Suggestion: Revocation state should be unknown if no CRL is present.
2996 * For backwards compatibility this is not yet implemented.
2997 */
2998
2999 while( ca != NULL && crl_list != NULL && crl_list->version != 0 )
3000 {
3001 if( crl_list->issuer_raw.len != ca->subject_raw.len ||
3002 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
3003 crl_list->issuer_raw.len ) != 0 )
3004 {
3005 crl_list = crl_list->next;
3006 continue;
3007 }
3008
3009 /*
3010 * Check if CRL is correctly signed by the trusted CA
3011 */
3012 hash_id = crl_list->sig_alg;
3013
3014 x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
3015
3016 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, hash_id,
3017 0, hash, crl_list->sig.p ) == 0 )
3018 {
3019 /*
3020 * CRL is not trusted
3021 */
3022 flags |= BADCRL_NOT_TRUSTED;
3023 break;
3024 }
3025
3026 /*
3027 * Check for validity of CRL (Do not drop out)
3028 */
3029 if( x509parse_time_expired( &crl_list->next_update ) )
3030 flags |= BADCRL_EXPIRED;
3031
3032 /*
3033 * Check if certificate is revoked
3034 */
3035 if( x509parse_revoked(crt, crl_list) )
3036 {
3037 flags |= BADCERT_REVOKED;
3038 break;
3039 }
3040
3041 crl_list = crl_list->next;
3042 }
3043 return flags;
3044}
3045
Paul Bakker57b12982012-02-11 17:38:38 +00003046int x509_wildcard_verify( const char *cn, x509_buf *name )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003047{
3048 size_t i;
3049 size_t cn_idx = 0;
3050
Paul Bakker57b12982012-02-11 17:38:38 +00003051 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003052 return( 0 );
3053
3054 for( i = 0; i < strlen( cn ); ++i )
3055 {
3056 if( cn[i] == '.' )
3057 {
3058 cn_idx = i;
3059 break;
3060 }
3061 }
3062
3063 if( cn_idx == 0 )
3064 return( 0 );
3065
Paul Bakker57b12982012-02-11 17:38:38 +00003066 if( memcmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 &&
3067 strlen( cn ) - cn_idx == name->len - 1 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003068 {
3069 return( 1 );
3070 }
3071
3072 return( 0 );
3073}
3074
Paul Bakker76fd75a2011-01-16 21:12:10 +00003075/*
Paul Bakker5121ce52009-01-03 21:22:43 +00003076 * Verify the certificate validity
3077 */
3078int x509parse_verify( x509_cert *crt,
3079 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00003080 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003081 const char *cn, int *flags,
3082 int (*f_vrfy)(void *, x509_cert *, int, int),
3083 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00003084{
Paul Bakker23986e52011-04-24 08:57:21 +00003085 size_t cn_len;
Paul Bakker5121ce52009-01-03 21:22:43 +00003086 int hash_id;
3087 int pathlen;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003088 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00003089 x509_name *name;
Paul Bakker4593aea2009-02-09 22:32:35 +00003090 unsigned char hash[64];
Paul Bakkera8cd2392012-02-11 16:09:32 +00003091 x509_sequence *cur = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003092
Paul Bakker40ea7de2009-05-03 10:18:48 +00003093 *flags = 0;
3094
3095 if( x509parse_time_expired( &crt->valid_to ) )
3096 *flags = BADCERT_EXPIRED;
Paul Bakker5121ce52009-01-03 21:22:43 +00003097
3098 if( cn != NULL )
3099 {
3100 name = &crt->subject;
3101 cn_len = strlen( cn );
3102
Paul Bakker4d2c1242012-05-10 14:12:46 +00003103 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
Paul Bakker5121ce52009-01-03 21:22:43 +00003104 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00003105 cur = &crt->subject_alt_names;
3106
3107 while( cur != NULL )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003108 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00003109 if( memcmp( cn, cur->buf.p, cn_len ) == 0 &&
3110 cur->buf.len == cn_len )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003111 break;
3112
Paul Bakker4d2c1242012-05-10 14:12:46 +00003113 if( memcmp( cur->buf.p, "*.", 2 ) == 0 &&
3114 x509_wildcard_verify( cn, &cur->buf ) )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003115 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003116
Paul Bakker4d2c1242012-05-10 14:12:46 +00003117 cur = cur->next;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003118 }
3119
3120 if( cur == NULL )
3121 *flags |= BADCERT_CN_MISMATCH;
3122 }
Paul Bakker4d2c1242012-05-10 14:12:46 +00003123 else
3124 {
3125 while( name != NULL )
3126 {
3127 if( memcmp( name->oid.p, OID_CN, 3 ) == 0 )
3128 {
3129 if( memcmp( name->val.p, cn, cn_len ) == 0 &&
3130 name->val.len == cn_len )
3131 break;
3132
3133 if( memcmp( name->val.p, "*.", 2 ) == 0 &&
3134 x509_wildcard_verify( cn, &name->val ) )
3135 break;
3136 }
3137
3138 name = name->next;
3139 }
3140
3141 if( name == NULL )
3142 *flags |= BADCERT_CN_MISMATCH;
3143 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003144 }
3145
Paul Bakker5121ce52009-01-03 21:22:43 +00003146 /*
3147 * Iterate upwards in the given cert chain,
3148 * ignoring any upper cert with CA != TRUE.
3149 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003150 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003151
3152 pathlen = 1;
3153
Paul Bakker76fd75a2011-01-16 21:12:10 +00003154 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003155 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003156 if( parent->ca_istrue == 0 ||
3157 crt->issuer_raw.len != parent->subject_raw.len ||
3158 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00003159 crt->issuer_raw.len ) != 0 )
3160 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003161 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003162 continue;
3163 }
3164
Paul Bakker27d66162010-03-17 06:56:01 +00003165 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00003166
3167 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
3168
Paul Bakker76fd75a2011-01-16 21:12:10 +00003169 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, hash_id, 0, hash,
3170 crt->sig.p ) != 0 )
3171 *flags |= BADCERT_NOT_TRUSTED;
3172
3173 /* Check trusted CA's CRL for the given crt */
3174 *flags |= x509parse_verifycrl(crt, parent, ca_crl);
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003175
3176 /* crt is verified to be a child of the parent cur, call verify callback */
Paul Bakker74111d32011-01-15 16:57:55 +00003177 if( NULL != f_vrfy )
3178 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003179 if( f_vrfy( p_vrfy, crt, pathlen - 1, ( *flags == 0 ) ) != 0 )
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003180 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker76fd75a2011-01-16 21:12:10 +00003181 else
3182 *flags = 0;
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003183 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00003184 else if( *flags != 0 )
3185 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00003186
3187 pathlen++;
3188
Paul Bakker76fd75a2011-01-16 21:12:10 +00003189 crt = parent;
3190 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003191 }
3192
3193 /*
Paul Bakker76fd75a2011-01-16 21:12:10 +00003194 * Attempt to validate topmost cert with our CA chain.
Paul Bakker5121ce52009-01-03 21:22:43 +00003195 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003196 *flags |= BADCERT_NOT_TRUSTED;
3197
Paul Bakker7c6d4a42009-03-28 20:35:47 +00003198 while( trust_ca != NULL && trust_ca->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003199 {
3200 if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
3201 memcmp( crt->issuer_raw.p, trust_ca->subject_raw.p,
3202 crt->issuer_raw.len ) != 0 )
3203 {
3204 trust_ca = trust_ca->next;
3205 continue;
3206 }
3207
3208 if( trust_ca->max_pathlen > 0 &&
3209 trust_ca->max_pathlen < pathlen )
3210 break;
3211
Paul Bakker27d66162010-03-17 06:56:01 +00003212 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00003213
3214 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
3215
3216 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
3217 0, hash, crt->sig.p ) == 0 )
3218 {
3219 /*
3220 * cert. is signed by a trusted CA
3221 */
3222 *flags &= ~BADCERT_NOT_TRUSTED;
3223 break;
3224 }
3225
3226 trust_ca = trust_ca->next;
3227 }
3228
Paul Bakker76fd75a2011-01-16 21:12:10 +00003229 /* Check trusted CA's CRL for the given crt */
3230 *flags |= x509parse_verifycrl( crt, trust_ca, ca_crl );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003231
3232 /* Verification succeeded, call callback on top cert */
Paul Bakker74111d32011-01-15 16:57:55 +00003233 if( NULL != f_vrfy )
3234 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003235 if( f_vrfy(p_vrfy, crt, pathlen-1, ( *flags == 0 ) ) != 0 )
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003236 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker76fd75a2011-01-16 21:12:10 +00003237 else
3238 *flags = 0;
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003239 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00003240 else if( *flags != 0 )
3241 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003242
Paul Bakker5121ce52009-01-03 21:22:43 +00003243 return( 0 );
3244}
3245
3246/*
3247 * Unallocate all certificate data
3248 */
3249void x509_free( x509_cert *crt )
3250{
3251 x509_cert *cert_cur = crt;
3252 x509_cert *cert_prv;
3253 x509_name *name_cur;
3254 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00003255 x509_sequence *seq_cur;
3256 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00003257
3258 if( crt == NULL )
3259 return;
3260
3261 do
3262 {
3263 rsa_free( &cert_cur->rsa );
3264
3265 name_cur = cert_cur->issuer.next;
3266 while( name_cur != NULL )
3267 {
3268 name_prv = name_cur;
3269 name_cur = name_cur->next;
3270 memset( name_prv, 0, sizeof( x509_name ) );
3271 free( name_prv );
3272 }
3273
3274 name_cur = cert_cur->subject.next;
3275 while( name_cur != NULL )
3276 {
3277 name_prv = name_cur;
3278 name_cur = name_cur->next;
3279 memset( name_prv, 0, sizeof( x509_name ) );
3280 free( name_prv );
3281 }
3282
Paul Bakker74111d32011-01-15 16:57:55 +00003283 seq_cur = cert_cur->ext_key_usage.next;
3284 while( seq_cur != NULL )
3285 {
3286 seq_prv = seq_cur;
3287 seq_cur = seq_cur->next;
3288 memset( seq_prv, 0, sizeof( x509_sequence ) );
3289 free( seq_prv );
3290 }
3291
Paul Bakker8afa70d2012-02-11 18:42:45 +00003292 seq_cur = cert_cur->subject_alt_names.next;
3293 while( seq_cur != NULL )
3294 {
3295 seq_prv = seq_cur;
3296 seq_cur = seq_cur->next;
3297 memset( seq_prv, 0, sizeof( x509_sequence ) );
3298 free( seq_prv );
3299 }
3300
Paul Bakker5121ce52009-01-03 21:22:43 +00003301 if( cert_cur->raw.p != NULL )
3302 {
3303 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
3304 free( cert_cur->raw.p );
3305 }
3306
3307 cert_cur = cert_cur->next;
3308 }
3309 while( cert_cur != NULL );
3310
3311 cert_cur = crt;
3312 do
3313 {
3314 cert_prv = cert_cur;
3315 cert_cur = cert_cur->next;
3316
3317 memset( cert_prv, 0, sizeof( x509_cert ) );
3318 if( cert_prv != crt )
3319 free( cert_prv );
3320 }
3321 while( cert_cur != NULL );
3322}
3323
Paul Bakkerd98030e2009-05-02 15:13:40 +00003324/*
3325 * Unallocate all CRL data
3326 */
3327void x509_crl_free( x509_crl *crl )
3328{
3329 x509_crl *crl_cur = crl;
3330 x509_crl *crl_prv;
3331 x509_name *name_cur;
3332 x509_name *name_prv;
3333 x509_crl_entry *entry_cur;
3334 x509_crl_entry *entry_prv;
3335
3336 if( crl == NULL )
3337 return;
3338
3339 do
3340 {
3341 name_cur = crl_cur->issuer.next;
3342 while( name_cur != NULL )
3343 {
3344 name_prv = name_cur;
3345 name_cur = name_cur->next;
3346 memset( name_prv, 0, sizeof( x509_name ) );
3347 free( name_prv );
3348 }
3349
3350 entry_cur = crl_cur->entry.next;
3351 while( entry_cur != NULL )
3352 {
3353 entry_prv = entry_cur;
3354 entry_cur = entry_cur->next;
3355 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
3356 free( entry_prv );
3357 }
3358
3359 if( crl_cur->raw.p != NULL )
3360 {
3361 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
3362 free( crl_cur->raw.p );
3363 }
3364
3365 crl_cur = crl_cur->next;
3366 }
3367 while( crl_cur != NULL );
3368
3369 crl_cur = crl;
3370 do
3371 {
3372 crl_prv = crl_cur;
3373 crl_cur = crl_cur->next;
3374
3375 memset( crl_prv, 0, sizeof( x509_crl ) );
3376 if( crl_prv != crl )
3377 free( crl_prv );
3378 }
3379 while( crl_cur != NULL );
3380}
3381
Paul Bakker40e46942009-01-03 21:51:57 +00003382#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00003383
Paul Bakker40e46942009-01-03 21:51:57 +00003384#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00003385
3386/*
3387 * Checkup routine
3388 */
3389int x509_self_test( int verbose )
3390{
Paul Bakker5690efc2011-05-26 13:16:06 +00003391#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00003392 int ret;
3393 int flags;
3394 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00003395 x509_cert cacert;
3396 x509_cert clicert;
3397 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00003398#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003399 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00003400#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003401
3402 if( verbose != 0 )
3403 printf( " X.509 certificate load: " );
3404
3405 memset( &clicert, 0, sizeof( x509_cert ) );
3406
3407 ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003408 strlen( test_cli_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003409 if( ret != 0 )
3410 {
3411 if( verbose != 0 )
3412 printf( "failed\n" );
3413
3414 return( ret );
3415 }
3416
3417 memset( &cacert, 0, sizeof( x509_cert ) );
3418
3419 ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003420 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003421 if( ret != 0 )
3422 {
3423 if( verbose != 0 )
3424 printf( "failed\n" );
3425
3426 return( ret );
3427 }
3428
3429 if( verbose != 0 )
3430 printf( "passed\n X.509 private key load: " );
3431
3432 i = strlen( test_ca_key );
3433 j = strlen( test_ca_pwd );
3434
Paul Bakker66b78b22011-03-25 14:22:50 +00003435 rsa_init( &rsa, RSA_PKCS_V15, 0 );
3436
Paul Bakker5121ce52009-01-03 21:22:43 +00003437 if( ( ret = x509parse_key( &rsa,
3438 (unsigned char *) test_ca_key, i,
3439 (unsigned char *) test_ca_pwd, j ) ) != 0 )
3440 {
3441 if( verbose != 0 )
3442 printf( "failed\n" );
3443
3444 return( ret );
3445 }
3446
3447 if( verbose != 0 )
3448 printf( "passed\n X.509 signature verify: ");
3449
Paul Bakker23986e52011-04-24 08:57:21 +00003450 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003451 if( ret != 0 )
3452 {
Paul Bakker23986e52011-04-24 08:57:21 +00003453 printf("%02x", flags);
Paul Bakker5121ce52009-01-03 21:22:43 +00003454 if( verbose != 0 )
3455 printf( "failed\n" );
3456
3457 return( ret );
3458 }
3459
Paul Bakker5690efc2011-05-26 13:16:06 +00003460#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003461 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003462 printf( "passed\n X.509 DHM parameter load: " );
3463
3464 i = strlen( test_dhm_params );
3465 j = strlen( test_ca_pwd );
3466
3467 if( ( ret = x509parse_dhm( &dhm, (unsigned char *) test_dhm_params, i ) ) != 0 )
3468 {
3469 if( verbose != 0 )
3470 printf( "failed\n" );
3471
3472 return( ret );
3473 }
3474
3475 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003476 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00003477#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003478
3479 x509_free( &cacert );
3480 x509_free( &clicert );
3481 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00003482#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003483 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00003484#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003485
3486 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003487#else
3488 ((void) verbose);
3489 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3490#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003491}
3492
3493#endif
3494
3495#endif