blob: f1e98b31ef4dfbe3ac66db3073019383f3cf72a6 [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>
63#endif
64
Paul Bakker5121ce52009-01-03 21:22:43 +000065/*
Paul Bakker5121ce52009-01-03 21:22:43 +000066 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
67 */
68static int x509_get_version( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +000069 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +000070 int *ver )
71{
Paul Bakker23986e52011-04-24 08:57:21 +000072 int ret;
73 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +000074
75 if( ( ret = asn1_get_tag( p, end, &len,
76 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
77 {
Paul Bakker40e46942009-01-03 21:51:57 +000078 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +000079 {
80 *ver = 0;
81 return( 0 );
82 }
Paul Bakker5121ce52009-01-03 21:22:43 +000083
84 return( ret );
85 }
86
87 end = *p + len;
88
89 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +000090 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +000091
92 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +000093 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION +
Paul Bakker40e46942009-01-03 21:51:57 +000094 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +000095
96 return( 0 );
97}
98
99/*
Paul Bakkerfae618f2011-10-12 11:53:52 +0000100 * Version ::= INTEGER { v1(0), v2(1) }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000101 */
102static int x509_crl_get_version( unsigned char **p,
103 const unsigned char *end,
104 int *ver )
105{
106 int ret;
107
108 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
109 {
110 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker2a1c5f52011-10-19 14:15:17 +0000111 {
112 *ver = 0;
113 return( 0 );
114 }
Paul Bakker3329d1f2011-10-12 09:55:01 +0000115
116 return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
117 }
118
119 return( 0 );
120}
121
122/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000123 * CertificateSerialNumber ::= INTEGER
124 */
125static int x509_get_serial( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000126 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000127 x509_buf *serial )
128{
129 int ret;
130
131 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000132 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000133 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000134
135 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
136 **p != ASN1_INTEGER )
Paul Bakker9d781402011-05-09 16:17:09 +0000137 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
Paul Bakker40e46942009-01-03 21:51:57 +0000138 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000139
140 serial->tag = *(*p)++;
141
142 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000143 return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000144
145 serial->p = *p;
146 *p += serial->len;
147
148 return( 0 );
149}
150
151/*
152 * AlgorithmIdentifier ::= SEQUENCE {
153 * algorithm OBJECT IDENTIFIER,
154 * parameters ANY DEFINED BY algorithm OPTIONAL }
155 */
156static int x509_get_alg( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000157 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000158 x509_buf *alg )
159{
Paul Bakker23986e52011-04-24 08:57:21 +0000160 int ret;
161 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000162
163 if( ( ret = asn1_get_tag( p, end, &len,
164 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000165 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000166
167 end = *p + len;
168 alg->tag = **p;
169
170 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000171 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000172
173 alg->p = *p;
174 *p += alg->len;
175
176 if( *p == end )
177 return( 0 );
178
179 /*
180 * assume the algorithm parameters must be NULL
181 */
182 if( ( ret = asn1_get_tag( p, end, &len, ASN1_NULL ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000183 return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000184
185 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000186 return( POLARSSL_ERR_X509_CERT_INVALID_ALG +
Paul Bakker40e46942009-01-03 21:51:57 +0000187 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000188
189 return( 0 );
190}
191
192/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000193 * AttributeTypeAndValue ::= SEQUENCE {
194 * type AttributeType,
195 * value AttributeValue }
196 *
197 * AttributeType ::= OBJECT IDENTIFIER
198 *
199 * AttributeValue ::= ANY DEFINED BY AttributeType
200 */
Paul Bakker400ff6f2011-02-20 10:40:16 +0000201static int x509_get_attr_type_value( unsigned char **p,
202 const unsigned char *end,
203 x509_name *cur )
Paul Bakker5121ce52009-01-03 21:22:43 +0000204{
Paul Bakker23986e52011-04-24 08:57:21 +0000205 int ret;
206 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000207 x509_buf *oid;
208 x509_buf *val;
209
210 if( ( ret = asn1_get_tag( p, end, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000211 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000212 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000213
Paul Bakker5121ce52009-01-03 21:22:43 +0000214 oid = &cur->oid;
215 oid->tag = **p;
216
217 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000218 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000219
220 oid->p = *p;
221 *p += oid->len;
222
223 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000224 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000225 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000226
227 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
228 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
229 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
Paul Bakker9d781402011-05-09 16:17:09 +0000230 return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
Paul Bakker40e46942009-01-03 21:51:57 +0000231 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000232
233 val = &cur->val;
234 val->tag = *(*p)++;
235
236 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000237 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000238
239 val->p = *p;
240 *p += val->len;
241
242 cur->next = NULL;
243
Paul Bakker400ff6f2011-02-20 10:40:16 +0000244 return( 0 );
245}
246
247/*
248 * RelativeDistinguishedName ::=
249 * SET OF AttributeTypeAndValue
250 *
251 * AttributeTypeAndValue ::= SEQUENCE {
252 * type AttributeType,
253 * value AttributeValue }
254 *
255 * AttributeType ::= OBJECT IDENTIFIER
256 *
257 * AttributeValue ::= ANY DEFINED BY AttributeType
258 */
259static int x509_get_name( unsigned char **p,
260 const unsigned char *end,
261 x509_name *cur )
262{
Paul Bakker23986e52011-04-24 08:57:21 +0000263 int ret;
264 size_t len;
Paul Bakker400ff6f2011-02-20 10:40:16 +0000265 const unsigned char *end2;
266 x509_name *use;
267
268 if( ( ret = asn1_get_tag( p, end, &len,
269 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000270 return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000271
272 end2 = end;
273 end = *p + len;
274 use = cur;
275
276 do
277 {
278 if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
279 return( ret );
280
281 if( *p != end )
282 {
283 use->next = (x509_name *) malloc(
284 sizeof( x509_name ) );
285
286 if( use->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000287 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker400ff6f2011-02-20 10:40:16 +0000288
289 memset( use->next, 0, sizeof( x509_name ) );
290
291 use = use->next;
292 }
293 }
294 while( *p != end );
Paul Bakker5121ce52009-01-03 21:22:43 +0000295
296 /*
297 * recurse until end of SEQUENCE is reached
298 */
299 if( *p == end2 )
300 return( 0 );
301
302 cur->next = (x509_name *) malloc(
303 sizeof( x509_name ) );
304
305 if( cur->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000306 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000307
Paul Bakker430ffbe2012-05-01 08:14:20 +0000308 memset( cur->next, 0, sizeof( x509_name ) );
309
Paul Bakker5121ce52009-01-03 21:22:43 +0000310 return( x509_get_name( p, end2, cur->next ) );
311}
312
313/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000314 * Time ::= CHOICE {
315 * utcTime UTCTime,
316 * generalTime GeneralizedTime }
317 */
Paul Bakker91200182010-02-18 21:26:15 +0000318static int x509_get_time( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000319 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000320 x509_time *time )
321{
Paul Bakker23986e52011-04-24 08:57:21 +0000322 int ret;
323 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000324 char date[64];
Paul Bakker91200182010-02-18 21:26:15 +0000325 unsigned char tag;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000326
Paul Bakker91200182010-02-18 21:26:15 +0000327 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000328 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
329 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000330
Paul Bakker91200182010-02-18 21:26:15 +0000331 tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000332
Paul Bakker91200182010-02-18 21:26:15 +0000333 if ( tag == ASN1_UTC_TIME )
334 {
335 (*p)++;
336 ret = asn1_get_len( p, end, &len );
337
338 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000339 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000340
Paul Bakker91200182010-02-18 21:26:15 +0000341 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000342 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
343 len : sizeof( date ) - 1 );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000344
Paul Bakker91200182010-02-18 21:26:15 +0000345 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
346 &time->year, &time->mon, &time->day,
347 &time->hour, &time->min, &time->sec ) < 5 )
348 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000349
Paul Bakker400ff6f2011-02-20 10:40:16 +0000350 time->year += 100 * ( time->year < 50 );
Paul Bakker91200182010-02-18 21:26:15 +0000351 time->year += 1900;
352
353 *p += len;
354
355 return( 0 );
356 }
357 else if ( tag == ASN1_GENERALIZED_TIME )
358 {
359 (*p)++;
360 ret = asn1_get_len( p, end, &len );
361
362 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000363 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker91200182010-02-18 21:26:15 +0000364
365 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000366 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
367 len : sizeof( date ) - 1 );
Paul Bakker91200182010-02-18 21:26:15 +0000368
369 if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
370 &time->year, &time->mon, &time->day,
371 &time->hour, &time->min, &time->sec ) < 5 )
372 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
373
374 *p += len;
375
376 return( 0 );
377 }
378 else
Paul Bakker9d781402011-05-09 16:17:09 +0000379 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000380}
381
382
383/*
384 * Validity ::= SEQUENCE {
385 * notBefore Time,
386 * notAfter Time }
387 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000388static int x509_get_dates( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000389 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000390 x509_time *from,
391 x509_time *to )
392{
Paul Bakker23986e52011-04-24 08:57:21 +0000393 int ret;
394 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000395
396 if( ( ret = asn1_get_tag( p, end, &len,
397 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000398 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000399
400 end = *p + len;
401
Paul Bakker91200182010-02-18 21:26:15 +0000402 if( ( ret = x509_get_time( p, end, from ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000403 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000404
Paul Bakker91200182010-02-18 21:26:15 +0000405 if( ( ret = x509_get_time( p, end, to ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000406 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000407
408 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000409 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker40e46942009-01-03 21:51:57 +0000410 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000411
412 return( 0 );
413}
414
415/*
416 * SubjectPublicKeyInfo ::= SEQUENCE {
417 * algorithm AlgorithmIdentifier,
418 * subjectPublicKey BIT STRING }
419 */
420static int x509_get_pubkey( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000421 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000422 x509_buf *pk_alg_oid,
423 mpi *N, mpi *E )
424{
Paul Bakker23986e52011-04-24 08:57:21 +0000425 int ret, can_handle;
426 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000427 unsigned char *end2;
428
429 if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 )
430 return( ret );
431
432 /*
433 * only RSA public keys handled at this time
434 */
Paul Bakker400ff6f2011-02-20 10:40:16 +0000435 can_handle = 0;
436
437 if( pk_alg_oid->len == 9 &&
438 memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) == 0 )
439 can_handle = 1;
440
441 if( pk_alg_oid->len == 9 &&
442 memcmp( pk_alg_oid->p, OID_PKCS1, 8 ) == 0 )
443 {
444 if( pk_alg_oid->p[8] >= 2 && pk_alg_oid->p[8] <= 5 )
445 can_handle = 1;
446
447 if ( pk_alg_oid->p[8] >= 11 && pk_alg_oid->p[8] <= 14 )
448 can_handle = 1;
449 }
450
451 if( pk_alg_oid->len == 5 &&
452 memcmp( pk_alg_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
453 can_handle = 1;
454
455 if( can_handle == 0 )
Paul Bakkered56b222011-07-13 11:26:43 +0000456 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000457
458 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000459 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000460
461 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000462 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000463 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000464
465 end2 = *p + len;
466
467 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000468 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000469
470 /*
471 * RSAPublicKey ::= SEQUENCE {
472 * modulus INTEGER, -- n
473 * publicExponent INTEGER -- e
474 * }
475 */
476 if( ( ret = asn1_get_tag( p, end2, &len,
477 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000478 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000479
480 if( *p + len != end2 )
Paul Bakker9d781402011-05-09 16:17:09 +0000481 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000482 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000483
484 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
485 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000486 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000487
488 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000489 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000490 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000491
492 return( 0 );
493}
494
495static int x509_get_sig( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000496 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000497 x509_buf *sig )
498{
Paul Bakker23986e52011-04-24 08:57:21 +0000499 int ret;
500 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000501
Paul Bakker8afa70d2012-02-11 18:42:45 +0000502 if( ( end - *p ) < 1 )
503 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE +
504 POLARSSL_ERR_ASN1_OUT_OF_DATA );
505
Paul Bakker5121ce52009-01-03 21:22:43 +0000506 sig->tag = **p;
507
508 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000509 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000510
Paul Bakker74111d32011-01-15 16:57:55 +0000511
Paul Bakker5121ce52009-01-03 21:22:43 +0000512 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000513 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000514
515 sig->len = len;
516 sig->p = *p;
517
518 *p += len;
519
520 return( 0 );
521}
522
523/*
524 * X.509 v2/v3 unique identifier (not parsed)
525 */
526static int x509_get_uid( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000527 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000528 x509_buf *uid, int n )
529{
530 int ret;
531
532 if( *p == end )
533 return( 0 );
534
535 uid->tag = **p;
536
537 if( ( ret = asn1_get_tag( p, end, &uid->len,
538 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
539 {
Paul Bakker40e46942009-01-03 21:51:57 +0000540 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000541 return( 0 );
542
543 return( ret );
544 }
545
546 uid->p = *p;
547 *p += uid->len;
548
549 return( 0 );
550}
551
552/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000553 * X.509 Extensions (No parsing of extensions, pointer should
554 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000555 */
556static int x509_get_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000557 const unsigned char *end,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000558 x509_buf *ext, int tag )
Paul Bakker5121ce52009-01-03 21:22:43 +0000559{
Paul Bakker23986e52011-04-24 08:57:21 +0000560 int ret;
561 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000562
563 if( *p == end )
564 return( 0 );
565
566 ext->tag = **p;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000567
Paul Bakker5121ce52009-01-03 21:22:43 +0000568 if( ( ret = asn1_get_tag( p, end, &ext->len,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000569 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000570 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000571
572 ext->p = *p;
573 end = *p + ext->len;
574
575 /*
576 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
577 *
578 * Extension ::= SEQUENCE {
579 * extnID OBJECT IDENTIFIER,
580 * critical BOOLEAN DEFAULT FALSE,
581 * extnValue OCTET STRING }
582 */
583 if( ( ret = asn1_get_tag( p, end, &len,
584 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000585 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000586
587 if( end != *p + len )
Paul Bakker9d781402011-05-09 16:17:09 +0000588 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +0000589 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000590
Paul Bakkerd98030e2009-05-02 15:13:40 +0000591 return( 0 );
592}
593
594/*
595 * X.509 CRL v2 extensions (no extensions parsed yet.)
596 */
597static int x509_get_crl_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000598 const unsigned char *end,
599 x509_buf *ext )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000600{
Paul Bakker23986e52011-04-24 08:57:21 +0000601 int ret;
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000602 size_t len = 0;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000603
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000604 /* Get explicit tag */
605 if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000606 {
607 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
608 return( 0 );
609
610 return( ret );
611 }
612
613 while( *p < end )
614 {
615 if( ( ret = asn1_get_tag( p, end, &len,
616 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000617 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000618
619 *p += len;
620 }
621
622 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000623 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerd98030e2009-05-02 15:13:40 +0000624 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
625
626 return( 0 );
627}
628
Paul Bakkerb5a11ab2011-10-12 09:58:41 +0000629/*
630 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
631 */
632static int x509_get_crl_entry_ext( unsigned char **p,
633 const unsigned char *end,
634 x509_buf *ext )
635{
636 int ret;
637 size_t len = 0;
638
639 /* OPTIONAL */
640 if (end <= *p)
641 return( 0 );
642
643 ext->tag = **p;
644 ext->p = *p;
645
646 /*
647 * Get CRL-entry extension sequence header
648 * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
649 */
650 if( ( ret = asn1_get_tag( p, end, &ext->len,
651 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
652 {
653 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
654 {
655 ext->p = NULL;
656 return( 0 );
657 }
658 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
659 }
660
661 end = *p + ext->len;
662
663 if( end != *p + ext->len )
664 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
665 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
666
667 while( *p < end )
668 {
669 if( ( ret = asn1_get_tag( p, end, &len,
670 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
671 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
672
673 *p += len;
674 }
675
676 if( *p != end )
677 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
678 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
679
680 return( 0 );
681}
682
Paul Bakker74111d32011-01-15 16:57:55 +0000683static int x509_get_basic_constraints( unsigned char **p,
684 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000685 int *ca_istrue,
686 int *max_pathlen )
687{
Paul Bakker23986e52011-04-24 08:57:21 +0000688 int ret;
689 size_t len;
Paul Bakker74111d32011-01-15 16:57:55 +0000690
691 /*
692 * BasicConstraints ::= SEQUENCE {
693 * cA BOOLEAN DEFAULT FALSE,
694 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
695 */
Paul Bakker3cccddb2011-01-16 21:46:31 +0000696 *ca_istrue = 0; /* DEFAULT FALSE */
Paul Bakker74111d32011-01-15 16:57:55 +0000697 *max_pathlen = 0; /* endless */
698
699 if( ( ret = asn1_get_tag( p, end, &len,
700 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000701 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000702
703 if( *p == end )
704 return 0;
705
Paul Bakker3cccddb2011-01-16 21:46:31 +0000706 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000707 {
708 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker3cccddb2011-01-16 21:46:31 +0000709 ret = asn1_get_int( p, end, ca_istrue );
Paul Bakker74111d32011-01-15 16:57:55 +0000710
711 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000712 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000713
Paul Bakker3cccddb2011-01-16 21:46:31 +0000714 if( *ca_istrue != 0 )
715 *ca_istrue = 1;
Paul Bakker74111d32011-01-15 16:57:55 +0000716 }
717
718 if( *p == end )
719 return 0;
720
721 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000722 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000723
724 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000725 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000726 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
727
728 (*max_pathlen)++;
729
Paul Bakker74111d32011-01-15 16:57:55 +0000730 return 0;
731}
732
733static int x509_get_ns_cert_type( unsigned char **p,
734 const unsigned char *end,
735 unsigned char *ns_cert_type)
736{
737 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000738 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000739
740 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000741 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000742
743 if( bs.len != 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000744 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000745 POLARSSL_ERR_ASN1_INVALID_LENGTH );
746
747 /* Get actual bitstring */
748 *ns_cert_type = *bs.p;
749 return 0;
750}
751
752static int x509_get_key_usage( unsigned char **p,
753 const unsigned char *end,
754 unsigned char *key_usage)
755{
756 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000757 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000758
759 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000760 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000761
Paul Bakkercebdf172011-11-11 15:01:31 +0000762 if( bs.len > 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000763 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000764 POLARSSL_ERR_ASN1_INVALID_LENGTH );
765
766 /* Get actual bitstring */
767 *key_usage = *bs.p;
768 return 0;
769}
770
Paul Bakkerd98030e2009-05-02 15:13:40 +0000771/*
Paul Bakker74111d32011-01-15 16:57:55 +0000772 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
773 *
774 * KeyPurposeId ::= OBJECT IDENTIFIER
775 */
776static int x509_get_ext_key_usage( unsigned char **p,
777 const unsigned char *end,
778 x509_sequence *ext_key_usage)
779{
780 int ret;
781
782 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000783 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000784
785 /* Sequence length must be >= 1 */
786 if( ext_key_usage->buf.p == NULL )
Paul Bakker9d781402011-05-09 16:17:09 +0000787 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000788 POLARSSL_ERR_ASN1_INVALID_LENGTH );
789
790 return 0;
791}
792
793/*
Paul Bakkera8cd2392012-02-11 16:09:32 +0000794 * SubjectAltName ::= GeneralNames
795 *
796 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
797 *
798 * GeneralName ::= CHOICE {
799 * otherName [0] OtherName,
800 * rfc822Name [1] IA5String,
801 * dNSName [2] IA5String,
802 * x400Address [3] ORAddress,
803 * directoryName [4] Name,
804 * ediPartyName [5] EDIPartyName,
805 * uniformResourceIdentifier [6] IA5String,
806 * iPAddress [7] OCTET STRING,
807 * registeredID [8] OBJECT IDENTIFIER }
808 *
809 * OtherName ::= SEQUENCE {
810 * type-id OBJECT IDENTIFIER,
811 * value [0] EXPLICIT ANY DEFINED BY type-id }
812 *
813 * EDIPartyName ::= SEQUENCE {
814 * nameAssigner [0] DirectoryString OPTIONAL,
815 * partyName [1] DirectoryString }
816 *
817 * NOTE: PolarSSL only parses and uses dNSName at this point.
818 */
819static int x509_get_subject_alt_name( unsigned char **p,
820 const unsigned char *end,
821 x509_sequence *subject_alt_name )
822{
823 int ret;
824 size_t len, tag_len;
825 asn1_buf *buf;
826 unsigned char tag;
827 asn1_sequence *cur = subject_alt_name;
828
829 /* Get main sequence tag */
830 if( ( ret = asn1_get_tag( p, end, &len,
831 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
832 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
833
834 if( *p + len != end )
835 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
836 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
837
838 while( *p < end )
839 {
840 if( ( end - *p ) < 1 )
841 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
842 POLARSSL_ERR_ASN1_OUT_OF_DATA );
843
844 tag = **p;
845 (*p)++;
846 if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 )
847 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
848
849 if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC )
850 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
851 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
852
853 if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) )
854 {
855 *p += tag_len;
856 continue;
857 }
858
859 buf = &(cur->buf);
860 buf->tag = tag;
861 buf->p = *p;
862 buf->len = tag_len;
863 *p += buf->len;
864
865 /* Allocate and assign next pointer */
866 if (*p < end)
867 {
868 cur->next = (asn1_sequence *) malloc(
869 sizeof( asn1_sequence ) );
870
871 if( cur->next == NULL )
872 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
873 POLARSSL_ERR_ASN1_MALLOC_FAILED );
874
875 cur = cur->next;
876 }
877 }
878
879 /* Set final sequence entry's next pointer to NULL */
880 cur->next = NULL;
881
882 if( *p != end )
883 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
884 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
885
886 return( 0 );
887}
888
889/*
Paul Bakker74111d32011-01-15 16:57:55 +0000890 * X.509 v3 extensions
891 *
892 * TODO: Perform all of the basic constraints tests required by the RFC
893 * TODO: Set values for undetected extensions to a sane default?
894 *
Paul Bakkerd98030e2009-05-02 15:13:40 +0000895 */
896static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000897 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000898 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000899{
Paul Bakker23986e52011-04-24 08:57:21 +0000900 int ret;
901 size_t len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000902 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000903
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000904 if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000905 {
906 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
907 return( 0 );
908
909 return( ret );
910 }
911
Paul Bakker5121ce52009-01-03 21:22:43 +0000912 while( *p < end )
913 {
Paul Bakker74111d32011-01-15 16:57:55 +0000914 /*
915 * Extension ::= SEQUENCE {
916 * extnID OBJECT IDENTIFIER,
917 * critical BOOLEAN DEFAULT FALSE,
918 * extnValue OCTET STRING }
919 */
920 x509_buf extn_oid = {0, 0, NULL};
921 int is_critical = 0; /* DEFAULT FALSE */
922
Paul Bakker5121ce52009-01-03 21:22:43 +0000923 if( ( ret = asn1_get_tag( p, end, &len,
924 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000925 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000926
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000927 end_ext_data = *p + len;
928
Paul Bakker74111d32011-01-15 16:57:55 +0000929 /* Get extension ID */
930 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000931
Paul Bakker74111d32011-01-15 16:57:55 +0000932 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000933 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000934
Paul Bakker74111d32011-01-15 16:57:55 +0000935 extn_oid.p = *p;
936 *p += extn_oid.len;
937
938 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000939 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000940 POLARSSL_ERR_ASN1_OUT_OF_DATA );
941
942 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000943 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000944 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
Paul Bakker9d781402011-05-09 16:17:09 +0000945 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000946
Paul Bakker74111d32011-01-15 16:57:55 +0000947 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000948 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000949 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000950 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000951
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000952 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000953
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000954 if( end_ext_octet != end_ext_data )
Paul Bakker9d781402011-05-09 16:17:09 +0000955 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000956 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000957
Paul Bakker74111d32011-01-15 16:57:55 +0000958 /*
959 * Detect supported extensions
960 */
961 if( ( OID_SIZE( OID_BASIC_CONSTRAINTS ) == extn_oid.len ) &&
962 memcmp( extn_oid.p, OID_BASIC_CONSTRAINTS, extn_oid.len ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000963 {
Paul Bakker74111d32011-01-15 16:57:55 +0000964 /* Parse basic constraints */
965 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
Paul Bakker3cccddb2011-01-16 21:46:31 +0000966 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000967 return ( ret );
968 crt->ext_types |= EXT_BASIC_CONSTRAINTS;
Paul Bakker5121ce52009-01-03 21:22:43 +0000969 }
Paul Bakker74111d32011-01-15 16:57:55 +0000970 else if( ( OID_SIZE( OID_NS_CERT_TYPE ) == extn_oid.len ) &&
971 memcmp( extn_oid.p, OID_NS_CERT_TYPE, extn_oid.len ) == 0 )
972 {
973 /* Parse netscape certificate type */
974 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
975 &crt->ns_cert_type ) ) != 0 )
976 return ( ret );
977 crt->ext_types |= EXT_NS_CERT_TYPE;
978 }
979 else if( ( OID_SIZE( OID_KEY_USAGE ) == extn_oid.len ) &&
980 memcmp( extn_oid.p, OID_KEY_USAGE, extn_oid.len ) == 0 )
981 {
982 /* Parse key usage */
983 if( ( ret = x509_get_key_usage( p, end_ext_octet,
984 &crt->key_usage ) ) != 0 )
985 return ( ret );
986 crt->ext_types |= EXT_KEY_USAGE;
987 }
988 else if( ( OID_SIZE( OID_EXTENDED_KEY_USAGE ) == extn_oid.len ) &&
989 memcmp( extn_oid.p, OID_EXTENDED_KEY_USAGE, extn_oid.len ) == 0 )
990 {
991 /* Parse extended key usage */
992 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
993 &crt->ext_key_usage ) ) != 0 )
994 return ( ret );
995 crt->ext_types |= EXT_EXTENDED_KEY_USAGE;
996 }
Paul Bakkera8cd2392012-02-11 16:09:32 +0000997 else if( ( OID_SIZE( OID_SUBJECT_ALT_NAME ) == extn_oid.len ) &&
998 memcmp( extn_oid.p, OID_SUBJECT_ALT_NAME, extn_oid.len ) == 0 )
999 {
1000 /* Parse extended key usage */
1001 if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
1002 &crt->subject_alt_names ) ) != 0 )
1003 return ( ret );
1004 crt->ext_types |= EXT_SUBJECT_ALT_NAME;
1005 }
Paul Bakker74111d32011-01-15 16:57:55 +00001006 else
1007 {
1008 /* No parser found, skip extension */
1009 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +00001010
Paul Bakker5c721f92011-07-27 16:51:09 +00001011#if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
Paul Bakker74111d32011-01-15 16:57:55 +00001012 if( is_critical )
1013 {
1014 /* Data is marked as critical: fail */
Paul Bakker9d781402011-05-09 16:17:09 +00001015 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +00001016 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
1017 }
Paul Bakker5c721f92011-07-27 16:51:09 +00001018#endif
Paul Bakker74111d32011-01-15 16:57:55 +00001019 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001020 }
1021
1022 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +00001023 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +00001024 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001025
Paul Bakker5121ce52009-01-03 21:22:43 +00001026 return( 0 );
1027}
1028
1029/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001030 * X.509 CRL Entries
1031 */
1032static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001033 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001034 x509_crl_entry *entry )
1035{
Paul Bakker23986e52011-04-24 08:57:21 +00001036 int ret;
1037 size_t entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001038 x509_crl_entry *cur_entry = entry;
1039
1040 if( *p == end )
1041 return( 0 );
1042
Paul Bakker9be19372009-07-27 20:21:53 +00001043 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001044 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1045 {
1046 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
1047 return( 0 );
1048
1049 return( ret );
1050 }
1051
Paul Bakker9be19372009-07-27 20:21:53 +00001052 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001053
1054 while( *p < end )
1055 {
Paul Bakker23986e52011-04-24 08:57:21 +00001056 size_t len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001057 const unsigned char *end2;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001058
1059 if( ( ret = asn1_get_tag( p, end, &len2,
1060 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1061 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001062 return( ret );
1063 }
1064
Paul Bakker9be19372009-07-27 20:21:53 +00001065 cur_entry->raw.tag = **p;
1066 cur_entry->raw.p = *p;
1067 cur_entry->raw.len = len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001068 end2 = *p + len2;
Paul Bakker9be19372009-07-27 20:21:53 +00001069
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001070 if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001071 return( ret );
1072
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001073 if( ( ret = x509_get_time( p, end2, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001074 return( ret );
1075
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001076 if( ( ret = x509_get_crl_entry_ext( p, end2, &cur_entry->entry_ext ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001077 return( ret );
1078
Paul Bakker74111d32011-01-15 16:57:55 +00001079 if ( *p < end )
1080 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001081 cur_entry->next = malloc( sizeof( x509_crl_entry ) );
Paul Bakkerb15b8512012-01-13 13:44:06 +00001082
1083 if( cur_entry->next == NULL )
1084 return( POLARSSL_ERR_X509_MALLOC_FAILED );
1085
Paul Bakkerd98030e2009-05-02 15:13:40 +00001086 cur_entry = cur_entry->next;
1087 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
1088 }
1089 }
1090
1091 return( 0 );
1092}
1093
Paul Bakker27d66162010-03-17 06:56:01 +00001094static int x509_get_sig_alg( const x509_buf *sig_oid, int *sig_alg )
1095{
1096 if( sig_oid->len == 9 &&
1097 memcmp( sig_oid->p, OID_PKCS1, 8 ) == 0 )
1098 {
1099 if( sig_oid->p[8] >= 2 && sig_oid->p[8] <= 5 )
1100 {
1101 *sig_alg = sig_oid->p[8];
1102 return( 0 );
1103 }
1104
1105 if ( sig_oid->p[8] >= 11 && sig_oid->p[8] <= 14 )
1106 {
1107 *sig_alg = sig_oid->p[8];
1108 return( 0 );
1109 }
1110
1111 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1112 }
Paul Bakker400ff6f2011-02-20 10:40:16 +00001113 if( sig_oid->len == 5 &&
1114 memcmp( sig_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
1115 {
1116 *sig_alg = SIG_RSA_SHA1;
1117 return( 0 );
1118 }
Paul Bakker27d66162010-03-17 06:56:01 +00001119
1120 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1121}
1122
Paul Bakkerd98030e2009-05-02 15:13:40 +00001123/*
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001124 * Parse and fill a single X.509 certificate in DER format
Paul Bakker5121ce52009-01-03 21:22:43 +00001125 */
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001126int x509parse_crt_der( x509_cert *crt, const unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001127{
Paul Bakker23986e52011-04-24 08:57:21 +00001128 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001129 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00001130 unsigned char *p, *end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001131
Paul Bakker320a4b52009-03-28 18:52:39 +00001132 /*
1133 * Check for valid input
1134 */
1135 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001136 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker320a4b52009-03-28 18:52:39 +00001137
Paul Bakker96743fc2011-02-12 14:30:57 +00001138 p = (unsigned char *) malloc( len = buflen );
1139
1140 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001141 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001142
1143 memcpy( p, buf, buflen );
1144
1145 buflen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001146
1147 crt->raw.p = p;
1148 crt->raw.len = len;
1149 end = p + len;
1150
1151 /*
1152 * Certificate ::= SEQUENCE {
1153 * tbsCertificate TBSCertificate,
1154 * signatureAlgorithm AlgorithmIdentifier,
1155 * signatureValue BIT STRING }
1156 */
1157 if( ( ret = asn1_get_tag( &p, end, &len,
1158 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1159 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001160 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001161 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001162 }
1163
Paul Bakker23986e52011-04-24 08:57:21 +00001164 if( len != (size_t) ( end - p ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001165 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001166 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001167 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001168 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001169 }
1170
1171 /*
1172 * TBSCertificate ::= SEQUENCE {
1173 */
1174 crt->tbs.p = p;
1175
1176 if( ( ret = asn1_get_tag( &p, end, &len,
1177 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1178 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001179 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001180 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001181 }
1182
1183 end = p + len;
1184 crt->tbs.len = end - crt->tbs.p;
1185
1186 /*
1187 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1188 *
1189 * CertificateSerialNumber ::= INTEGER
1190 *
1191 * signature AlgorithmIdentifier
1192 */
1193 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1194 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1195 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
1196 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001197 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001198 return( ret );
1199 }
1200
1201 crt->version++;
1202
1203 if( crt->version > 3 )
1204 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001205 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001206 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001207 }
1208
Paul Bakker27d66162010-03-17 06:56:01 +00001209 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_alg ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001210 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001211 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001212 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001213 }
1214
1215 /*
1216 * issuer Name
1217 */
1218 crt->issuer_raw.p = p;
1219
1220 if( ( ret = asn1_get_tag( &p, end, &len,
1221 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1222 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001223 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001224 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001225 }
1226
1227 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1228 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001229 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001230 return( ret );
1231 }
1232
1233 crt->issuer_raw.len = p - crt->issuer_raw.p;
1234
1235 /*
1236 * Validity ::= SEQUENCE {
1237 * notBefore Time,
1238 * notAfter Time }
1239 *
1240 */
1241 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1242 &crt->valid_to ) ) != 0 )
1243 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001244 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001245 return( ret );
1246 }
1247
1248 /*
1249 * subject Name
1250 */
1251 crt->subject_raw.p = p;
1252
1253 if( ( ret = asn1_get_tag( &p, end, &len,
1254 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1255 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001256 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001257 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001258 }
1259
1260 if( ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
1261 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001262 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001263 return( ret );
1264 }
1265
1266 crt->subject_raw.len = p - crt->subject_raw.p;
1267
1268 /*
1269 * SubjectPublicKeyInfo ::= SEQUENCE
1270 * algorithm AlgorithmIdentifier,
1271 * subjectPublicKey BIT STRING }
1272 */
1273 if( ( ret = asn1_get_tag( &p, end, &len,
1274 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1275 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001276 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001277 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001278 }
1279
1280 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1281 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1282 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001283 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001284 return( ret );
1285 }
1286
1287 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1288 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001289 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001290 return( ret );
1291 }
1292
1293 crt->rsa.len = mpi_size( &crt->rsa.N );
1294
1295 /*
1296 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1297 * -- If present, version shall be v2 or v3
1298 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1299 * -- If present, version shall be v2 or v3
1300 * extensions [3] EXPLICIT Extensions OPTIONAL
1301 * -- If present, version shall be v3
1302 */
1303 if( crt->version == 2 || crt->version == 3 )
1304 {
1305 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1306 if( ret != 0 )
1307 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001308 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001309 return( ret );
1310 }
1311 }
1312
1313 if( crt->version == 2 || crt->version == 3 )
1314 {
1315 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1316 if( ret != 0 )
1317 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001318 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001319 return( ret );
1320 }
1321 }
1322
1323 if( crt->version == 3 )
1324 {
Paul Bakker74111d32011-01-15 16:57:55 +00001325 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001326 if( ret != 0 )
1327 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001328 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001329 return( ret );
1330 }
1331 }
1332
1333 if( p != end )
1334 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001335 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001336 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001337 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001338 }
1339
1340 end = crt->raw.p + crt->raw.len;
1341
1342 /*
1343 * signatureAlgorithm AlgorithmIdentifier,
1344 * signatureValue BIT STRING
1345 */
1346 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1347 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001348 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001349 return( ret );
1350 }
1351
Paul Bakker320a4b52009-03-28 18:52:39 +00001352 if( memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001353 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001354 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001355 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001356 }
1357
1358 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1359 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001360 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001361 return( ret );
1362 }
1363
1364 if( p != end )
1365 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001366 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001367 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001368 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001369 }
1370
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001371 return( 0 );
1372}
1373
1374/*
1375 * Parse one or more PEM certificates from a buffer and add them to the chained list
1376 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001377int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001378{
Paul Bakker69e095c2011-12-10 21:55:01 +00001379 int ret, success = 0, first_error = 0, total_failed = 0;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001380 x509_cert *crt, *prev = NULL;
1381 int buf_format = X509_FORMAT_DER;
1382
1383 crt = chain;
1384
1385 /*
1386 * Check for valid input
1387 */
1388 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001389 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001390
1391 while( crt->version != 0 && crt->next != NULL )
1392 {
1393 prev = crt;
1394 crt = crt->next;
1395 }
1396
1397 /*
1398 * Add new certificate on the end of the chain if needed.
1399 */
1400 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001401 {
1402 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1403
Paul Bakker7d06ad22009-05-02 15:53:56 +00001404 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001405 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker320a4b52009-03-28 18:52:39 +00001406
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001407 prev = crt;
Paul Bakker7d06ad22009-05-02 15:53:56 +00001408 crt = crt->next;
1409 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001410 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001411
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001412 /*
1413 * Determine buffer content. Buffer contains either one DER certificate or
1414 * one or more PEM certificates.
1415 */
1416#if defined(POLARSSL_PEM_C)
1417 if( strstr( (char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
1418 buf_format = X509_FORMAT_PEM;
1419#endif
1420
1421 if( buf_format == X509_FORMAT_DER )
1422 return x509parse_crt_der( crt, buf, buflen );
1423
1424#if defined(POLARSSL_PEM_C)
1425 if( buf_format == X509_FORMAT_PEM )
1426 {
1427 pem_context pem;
1428
1429 while( buflen > 0 )
1430 {
1431 size_t use_len;
1432 pem_init( &pem );
1433
1434 ret = pem_read_buffer( &pem,
1435 "-----BEGIN CERTIFICATE-----",
1436 "-----END CERTIFICATE-----",
1437 buf, NULL, 0, &use_len );
1438
1439 if( ret == 0 )
1440 {
1441 /*
1442 * Was PEM encoded
1443 */
1444 buflen -= use_len;
1445 buf += use_len;
1446 }
1447 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
1448 {
1449 pem_free( &pem );
1450
1451 if( first_error == 0 )
1452 first_error = ret;
1453
1454 continue;
1455 }
1456 else
1457 break;
1458
1459 ret = x509parse_crt_der( crt, pem.buf, pem.buflen );
1460
1461 pem_free( &pem );
1462
1463 if( ret != 0 )
1464 {
1465 /*
Paul Bakker69e095c2011-12-10 21:55:01 +00001466 * quit parsing on a memory error
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001467 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001468 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001469 {
1470 if( prev )
1471 prev->next = NULL;
1472
1473 if( crt != chain )
1474 free( crt );
1475
1476 return( ret );
1477 }
1478
1479 if( first_error == 0 )
1480 first_error = ret;
Paul Bakker69e095c2011-12-10 21:55:01 +00001481
1482 total_failed++;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001483
1484 memset( crt, 0, sizeof( x509_cert ) );
1485 continue;
1486 }
1487
1488 success = 1;
1489
1490 /*
1491 * Add new certificate to the list
1492 */
1493 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1494
1495 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001496 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001497
1498 prev = crt;
1499 crt = crt->next;
1500 memset( crt, 0, sizeof( x509_cert ) );
1501 }
1502 }
1503#endif
1504
1505 if( crt->version == 0 )
1506 {
1507 if( prev )
1508 prev->next = NULL;
1509
1510 if( crt != chain )
1511 free( crt );
1512 }
1513
1514 if( success )
Paul Bakker69e095c2011-12-10 21:55:01 +00001515 return( total_failed );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001516 else if( first_error )
1517 return( first_error );
1518 else
1519 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001520}
1521
1522/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001523 * Parse one or more CRLs and add them to the chained list
1524 */
Paul Bakker23986e52011-04-24 08:57:21 +00001525int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001526{
Paul Bakker23986e52011-04-24 08:57:21 +00001527 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001528 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001529 unsigned char *p, *end;
1530 x509_crl *crl;
Paul Bakker96743fc2011-02-12 14:30:57 +00001531#if defined(POLARSSL_PEM_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00001532 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001533 pem_context pem;
1534#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001535
1536 crl = chain;
1537
1538 /*
1539 * Check for valid input
1540 */
1541 if( crl == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001542 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001543
1544 while( crl->version != 0 && crl->next != NULL )
1545 crl = crl->next;
1546
1547 /*
1548 * Add new CRL on the end of the chain if needed.
1549 */
1550 if ( crl->version != 0 && crl->next == NULL)
1551 {
1552 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1553
Paul Bakker7d06ad22009-05-02 15:53:56 +00001554 if( crl->next == NULL )
1555 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001556 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001557 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001558 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001559
Paul Bakker7d06ad22009-05-02 15:53:56 +00001560 crl = crl->next;
1561 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001562 }
1563
Paul Bakker96743fc2011-02-12 14:30:57 +00001564#if defined(POLARSSL_PEM_C)
1565 pem_init( &pem );
1566 ret = pem_read_buffer( &pem,
1567 "-----BEGIN X509 CRL-----",
1568 "-----END X509 CRL-----",
1569 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001570
Paul Bakker96743fc2011-02-12 14:30:57 +00001571 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001572 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001573 /*
1574 * Was PEM encoded
1575 */
1576 buflen -= use_len;
1577 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001578
1579 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001580 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001581 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001582 p = pem.buf;
1583 pem.buf = NULL;
1584 len = pem.buflen;
1585 pem_free( &pem );
1586 }
1587 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
1588 {
1589 pem_free( &pem );
1590 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001591 }
1592 else
1593 {
1594 /*
1595 * nope, copy the raw DER data
1596 */
1597 p = (unsigned char *) malloc( len = buflen );
1598
1599 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001600 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001601
1602 memcpy( p, buf, buflen );
1603
1604 buflen = 0;
1605 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001606#else
1607 p = (unsigned char *) malloc( len = buflen );
1608
1609 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001610 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001611
1612 memcpy( p, buf, buflen );
1613
1614 buflen = 0;
1615#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001616
1617 crl->raw.p = p;
1618 crl->raw.len = len;
1619 end = p + len;
1620
1621 /*
1622 * CertificateList ::= SEQUENCE {
1623 * tbsCertList TBSCertList,
1624 * signatureAlgorithm AlgorithmIdentifier,
1625 * signatureValue BIT STRING }
1626 */
1627 if( ( ret = asn1_get_tag( &p, end, &len,
1628 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1629 {
1630 x509_crl_free( crl );
1631 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1632 }
1633
Paul Bakker23986e52011-04-24 08:57:21 +00001634 if( len != (size_t) ( end - p ) )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001635 {
1636 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001637 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001638 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1639 }
1640
1641 /*
1642 * TBSCertList ::= SEQUENCE {
1643 */
1644 crl->tbs.p = p;
1645
1646 if( ( ret = asn1_get_tag( &p, end, &len,
1647 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1648 {
1649 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001650 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001651 }
1652
1653 end = p + len;
1654 crl->tbs.len = end - crl->tbs.p;
1655
1656 /*
1657 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1658 * -- if present, MUST be v2
1659 *
1660 * signature AlgorithmIdentifier
1661 */
Paul Bakker3329d1f2011-10-12 09:55:01 +00001662 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
Paul Bakkerd98030e2009-05-02 15:13:40 +00001663 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1664 {
1665 x509_crl_free( crl );
1666 return( ret );
1667 }
1668
1669 crl->version++;
1670
1671 if( crl->version > 2 )
1672 {
1673 x509_crl_free( crl );
1674 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1675 }
1676
Paul Bakker27d66162010-03-17 06:56:01 +00001677 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_alg ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001678 {
1679 x509_crl_free( crl );
1680 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1681 }
1682
1683 /*
1684 * issuer Name
1685 */
1686 crl->issuer_raw.p = p;
1687
1688 if( ( ret = asn1_get_tag( &p, end, &len,
1689 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1690 {
1691 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001692 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001693 }
1694
1695 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1696 {
1697 x509_crl_free( crl );
1698 return( ret );
1699 }
1700
1701 crl->issuer_raw.len = p - crl->issuer_raw.p;
1702
1703 /*
1704 * thisUpdate Time
1705 * nextUpdate Time OPTIONAL
1706 */
Paul Bakker91200182010-02-18 21:26:15 +00001707 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001708 {
1709 x509_crl_free( crl );
1710 return( ret );
1711 }
1712
Paul Bakker91200182010-02-18 21:26:15 +00001713 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001714 {
Paul Bakker9d781402011-05-09 16:17:09 +00001715 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001716 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker9d781402011-05-09 16:17:09 +00001717 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001718 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001719 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001720 x509_crl_free( crl );
1721 return( ret );
1722 }
1723 }
1724
1725 /*
1726 * revokedCertificates SEQUENCE OF SEQUENCE {
1727 * userCertificate CertificateSerialNumber,
1728 * revocationDate Time,
1729 * crlEntryExtensions Extensions OPTIONAL
1730 * -- if present, MUST be v2
1731 * } OPTIONAL
1732 */
1733 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1734 {
1735 x509_crl_free( crl );
1736 return( ret );
1737 }
1738
1739 /*
1740 * crlExtensions EXPLICIT Extensions OPTIONAL
1741 * -- if present, MUST be v2
1742 */
1743 if( crl->version == 2 )
1744 {
1745 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1746
1747 if( ret != 0 )
1748 {
1749 x509_crl_free( crl );
1750 return( ret );
1751 }
1752 }
1753
1754 if( p != end )
1755 {
1756 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001757 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001758 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1759 }
1760
1761 end = crl->raw.p + crl->raw.len;
1762
1763 /*
1764 * signatureAlgorithm AlgorithmIdentifier,
1765 * signatureValue BIT STRING
1766 */
1767 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1768 {
1769 x509_crl_free( crl );
1770 return( ret );
1771 }
1772
1773 if( memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
1774 {
1775 x509_crl_free( crl );
1776 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1777 }
1778
1779 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1780 {
1781 x509_crl_free( crl );
1782 return( ret );
1783 }
1784
1785 if( p != end )
1786 {
1787 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001788 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001789 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1790 }
1791
1792 if( buflen > 0 )
1793 {
1794 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1795
Paul Bakker7d06ad22009-05-02 15:53:56 +00001796 if( crl->next == NULL )
1797 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001798 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001799 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001800 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001801
Paul Bakker7d06ad22009-05-02 15:53:56 +00001802 crl = crl->next;
1803 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001804
1805 return( x509parse_crl( crl, buf, buflen ) );
1806 }
1807
1808 return( 0 );
1809}
1810
Paul Bakker335db3f2011-04-25 15:28:35 +00001811#if defined(POLARSSL_FS_IO)
Paul Bakkerd98030e2009-05-02 15:13:40 +00001812/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001813 * Load all data from a file into a given buffer.
1814 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001815int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001816{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001817 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001818
Paul Bakkerd98030e2009-05-02 15:13:40 +00001819 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001820 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001821
Paul Bakkerd98030e2009-05-02 15:13:40 +00001822 fseek( f, 0, SEEK_END );
1823 *n = (size_t) ftell( f );
1824 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001825
Paul Bakkerd98030e2009-05-02 15:13:40 +00001826 if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001827 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001828
Paul Bakkerd98030e2009-05-02 15:13:40 +00001829 if( fread( *buf, 1, *n, f ) != *n )
1830 {
1831 fclose( f );
1832 free( *buf );
Paul Bakker69e095c2011-12-10 21:55:01 +00001833 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001834 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001835
Paul Bakkerd98030e2009-05-02 15:13:40 +00001836 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001837
Paul Bakkerd98030e2009-05-02 15:13:40 +00001838 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001839
Paul Bakkerd98030e2009-05-02 15:13:40 +00001840 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001841}
1842
1843/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001844 * Load one or more certificates and add them to the chained list
1845 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001846int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001847{
1848 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001849 size_t n;
1850 unsigned char *buf;
1851
Paul Bakker69e095c2011-12-10 21:55:01 +00001852 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1853 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001854
Paul Bakker69e095c2011-12-10 21:55:01 +00001855 ret = x509parse_crt( chain, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001856
1857 memset( buf, 0, n + 1 );
1858 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001859
1860 return( ret );
1861}
1862
Paul Bakkerd98030e2009-05-02 15:13:40 +00001863/*
1864 * Load one or more CRLs and add them to the chained list
1865 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001866int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001867{
1868 int ret;
1869 size_t n;
1870 unsigned char *buf;
1871
Paul Bakker69e095c2011-12-10 21:55:01 +00001872 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1873 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001874
Paul Bakker27fdf462011-06-09 13:55:13 +00001875 ret = x509parse_crl( chain, buf, n );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001876
1877 memset( buf, 0, n + 1 );
1878 free( buf );
1879
1880 return( ret );
1881}
1882
Paul Bakker5121ce52009-01-03 21:22:43 +00001883/*
Paul Bakker335db3f2011-04-25 15:28:35 +00001884 * Load and parse a private RSA key
1885 */
1886int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
1887{
1888 int ret;
1889 size_t n;
1890 unsigned char *buf;
1891
Paul Bakker69e095c2011-12-10 21:55:01 +00001892 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1893 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00001894
1895 if( pwd == NULL )
Paul Bakker27fdf462011-06-09 13:55:13 +00001896 ret = x509parse_key( rsa, buf, n, NULL, 0 );
Paul Bakker335db3f2011-04-25 15:28:35 +00001897 else
Paul Bakker27fdf462011-06-09 13:55:13 +00001898 ret = x509parse_key( rsa, buf, n,
Paul Bakker335db3f2011-04-25 15:28:35 +00001899 (unsigned char *) pwd, strlen( pwd ) );
1900
1901 memset( buf, 0, n + 1 );
1902 free( buf );
1903
1904 return( ret );
1905}
1906
1907/*
1908 * Load and parse a public RSA key
1909 */
1910int x509parse_public_keyfile( rsa_context *rsa, const char *path )
1911{
1912 int ret;
1913 size_t n;
1914 unsigned char *buf;
1915
Paul Bakker69e095c2011-12-10 21:55:01 +00001916 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1917 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00001918
Paul Bakker27fdf462011-06-09 13:55:13 +00001919 ret = x509parse_public_key( rsa, buf, n );
Paul Bakker335db3f2011-04-25 15:28:35 +00001920
1921 memset( buf, 0, n + 1 );
1922 free( buf );
1923
1924 return( ret );
1925}
1926#endif /* POLARSSL_FS_IO */
1927
1928/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001929 * Parse a private RSA key
1930 */
Paul Bakker23986e52011-04-24 08:57:21 +00001931int x509parse_key( rsa_context *rsa, const unsigned char *key, size_t keylen,
1932 const unsigned char *pwd, size_t pwdlen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001933{
Paul Bakker23986e52011-04-24 08:57:21 +00001934 int ret;
1935 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00001936 unsigned char *p, *end;
Paul Bakkered56b222011-07-13 11:26:43 +00001937 unsigned char *p_alt;
1938 x509_buf pk_alg_oid;
1939
Paul Bakker96743fc2011-02-12 14:30:57 +00001940#if defined(POLARSSL_PEM_C)
1941 pem_context pem;
Paul Bakker5121ce52009-01-03 21:22:43 +00001942
Paul Bakker96743fc2011-02-12 14:30:57 +00001943 pem_init( &pem );
1944 ret = pem_read_buffer( &pem,
1945 "-----BEGIN RSA PRIVATE KEY-----",
1946 "-----END RSA PRIVATE KEY-----",
1947 key, pwd, pwdlen, &len );
Paul Bakker5121ce52009-01-03 21:22:43 +00001948
Paul Bakkered56b222011-07-13 11:26:43 +00001949 if( ret == POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
1950 {
1951 ret = pem_read_buffer( &pem,
1952 "-----BEGIN PRIVATE KEY-----",
1953 "-----END PRIVATE KEY-----",
1954 key, pwd, pwdlen, &len );
1955 }
1956
Paul Bakker96743fc2011-02-12 14:30:57 +00001957 if( ret == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001958 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001959 /*
1960 * Was PEM encoded
1961 */
1962 keylen = pem.buflen;
Paul Bakker5121ce52009-01-03 21:22:43 +00001963 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001964 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
Paul Bakkerff60ee62010-03-16 21:09:09 +00001965 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001966 pem_free( &pem );
1967 return( ret );
Paul Bakkerff60ee62010-03-16 21:09:09 +00001968 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001969
Paul Bakker96743fc2011-02-12 14:30:57 +00001970 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
1971#else
Paul Bakker5690efc2011-05-26 13:16:06 +00001972 ((void) pwd);
1973 ((void) pwdlen);
Paul Bakker96743fc2011-02-12 14:30:57 +00001974 p = (unsigned char *) key;
1975#endif
1976 end = p + keylen;
1977
Paul Bakker5121ce52009-01-03 21:22:43 +00001978 /*
Paul Bakkered56b222011-07-13 11:26:43 +00001979 * Note: Depending on the type of private key file one can expect either a
1980 * PrivatKeyInfo object (PKCS#8) or a RSAPrivateKey (PKCS#1) directly.
1981 *
1982 * PrivateKeyInfo ::= SEQUENCE {
Paul Bakker5c721f92011-07-27 16:51:09 +00001983 * version Version,
Paul Bakkered56b222011-07-13 11:26:43 +00001984 * algorithm AlgorithmIdentifier,
1985 * PrivateKey BIT STRING
1986 * }
1987 *
1988 * AlgorithmIdentifier ::= SEQUENCE {
1989 * algorithm OBJECT IDENTIFIER,
1990 * parameters ANY DEFINED BY algorithm OPTIONAL
1991 * }
1992 *
Paul Bakker5121ce52009-01-03 21:22:43 +00001993 * RSAPrivateKey ::= SEQUENCE {
1994 * version Version,
1995 * modulus INTEGER, -- n
1996 * publicExponent INTEGER, -- e
1997 * privateExponent INTEGER, -- d
1998 * prime1 INTEGER, -- p
1999 * prime2 INTEGER, -- q
2000 * exponent1 INTEGER, -- d mod (p-1)
2001 * exponent2 INTEGER, -- d mod (q-1)
2002 * coefficient INTEGER, -- (inverse of q) mod p
2003 * otherPrimeInfos OtherPrimeInfos OPTIONAL
2004 * }
2005 */
2006 if( ( ret = asn1_get_tag( &p, end, &len,
2007 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2008 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002009#if defined(POLARSSL_PEM_C)
2010 pem_free( &pem );
2011#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002012 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002013 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002014 }
2015
2016 end = p + len;
2017
2018 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2019 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002020#if defined(POLARSSL_PEM_C)
2021 pem_free( &pem );
2022#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002023 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002024 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002025 }
2026
2027 if( rsa->ver != 0 )
2028 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002029#if defined(POLARSSL_PEM_C)
2030 pem_free( &pem );
2031#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002032 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002033 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002034 }
2035
Paul Bakkered56b222011-07-13 11:26:43 +00002036 p_alt = p;
2037
2038 if( ( ret = x509_get_alg( &p_alt, end, &pk_alg_oid ) ) != 0 )
2039 {
2040 // Assume that we have the PKCS#1 format if wrong
2041 // tag was encountered
2042 //
2043 if( ret != POLARSSL_ERR_X509_CERT_INVALID_ALG +
2044 POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
2045 {
2046#if defined(POLARSSL_PEM_C)
2047 pem_free( &pem );
2048#endif
2049 rsa_free( rsa );
2050 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
2051 }
2052 }
2053 else
2054 {
2055 int can_handle;
2056
2057 /*
2058 * only RSA keys handled at this time
2059 */
2060 can_handle = 0;
2061
2062 if( pk_alg_oid.len == 9 &&
2063 memcmp( pk_alg_oid.p, OID_PKCS1_RSA, 9 ) == 0 )
2064 can_handle = 1;
2065
2066 if( pk_alg_oid.len == 9 &&
2067 memcmp( pk_alg_oid.p, OID_PKCS1, 8 ) == 0 )
2068 {
2069 if( pk_alg_oid.p[8] >= 2 && pk_alg_oid.p[8] <= 5 )
2070 can_handle = 1;
2071
2072 if ( pk_alg_oid.p[8] >= 11 && pk_alg_oid.p[8] <= 14 )
2073 can_handle = 1;
2074 }
2075
2076 if( pk_alg_oid.len == 5 &&
2077 memcmp( pk_alg_oid.p, OID_RSA_SHA_OBS, 5 ) == 0 )
2078 can_handle = 1;
2079
2080 if( can_handle == 0 )
2081 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
2082
2083 /*
2084 * Parse the PKCS#8 format
2085 */
2086
2087 p = p_alt;
2088 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2089 {
2090#if defined(POLARSSL_PEM_C)
2091 pem_free( &pem );
2092#endif
2093 rsa_free( rsa );
2094 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2095 }
2096
2097 if( ( end - p ) < 1 )
2098 {
2099#if defined(POLARSSL_PEM_C)
2100 pem_free( &pem );
2101#endif
2102 rsa_free( rsa );
2103 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
2104 POLARSSL_ERR_ASN1_OUT_OF_DATA );
2105 }
2106
2107 end = p + len;
2108
2109 if( ( ret = asn1_get_tag( &p, end, &len,
2110 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
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 + ret );
2117 }
2118
2119 end = p + len;
2120
2121 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2122 {
2123#if defined(POLARSSL_PEM_C)
2124 pem_free( &pem );
2125#endif
2126 rsa_free( rsa );
2127 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2128 }
2129
2130 if( rsa->ver != 0 )
2131 {
2132#if defined(POLARSSL_PEM_C)
2133 pem_free( &pem );
2134#endif
2135 rsa_free( rsa );
2136 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2137 }
2138 }
2139
Paul Bakker5121ce52009-01-03 21:22:43 +00002140 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
2141 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
2142 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
2143 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
2144 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
2145 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
2146 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
2147 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
2148 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002149#if defined(POLARSSL_PEM_C)
2150 pem_free( &pem );
2151#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002152 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002153 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002154 }
2155
2156 rsa->len = mpi_size( &rsa->N );
2157
2158 if( p != end )
2159 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002160#if defined(POLARSSL_PEM_C)
2161 pem_free( &pem );
2162#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002163 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002164 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00002165 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002166 }
2167
2168 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2169 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002170#if defined(POLARSSL_PEM_C)
2171 pem_free( &pem );
2172#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002173 rsa_free( rsa );
2174 return( ret );
2175 }
2176
Paul Bakker96743fc2011-02-12 14:30:57 +00002177#if defined(POLARSSL_PEM_C)
2178 pem_free( &pem );
2179#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002180
2181 return( 0 );
2182}
2183
2184/*
Paul Bakker53019ae2011-03-25 13:58:48 +00002185 * Parse a public RSA key
2186 */
Paul Bakker23986e52011-04-24 08:57:21 +00002187int x509parse_public_key( rsa_context *rsa, const unsigned char *key, size_t keylen )
Paul Bakker53019ae2011-03-25 13:58:48 +00002188{
Paul Bakker23986e52011-04-24 08:57:21 +00002189 int ret;
2190 size_t len;
Paul Bakker53019ae2011-03-25 13:58:48 +00002191 unsigned char *p, *end;
2192 x509_buf alg_oid;
2193#if defined(POLARSSL_PEM_C)
2194 pem_context pem;
2195
2196 pem_init( &pem );
2197 ret = pem_read_buffer( &pem,
2198 "-----BEGIN PUBLIC KEY-----",
2199 "-----END PUBLIC KEY-----",
2200 key, NULL, 0, &len );
2201
2202 if( ret == 0 )
2203 {
2204 /*
2205 * Was PEM encoded
2206 */
2207 keylen = pem.buflen;
2208 }
2209 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
2210 {
2211 pem_free( &pem );
2212 return( ret );
2213 }
2214
2215 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2216#else
2217 p = (unsigned char *) key;
2218#endif
2219 end = p + keylen;
2220
2221 /*
2222 * PublicKeyInfo ::= SEQUENCE {
2223 * algorithm AlgorithmIdentifier,
2224 * PublicKey BIT STRING
2225 * }
2226 *
2227 * AlgorithmIdentifier ::= SEQUENCE {
2228 * algorithm OBJECT IDENTIFIER,
2229 * parameters ANY DEFINED BY algorithm OPTIONAL
2230 * }
2231 *
2232 * RSAPublicKey ::= SEQUENCE {
2233 * modulus INTEGER, -- n
2234 * publicExponent INTEGER -- e
2235 * }
2236 */
2237
2238 if( ( ret = asn1_get_tag( &p, end, &len,
2239 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2240 {
2241#if defined(POLARSSL_PEM_C)
2242 pem_free( &pem );
2243#endif
2244 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002245 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002246 }
2247
2248 if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
2249 {
2250#if defined(POLARSSL_PEM_C)
2251 pem_free( &pem );
2252#endif
2253 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002254 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002255 }
2256
2257 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
2258 {
2259#if defined(POLARSSL_PEM_C)
2260 pem_free( &pem );
2261#endif
2262 rsa_free( rsa );
2263 return( ret );
2264 }
2265
2266 rsa->len = mpi_size( &rsa->N );
2267
2268#if defined(POLARSSL_PEM_C)
2269 pem_free( &pem );
2270#endif
2271
2272 return( 0 );
2273}
2274
Paul Bakkereaa89f82011-04-04 21:36:15 +00002275#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00002276/*
Paul Bakker1b57b062011-01-06 15:48:19 +00002277 * Parse DHM parameters
2278 */
Paul Bakker23986e52011-04-24 08:57:21 +00002279int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
Paul Bakker1b57b062011-01-06 15:48:19 +00002280{
Paul Bakker23986e52011-04-24 08:57:21 +00002281 int ret;
2282 size_t len;
Paul Bakker1b57b062011-01-06 15:48:19 +00002283 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00002284#if defined(POLARSSL_PEM_C)
2285 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00002286
Paul Bakker96743fc2011-02-12 14:30:57 +00002287 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00002288
Paul Bakker96743fc2011-02-12 14:30:57 +00002289 ret = pem_read_buffer( &pem,
2290 "-----BEGIN DH PARAMETERS-----",
2291 "-----END DH PARAMETERS-----",
2292 dhmin, NULL, 0, &dhminlen );
2293
2294 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00002295 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002296 /*
2297 * Was PEM encoded
2298 */
2299 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00002300 }
Paul Bakker96743fc2011-02-12 14:30:57 +00002301 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00002302 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002303 pem_free( &pem );
2304 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002305 }
2306
Paul Bakker96743fc2011-02-12 14:30:57 +00002307 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
2308#else
2309 p = (unsigned char *) dhmin;
2310#endif
2311 end = p + dhminlen;
2312
Paul Bakker1b57b062011-01-06 15:48:19 +00002313 memset( dhm, 0, sizeof( dhm_context ) );
2314
Paul Bakker1b57b062011-01-06 15:48:19 +00002315 /*
2316 * DHParams ::= SEQUENCE {
2317 * prime INTEGER, -- P
2318 * generator INTEGER, -- g
2319 * }
2320 */
2321 if( ( ret = asn1_get_tag( &p, end, &len,
2322 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2323 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002324#if defined(POLARSSL_PEM_C)
2325 pem_free( &pem );
2326#endif
Paul Bakker9d781402011-05-09 16:17:09 +00002327 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002328 }
2329
2330 end = p + len;
2331
2332 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
2333 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
2334 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002335#if defined(POLARSSL_PEM_C)
2336 pem_free( &pem );
2337#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002338 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002339 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002340 }
2341
2342 if( p != end )
2343 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002344#if defined(POLARSSL_PEM_C)
2345 pem_free( &pem );
2346#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002347 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002348 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker1b57b062011-01-06 15:48:19 +00002349 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
2350 }
2351
Paul Bakker96743fc2011-02-12 14:30:57 +00002352#if defined(POLARSSL_PEM_C)
2353 pem_free( &pem );
2354#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002355
2356 return( 0 );
2357}
2358
Paul Bakker335db3f2011-04-25 15:28:35 +00002359#if defined(POLARSSL_FS_IO)
Paul Bakker1b57b062011-01-06 15:48:19 +00002360/*
2361 * Load and parse a private RSA key
2362 */
2363int x509parse_dhmfile( dhm_context *dhm, const char *path )
2364{
2365 int ret;
2366 size_t n;
2367 unsigned char *buf;
2368
Paul Bakker69e095c2011-12-10 21:55:01 +00002369 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
2370 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002371
Paul Bakker27fdf462011-06-09 13:55:13 +00002372 ret = x509parse_dhm( dhm, buf, n );
Paul Bakker1b57b062011-01-06 15:48:19 +00002373
2374 memset( buf, 0, n + 1 );
2375 free( buf );
2376
2377 return( ret );
2378}
Paul Bakker335db3f2011-04-25 15:28:35 +00002379#endif /* POLARSSL_FS_IO */
Paul Bakkereaa89f82011-04-04 21:36:15 +00002380#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00002381
Paul Bakker5121ce52009-01-03 21:22:43 +00002382#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002383#include <stdarg.h>
2384
2385#if !defined vsnprintf
2386#define vsnprintf _vsnprintf
2387#endif // vsnprintf
2388
2389/*
2390 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2391 * Result value is not size of buffer needed, but -1 if no fit is possible.
2392 *
2393 * This fuction tries to 'fix' this by at least suggesting enlarging the
2394 * size by 20.
2395 */
2396int compat_snprintf(char *str, size_t size, const char *format, ...)
2397{
2398 va_list ap;
2399 int res = -1;
2400
2401 va_start( ap, format );
2402
2403 res = vsnprintf( str, size, format, ap );
2404
2405 va_end( ap );
2406
2407 // No quick fix possible
2408 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00002409 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002410
2411 return res;
2412}
2413
2414#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002415#endif
2416
Paul Bakkerd98030e2009-05-02 15:13:40 +00002417#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2418
2419#define SAFE_SNPRINTF() \
2420{ \
2421 if( ret == -1 ) \
2422 return( -1 ); \
2423 \
Paul Bakker23986e52011-04-24 08:57:21 +00002424 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002425 p[n - 1] = '\0'; \
2426 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2427 } \
2428 \
Paul Bakker23986e52011-04-24 08:57:21 +00002429 n -= (unsigned int) ret; \
2430 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002431}
2432
Paul Bakker5121ce52009-01-03 21:22:43 +00002433/*
2434 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002435 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002436 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002437int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002438{
Paul Bakker23986e52011-04-24 08:57:21 +00002439 int ret;
2440 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002441 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002442 const x509_name *name;
Paul Bakker5121ce52009-01-03 21:22:43 +00002443 char s[128], *p;
2444
2445 memset( s, 0, sizeof( s ) );
2446
2447 name = dn;
2448 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002449 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002450
2451 while( name != NULL )
2452 {
Paul Bakker74111d32011-01-15 16:57:55 +00002453 if( name != dn )
2454 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002455 ret = snprintf( p, n, ", " );
2456 SAFE_SNPRINTF();
2457 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002458
2459 if( memcmp( name->oid.p, OID_X520, 2 ) == 0 )
2460 {
2461 switch( name->oid.p[2] )
2462 {
2463 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002464 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002465
2466 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002467 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002468
2469 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002470 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002471
2472 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002473 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002474
2475 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002476 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002477
2478 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002479 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002480
2481 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002482 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002483 name->oid.p[2] );
2484 break;
2485 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002486 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002487 }
2488 else if( memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
2489 {
2490 switch( name->oid.p[8] )
2491 {
2492 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002493 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002494
2495 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002496 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002497 name->oid.p[8] );
2498 break;
2499 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002500 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002501 }
2502 else
Paul Bakker74111d32011-01-15 16:57:55 +00002503 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002504 ret = snprintf( p, n, "\?\?=" );
Paul Bakker74111d32011-01-15 16:57:55 +00002505 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002506 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002507
2508 for( i = 0; i < name->val.len; i++ )
2509 {
Paul Bakker27fdf462011-06-09 13:55:13 +00002510 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002511 break;
2512
2513 c = name->val.p[i];
2514 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2515 s[i] = '?';
2516 else s[i] = c;
2517 }
2518 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002519 ret = snprintf( p, n, "%s", s );
2520 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002521 name = name->next;
2522 }
2523
Paul Bakker23986e52011-04-24 08:57:21 +00002524 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002525}
2526
2527/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002528 * Store the serial in printable form into buf; no more
2529 * than size characters will be written
2530 */
2531int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2532{
Paul Bakker23986e52011-04-24 08:57:21 +00002533 int ret;
2534 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00002535 char *p;
2536
2537 p = buf;
2538 n = size;
2539
2540 nr = ( serial->len <= 32 )
Paul Bakker03c7c252011-11-25 12:37:37 +00002541 ? serial->len : 28;
Paul Bakkerdd476992011-01-16 21:34:59 +00002542
2543 for( i = 0; i < nr; i++ )
2544 {
Paul Bakker93048802011-12-05 14:38:06 +00002545 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002546 continue;
2547
Paul Bakkerdd476992011-01-16 21:34:59 +00002548 ret = snprintf( p, n, "%02X%s",
2549 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2550 SAFE_SNPRINTF();
2551 }
2552
Paul Bakker03c7c252011-11-25 12:37:37 +00002553 if( nr != serial->len )
2554 {
2555 ret = snprintf( p, n, "...." );
2556 SAFE_SNPRINTF();
2557 }
2558
Paul Bakker23986e52011-04-24 08:57:21 +00002559 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00002560}
2561
2562/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002563 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002564 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002565int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2566 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002567{
Paul Bakker23986e52011-04-24 08:57:21 +00002568 int ret;
2569 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002570 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00002571
2572 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002573 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002574
Paul Bakkerd98030e2009-05-02 15:13:40 +00002575 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002576 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002577 SAFE_SNPRINTF();
2578 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002579 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002580 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002581
Paul Bakkerdd476992011-01-16 21:34:59 +00002582 ret = x509parse_serial_gets( p, n, &crt->serial);
2583 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002584
Paul Bakkerd98030e2009-05-02 15:13:40 +00002585 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2586 SAFE_SNPRINTF();
2587 ret = x509parse_dn_gets( p, n, &crt->issuer );
2588 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002589
Paul Bakkerd98030e2009-05-02 15:13:40 +00002590 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2591 SAFE_SNPRINTF();
2592 ret = x509parse_dn_gets( p, n, &crt->subject );
2593 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002594
Paul Bakkerd98030e2009-05-02 15:13:40 +00002595 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002596 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2597 crt->valid_from.year, crt->valid_from.mon,
2598 crt->valid_from.day, crt->valid_from.hour,
2599 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002600 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002601
Paul Bakkerd98030e2009-05-02 15:13:40 +00002602 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002603 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2604 crt->valid_to.year, crt->valid_to.mon,
2605 crt->valid_to.day, crt->valid_to.hour,
2606 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002607 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002608
Paul Bakkerd98030e2009-05-02 15:13:40 +00002609 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2610 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002611
Paul Bakker27d66162010-03-17 06:56:01 +00002612 switch( crt->sig_alg )
Paul Bakker5121ce52009-01-03 21:22:43 +00002613 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002614 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2615 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2616 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2617 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2618 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2619 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2620 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2621 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2622 default: ret = snprintf( p, n, "???" ); break;
2623 }
2624 SAFE_SNPRINTF();
2625
2626 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
Paul Bakkerf4f69682011-04-24 16:08:12 +00002627 (int) crt->rsa.N.n * (int) sizeof( unsigned long ) * 8 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002628 SAFE_SNPRINTF();
2629
Paul Bakker23986e52011-04-24 08:57:21 +00002630 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002631}
2632
Paul Bakker74111d32011-01-15 16:57:55 +00002633/* Compare a given OID string with an OID x509_buf * */
2634#define OID_CMP(oid_str, oid_buf) \
2635 ( ( OID_SIZE(oid_str) == (oid_buf)->len ) && \
2636 memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0)
2637
2638/*
2639 * Return an informational string describing the given OID
2640 */
2641const char *x509_oid_get_description( x509_buf *oid )
2642{
2643 if ( oid == NULL )
2644 return ( NULL );
2645
2646 else if( OID_CMP( OID_SERVER_AUTH, oid ) )
2647 return( STRING_SERVER_AUTH );
2648
2649 else if( OID_CMP( OID_CLIENT_AUTH, oid ) )
2650 return( STRING_CLIENT_AUTH );
2651
2652 else if( OID_CMP( OID_CODE_SIGNING, oid ) )
2653 return( STRING_CODE_SIGNING );
2654
2655 else if( OID_CMP( OID_EMAIL_PROTECTION, oid ) )
2656 return( STRING_EMAIL_PROTECTION );
2657
2658 else if( OID_CMP( OID_TIME_STAMPING, oid ) )
2659 return( STRING_TIME_STAMPING );
2660
2661 else if( OID_CMP( OID_OCSP_SIGNING, oid ) )
2662 return( STRING_OCSP_SIGNING );
2663
2664 return( NULL );
2665}
2666
2667/* Return the x.y.z.... style numeric string for the given OID */
2668int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2669{
Paul Bakker23986e52011-04-24 08:57:21 +00002670 int ret;
2671 size_t i, n;
Paul Bakker74111d32011-01-15 16:57:55 +00002672 unsigned int value;
2673 char *p;
2674
2675 p = buf;
2676 n = size;
2677
2678 /* First byte contains first two dots */
2679 if( oid->len > 0 )
2680 {
2681 ret = snprintf( p, n, "%d.%d", oid->p[0]/40, oid->p[0]%40 );
2682 SAFE_SNPRINTF();
2683 }
2684
2685 /* TODO: value can overflow in value. */
2686 value = 0;
Paul Bakker23986e52011-04-24 08:57:21 +00002687 for( i = 1; i < oid->len; i++ )
Paul Bakker74111d32011-01-15 16:57:55 +00002688 {
2689 value <<= 7;
2690 value += oid->p[i] & 0x7F;
2691
2692 if( !( oid->p[i] & 0x80 ) )
2693 {
2694 /* Last byte */
2695 ret = snprintf( p, n, ".%d", value );
2696 SAFE_SNPRINTF();
2697 value = 0;
2698 }
2699 }
2700
Paul Bakker23986e52011-04-24 08:57:21 +00002701 return( (int) ( size - n ) );
Paul Bakker74111d32011-01-15 16:57:55 +00002702}
2703
Paul Bakkerd98030e2009-05-02 15:13:40 +00002704/*
2705 * Return an informational string about the CRL.
2706 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002707int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2708 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002709{
Paul Bakker23986e52011-04-24 08:57:21 +00002710 int ret;
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002711 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002712 char *p;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002713 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002714
2715 p = buf;
2716 n = size;
2717
2718 ret = snprintf( p, n, "%sCRL version : %d",
2719 prefix, crl->version );
2720 SAFE_SNPRINTF();
2721
2722 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2723 SAFE_SNPRINTF();
2724 ret = x509parse_dn_gets( p, n, &crl->issuer );
2725 SAFE_SNPRINTF();
2726
2727 ret = snprintf( p, n, "\n%sthis update : " \
2728 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2729 crl->this_update.year, crl->this_update.mon,
2730 crl->this_update.day, crl->this_update.hour,
2731 crl->this_update.min, crl->this_update.sec );
2732 SAFE_SNPRINTF();
2733
2734 ret = snprintf( p, n, "\n%snext update : " \
2735 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2736 crl->next_update.year, crl->next_update.mon,
2737 crl->next_update.day, crl->next_update.hour,
2738 crl->next_update.min, crl->next_update.sec );
2739 SAFE_SNPRINTF();
2740
2741 entry = &crl->entry;
2742
2743 ret = snprintf( p, n, "\n%sRevoked certificates:",
2744 prefix );
2745 SAFE_SNPRINTF();
2746
Paul Bakker9be19372009-07-27 20:21:53 +00002747 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002748 {
2749 ret = snprintf( p, n, "\n%sserial number: ",
2750 prefix );
2751 SAFE_SNPRINTF();
2752
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002753 ret = x509parse_serial_gets( p, n, &entry->serial);
2754 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002755
Paul Bakkerd98030e2009-05-02 15:13:40 +00002756 ret = snprintf( p, n, " revocation date: " \
2757 "%04d-%02d-%02d %02d:%02d:%02d",
2758 entry->revocation_date.year, entry->revocation_date.mon,
2759 entry->revocation_date.day, entry->revocation_date.hour,
2760 entry->revocation_date.min, entry->revocation_date.sec );
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002761 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002762
2763 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002764 }
2765
Paul Bakkerd98030e2009-05-02 15:13:40 +00002766 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2767 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002768
Paul Bakker27d66162010-03-17 06:56:01 +00002769 switch( crl->sig_alg )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002770 {
2771 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2772 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2773 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2774 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2775 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2776 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2777 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2778 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2779 default: ret = snprintf( p, n, "???" ); break;
2780 }
2781 SAFE_SNPRINTF();
2782
Paul Bakker1e27bb22009-07-19 20:25:25 +00002783 ret = snprintf( p, n, "\n" );
2784 SAFE_SNPRINTF();
2785
Paul Bakker23986e52011-04-24 08:57:21 +00002786 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002787}
2788
2789/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00002790 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00002791 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002792int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00002793{
Paul Bakkercce9d772011-11-18 14:26:47 +00002794 int year, mon, day;
2795 int hour, min, sec;
2796
2797#if defined(_WIN32)
2798 SYSTEMTIME st;
2799
2800 GetLocalTime(&st);
2801
2802 year = st.wYear;
2803 mon = st.wMonth;
2804 day = st.wDay;
2805 hour = st.wHour;
2806 min = st.wMinute;
2807 sec = st.wSecond;
2808#else
Paul Bakker5121ce52009-01-03 21:22:43 +00002809 struct tm *lt;
2810 time_t tt;
2811
2812 tt = time( NULL );
2813 lt = localtime( &tt );
2814
Paul Bakkercce9d772011-11-18 14:26:47 +00002815 year = lt->tm_year + 1900;
2816 mon = lt->tm_mon + 1;
2817 day = lt->tm_mday;
2818 hour = lt->tm_hour;
2819 min = lt->tm_min;
2820 sec = lt->tm_sec;
2821#endif
2822
2823 if( year > to->year )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002824 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002825
Paul Bakkercce9d772011-11-18 14:26:47 +00002826 if( year == to->year &&
2827 mon > to->mon )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002828 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002829
Paul Bakkercce9d772011-11-18 14:26:47 +00002830 if( year == to->year &&
2831 mon == to->mon &&
2832 day > to->day )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002833 return( 1 );
2834
Paul Bakkercce9d772011-11-18 14:26:47 +00002835 if( year == to->year &&
2836 mon == to->mon &&
2837 day == to->day &&
2838 hour > to->hour )
Paul Bakkerb6194992011-01-16 21:40:22 +00002839 return( 1 );
2840
Paul Bakkercce9d772011-11-18 14:26:47 +00002841 if( year == to->year &&
2842 mon == to->mon &&
2843 day == to->day &&
2844 hour == to->hour &&
2845 min > to->min )
Paul Bakkerb6194992011-01-16 21:40:22 +00002846 return( 1 );
2847
Paul Bakkercce9d772011-11-18 14:26:47 +00002848 if( year == to->year &&
2849 mon == to->mon &&
2850 day == to->day &&
2851 hour == to->hour &&
2852 min == to->min &&
2853 sec > to->sec )
Paul Bakkerb6194992011-01-16 21:40:22 +00002854 return( 1 );
2855
Paul Bakker40ea7de2009-05-03 10:18:48 +00002856 return( 0 );
2857}
2858
2859/*
2860 * Return 1 if the certificate is revoked, or 0 otherwise.
2861 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002862int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002863{
Paul Bakkerff60ee62010-03-16 21:09:09 +00002864 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00002865
2866 while( cur != NULL && cur->serial.len != 0 )
2867 {
Paul Bakkera056efc2011-01-16 21:38:35 +00002868 if( crt->serial.len == cur->serial.len &&
2869 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002870 {
2871 if( x509parse_time_expired( &cur->revocation_date ) )
2872 return( 1 );
2873 }
2874
2875 cur = cur->next;
2876 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002877
2878 return( 0 );
2879}
2880
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002881/*
2882 * Wrapper for x509 hashes.
2883 *
Paul Bakker0f5f72e2011-01-18 14:58:55 +00002884 * \param out Buffer to receive the hash (Should be at least 64 bytes)
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002885 */
Paul Bakker23986e52011-04-24 08:57:21 +00002886static void x509_hash( const unsigned char *in, size_t len, int alg,
Paul Bakker5121ce52009-01-03 21:22:43 +00002887 unsigned char *out )
2888{
2889 switch( alg )
2890 {
Paul Bakker40e46942009-01-03 21:51:57 +00002891#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002892 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002893#endif
Paul Bakker40e46942009-01-03 21:51:57 +00002894#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002895 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002896#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002897#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002898 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002899#endif
2900#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002901 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002902#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00002903#if defined(POLARSSL_SHA2_C)
2904 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
2905 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
2906#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00002907#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002908 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
2909 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
2910#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002911 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002912 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002913 break;
2914 }
2915}
2916
2917/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00002918 * Check that the given certificate is valid accoring to the CRL.
2919 */
2920static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
2921 x509_crl *crl_list)
2922{
2923 int flags = 0;
2924 int hash_id;
2925 unsigned char hash[64];
2926
2927 /*
2928 * TODO: What happens if no CRL is present?
2929 * Suggestion: Revocation state should be unknown if no CRL is present.
2930 * For backwards compatibility this is not yet implemented.
2931 */
2932
2933 while( ca != NULL && crl_list != NULL && crl_list->version != 0 )
2934 {
2935 if( crl_list->issuer_raw.len != ca->subject_raw.len ||
2936 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
2937 crl_list->issuer_raw.len ) != 0 )
2938 {
2939 crl_list = crl_list->next;
2940 continue;
2941 }
2942
2943 /*
2944 * Check if CRL is correctly signed by the trusted CA
2945 */
2946 hash_id = crl_list->sig_alg;
2947
2948 x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
2949
2950 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, hash_id,
2951 0, hash, crl_list->sig.p ) == 0 )
2952 {
2953 /*
2954 * CRL is not trusted
2955 */
2956 flags |= BADCRL_NOT_TRUSTED;
2957 break;
2958 }
2959
2960 /*
2961 * Check for validity of CRL (Do not drop out)
2962 */
2963 if( x509parse_time_expired( &crl_list->next_update ) )
2964 flags |= BADCRL_EXPIRED;
2965
2966 /*
2967 * Check if certificate is revoked
2968 */
2969 if( x509parse_revoked(crt, crl_list) )
2970 {
2971 flags |= BADCERT_REVOKED;
2972 break;
2973 }
2974
2975 crl_list = crl_list->next;
2976 }
2977 return flags;
2978}
2979
Paul Bakker57b12982012-02-11 17:38:38 +00002980int x509_wildcard_verify( const char *cn, x509_buf *name )
Paul Bakkera8cd2392012-02-11 16:09:32 +00002981{
2982 size_t i;
2983 size_t cn_idx = 0;
2984
Paul Bakker57b12982012-02-11 17:38:38 +00002985 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
Paul Bakkera8cd2392012-02-11 16:09:32 +00002986 return( 0 );
2987
2988 for( i = 0; i < strlen( cn ); ++i )
2989 {
2990 if( cn[i] == '.' )
2991 {
2992 cn_idx = i;
2993 break;
2994 }
2995 }
2996
2997 if( cn_idx == 0 )
2998 return( 0 );
2999
Paul Bakker57b12982012-02-11 17:38:38 +00003000 if( memcmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 &&
3001 strlen( cn ) - cn_idx == name->len - 1 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003002 {
3003 return( 1 );
3004 }
3005
3006 return( 0 );
3007}
3008
Paul Bakker76fd75a2011-01-16 21:12:10 +00003009/*
Paul Bakker5121ce52009-01-03 21:22:43 +00003010 * Verify the certificate validity
3011 */
3012int x509parse_verify( x509_cert *crt,
3013 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00003014 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003015 const char *cn, int *flags,
3016 int (*f_vrfy)(void *, x509_cert *, int, int),
3017 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00003018{
Paul Bakker23986e52011-04-24 08:57:21 +00003019 size_t cn_len;
Paul Bakker5121ce52009-01-03 21:22:43 +00003020 int hash_id;
3021 int pathlen;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003022 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00003023 x509_name *name;
Paul Bakker4593aea2009-02-09 22:32:35 +00003024 unsigned char hash[64];
Paul Bakkera8cd2392012-02-11 16:09:32 +00003025 x509_sequence *cur = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003026
Paul Bakker40ea7de2009-05-03 10:18:48 +00003027 *flags = 0;
3028
3029 if( x509parse_time_expired( &crt->valid_to ) )
3030 *flags = BADCERT_EXPIRED;
Paul Bakker5121ce52009-01-03 21:22:43 +00003031
3032 if( cn != NULL )
3033 {
3034 name = &crt->subject;
3035 cn_len = strlen( cn );
3036
Paul Bakker4d2c1242012-05-10 14:12:46 +00003037 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
Paul Bakker5121ce52009-01-03 21:22:43 +00003038 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00003039 cur = &crt->subject_alt_names;
3040
3041 while( cur != NULL )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003042 {
Paul Bakker4d2c1242012-05-10 14:12:46 +00003043 if( memcmp( cn, cur->buf.p, cn_len ) == 0 &&
3044 cur->buf.len == cn_len )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003045 break;
3046
Paul Bakker4d2c1242012-05-10 14:12:46 +00003047 if( memcmp( cur->buf.p, "*.", 2 ) == 0 &&
3048 x509_wildcard_verify( cn, &cur->buf ) )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003049 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003050
Paul Bakker4d2c1242012-05-10 14:12:46 +00003051 cur = cur->next;
Paul Bakkera8cd2392012-02-11 16:09:32 +00003052 }
3053
3054 if( cur == NULL )
3055 *flags |= BADCERT_CN_MISMATCH;
3056 }
Paul Bakker4d2c1242012-05-10 14:12:46 +00003057 else
3058 {
3059 while( name != NULL )
3060 {
3061 if( memcmp( name->oid.p, OID_CN, 3 ) == 0 )
3062 {
3063 if( memcmp( name->val.p, cn, cn_len ) == 0 &&
3064 name->val.len == cn_len )
3065 break;
3066
3067 if( memcmp( name->val.p, "*.", 2 ) == 0 &&
3068 x509_wildcard_verify( cn, &name->val ) )
3069 break;
3070 }
3071
3072 name = name->next;
3073 }
3074
3075 if( name == NULL )
3076 *flags |= BADCERT_CN_MISMATCH;
3077 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003078 }
3079
Paul Bakker5121ce52009-01-03 21:22:43 +00003080 /*
3081 * Iterate upwards in the given cert chain,
3082 * ignoring any upper cert with CA != TRUE.
3083 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003084 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003085
3086 pathlen = 1;
3087
Paul Bakker76fd75a2011-01-16 21:12:10 +00003088 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003089 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003090 if( parent->ca_istrue == 0 ||
3091 crt->issuer_raw.len != parent->subject_raw.len ||
3092 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00003093 crt->issuer_raw.len ) != 0 )
3094 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003095 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003096 continue;
3097 }
3098
Paul Bakker27d66162010-03-17 06:56:01 +00003099 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00003100
3101 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
3102
Paul Bakker76fd75a2011-01-16 21:12:10 +00003103 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, hash_id, 0, hash,
3104 crt->sig.p ) != 0 )
3105 *flags |= BADCERT_NOT_TRUSTED;
3106
3107 /* Check trusted CA's CRL for the given crt */
3108 *flags |= x509parse_verifycrl(crt, parent, ca_crl);
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003109
3110 /* crt is verified to be a child of the parent cur, call verify callback */
Paul Bakker74111d32011-01-15 16:57:55 +00003111 if( NULL != f_vrfy )
3112 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003113 if( f_vrfy( p_vrfy, crt, pathlen - 1, ( *flags == 0 ) ) != 0 )
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003114 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker76fd75a2011-01-16 21:12:10 +00003115 else
3116 *flags = 0;
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003117 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00003118 else if( *flags != 0 )
3119 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00003120
3121 pathlen++;
3122
Paul Bakker76fd75a2011-01-16 21:12:10 +00003123 crt = parent;
3124 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003125 }
3126
3127 /*
Paul Bakker76fd75a2011-01-16 21:12:10 +00003128 * Attempt to validate topmost cert with our CA chain.
Paul Bakker5121ce52009-01-03 21:22:43 +00003129 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003130 *flags |= BADCERT_NOT_TRUSTED;
3131
Paul Bakker7c6d4a42009-03-28 20:35:47 +00003132 while( trust_ca != NULL && trust_ca->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003133 {
3134 if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
3135 memcmp( crt->issuer_raw.p, trust_ca->subject_raw.p,
3136 crt->issuer_raw.len ) != 0 )
3137 {
3138 trust_ca = trust_ca->next;
3139 continue;
3140 }
3141
3142 if( trust_ca->max_pathlen > 0 &&
3143 trust_ca->max_pathlen < pathlen )
3144 break;
3145
Paul Bakker27d66162010-03-17 06:56:01 +00003146 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00003147
3148 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
3149
3150 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
3151 0, hash, crt->sig.p ) == 0 )
3152 {
3153 /*
3154 * cert. is signed by a trusted CA
3155 */
3156 *flags &= ~BADCERT_NOT_TRUSTED;
3157 break;
3158 }
3159
3160 trust_ca = trust_ca->next;
3161 }
3162
Paul Bakker76fd75a2011-01-16 21:12:10 +00003163 /* Check trusted CA's CRL for the given crt */
3164 *flags |= x509parse_verifycrl( crt, trust_ca, ca_crl );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003165
3166 /* Verification succeeded, call callback on top cert */
Paul Bakker74111d32011-01-15 16:57:55 +00003167 if( NULL != f_vrfy )
3168 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003169 if( f_vrfy(p_vrfy, crt, pathlen-1, ( *flags == 0 ) ) != 0 )
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003170 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker76fd75a2011-01-16 21:12:10 +00003171 else
3172 *flags = 0;
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003173 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00003174 else if( *flags != 0 )
3175 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003176
Paul Bakker5121ce52009-01-03 21:22:43 +00003177 return( 0 );
3178}
3179
3180/*
3181 * Unallocate all certificate data
3182 */
3183void x509_free( x509_cert *crt )
3184{
3185 x509_cert *cert_cur = crt;
3186 x509_cert *cert_prv;
3187 x509_name *name_cur;
3188 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00003189 x509_sequence *seq_cur;
3190 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00003191
3192 if( crt == NULL )
3193 return;
3194
3195 do
3196 {
3197 rsa_free( &cert_cur->rsa );
3198
3199 name_cur = cert_cur->issuer.next;
3200 while( name_cur != NULL )
3201 {
3202 name_prv = name_cur;
3203 name_cur = name_cur->next;
3204 memset( name_prv, 0, sizeof( x509_name ) );
3205 free( name_prv );
3206 }
3207
3208 name_cur = cert_cur->subject.next;
3209 while( name_cur != NULL )
3210 {
3211 name_prv = name_cur;
3212 name_cur = name_cur->next;
3213 memset( name_prv, 0, sizeof( x509_name ) );
3214 free( name_prv );
3215 }
3216
Paul Bakker74111d32011-01-15 16:57:55 +00003217 seq_cur = cert_cur->ext_key_usage.next;
3218 while( seq_cur != NULL )
3219 {
3220 seq_prv = seq_cur;
3221 seq_cur = seq_cur->next;
3222 memset( seq_prv, 0, sizeof( x509_sequence ) );
3223 free( seq_prv );
3224 }
3225
Paul Bakker8afa70d2012-02-11 18:42:45 +00003226 seq_cur = cert_cur->subject_alt_names.next;
3227 while( seq_cur != NULL )
3228 {
3229 seq_prv = seq_cur;
3230 seq_cur = seq_cur->next;
3231 memset( seq_prv, 0, sizeof( x509_sequence ) );
3232 free( seq_prv );
3233 }
3234
Paul Bakker5121ce52009-01-03 21:22:43 +00003235 if( cert_cur->raw.p != NULL )
3236 {
3237 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
3238 free( cert_cur->raw.p );
3239 }
3240
3241 cert_cur = cert_cur->next;
3242 }
3243 while( cert_cur != NULL );
3244
3245 cert_cur = crt;
3246 do
3247 {
3248 cert_prv = cert_cur;
3249 cert_cur = cert_cur->next;
3250
3251 memset( cert_prv, 0, sizeof( x509_cert ) );
3252 if( cert_prv != crt )
3253 free( cert_prv );
3254 }
3255 while( cert_cur != NULL );
3256}
3257
Paul Bakkerd98030e2009-05-02 15:13:40 +00003258/*
3259 * Unallocate all CRL data
3260 */
3261void x509_crl_free( x509_crl *crl )
3262{
3263 x509_crl *crl_cur = crl;
3264 x509_crl *crl_prv;
3265 x509_name *name_cur;
3266 x509_name *name_prv;
3267 x509_crl_entry *entry_cur;
3268 x509_crl_entry *entry_prv;
3269
3270 if( crl == NULL )
3271 return;
3272
3273 do
3274 {
3275 name_cur = crl_cur->issuer.next;
3276 while( name_cur != NULL )
3277 {
3278 name_prv = name_cur;
3279 name_cur = name_cur->next;
3280 memset( name_prv, 0, sizeof( x509_name ) );
3281 free( name_prv );
3282 }
3283
3284 entry_cur = crl_cur->entry.next;
3285 while( entry_cur != NULL )
3286 {
3287 entry_prv = entry_cur;
3288 entry_cur = entry_cur->next;
3289 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
3290 free( entry_prv );
3291 }
3292
3293 if( crl_cur->raw.p != NULL )
3294 {
3295 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
3296 free( crl_cur->raw.p );
3297 }
3298
3299 crl_cur = crl_cur->next;
3300 }
3301 while( crl_cur != NULL );
3302
3303 crl_cur = crl;
3304 do
3305 {
3306 crl_prv = crl_cur;
3307 crl_cur = crl_cur->next;
3308
3309 memset( crl_prv, 0, sizeof( x509_crl ) );
3310 if( crl_prv != crl )
3311 free( crl_prv );
3312 }
3313 while( crl_cur != NULL );
3314}
3315
Paul Bakker40e46942009-01-03 21:51:57 +00003316#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00003317
Paul Bakker40e46942009-01-03 21:51:57 +00003318#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00003319
3320/*
3321 * Checkup routine
3322 */
3323int x509_self_test( int verbose )
3324{
Paul Bakker5690efc2011-05-26 13:16:06 +00003325#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00003326 int ret;
3327 int flags;
3328 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00003329 x509_cert cacert;
3330 x509_cert clicert;
3331 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00003332#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003333 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00003334#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003335
3336 if( verbose != 0 )
3337 printf( " X.509 certificate load: " );
3338
3339 memset( &clicert, 0, sizeof( x509_cert ) );
3340
3341 ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003342 strlen( test_cli_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003343 if( ret != 0 )
3344 {
3345 if( verbose != 0 )
3346 printf( "failed\n" );
3347
3348 return( ret );
3349 }
3350
3351 memset( &cacert, 0, sizeof( x509_cert ) );
3352
3353 ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003354 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003355 if( ret != 0 )
3356 {
3357 if( verbose != 0 )
3358 printf( "failed\n" );
3359
3360 return( ret );
3361 }
3362
3363 if( verbose != 0 )
3364 printf( "passed\n X.509 private key load: " );
3365
3366 i = strlen( test_ca_key );
3367 j = strlen( test_ca_pwd );
3368
Paul Bakker66b78b22011-03-25 14:22:50 +00003369 rsa_init( &rsa, RSA_PKCS_V15, 0 );
3370
Paul Bakker5121ce52009-01-03 21:22:43 +00003371 if( ( ret = x509parse_key( &rsa,
3372 (unsigned char *) test_ca_key, i,
3373 (unsigned char *) test_ca_pwd, j ) ) != 0 )
3374 {
3375 if( verbose != 0 )
3376 printf( "failed\n" );
3377
3378 return( ret );
3379 }
3380
3381 if( verbose != 0 )
3382 printf( "passed\n X.509 signature verify: ");
3383
Paul Bakker23986e52011-04-24 08:57:21 +00003384 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003385 if( ret != 0 )
3386 {
Paul Bakker23986e52011-04-24 08:57:21 +00003387 printf("%02x", flags);
Paul Bakker5121ce52009-01-03 21:22:43 +00003388 if( verbose != 0 )
3389 printf( "failed\n" );
3390
3391 return( ret );
3392 }
3393
Paul Bakker5690efc2011-05-26 13:16:06 +00003394#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003395 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003396 printf( "passed\n X.509 DHM parameter load: " );
3397
3398 i = strlen( test_dhm_params );
3399 j = strlen( test_ca_pwd );
3400
3401 if( ( ret = x509parse_dhm( &dhm, (unsigned char *) test_dhm_params, i ) ) != 0 )
3402 {
3403 if( verbose != 0 )
3404 printf( "failed\n" );
3405
3406 return( ret );
3407 }
3408
3409 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003410 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00003411#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003412
3413 x509_free( &cacert );
3414 x509_free( &clicert );
3415 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00003416#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003417 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00003418#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003419
3420 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003421#else
3422 ((void) verbose);
3423 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3424#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003425}
3426
3427#endif
3428
3429#endif