blob: 9d01a6500455c2b4c050994fe924d56c724933a1 [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
308 return( x509_get_name( p, end2, cur->next ) );
309}
310
311/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000312 * Time ::= CHOICE {
313 * utcTime UTCTime,
314 * generalTime GeneralizedTime }
315 */
Paul Bakker91200182010-02-18 21:26:15 +0000316static int x509_get_time( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000317 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +0000318 x509_time *time )
319{
Paul Bakker23986e52011-04-24 08:57:21 +0000320 int ret;
321 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000322 char date[64];
Paul Bakker91200182010-02-18 21:26:15 +0000323 unsigned char tag;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000324
Paul Bakker91200182010-02-18 21:26:15 +0000325 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000326 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
327 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000328
Paul Bakker91200182010-02-18 21:26:15 +0000329 tag = **p;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000330
Paul Bakker91200182010-02-18 21:26:15 +0000331 if ( tag == ASN1_UTC_TIME )
332 {
333 (*p)++;
334 ret = asn1_get_len( p, end, &len );
335
336 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000337 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000338
Paul Bakker91200182010-02-18 21:26:15 +0000339 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000340 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
341 len : sizeof( date ) - 1 );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000342
Paul Bakker91200182010-02-18 21:26:15 +0000343 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
344 &time->year, &time->mon, &time->day,
345 &time->hour, &time->min, &time->sec ) < 5 )
346 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000347
Paul Bakker400ff6f2011-02-20 10:40:16 +0000348 time->year += 100 * ( time->year < 50 );
Paul Bakker91200182010-02-18 21:26:15 +0000349 time->year += 1900;
350
351 *p += len;
352
353 return( 0 );
354 }
355 else if ( tag == ASN1_GENERALIZED_TIME )
356 {
357 (*p)++;
358 ret = asn1_get_len( p, end, &len );
359
360 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000361 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker91200182010-02-18 21:26:15 +0000362
363 memset( date, 0, sizeof( date ) );
Paul Bakker27fdf462011-06-09 13:55:13 +0000364 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
365 len : sizeof( date ) - 1 );
Paul Bakker91200182010-02-18 21:26:15 +0000366
367 if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
368 &time->year, &time->mon, &time->day,
369 &time->hour, &time->min, &time->sec ) < 5 )
370 return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
371
372 *p += len;
373
374 return( 0 );
375 }
376 else
Paul Bakker9d781402011-05-09 16:17:09 +0000377 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000378}
379
380
381/*
382 * Validity ::= SEQUENCE {
383 * notBefore Time,
384 * notAfter Time }
385 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000386static int x509_get_dates( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000387 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000388 x509_time *from,
389 x509_time *to )
390{
Paul Bakker23986e52011-04-24 08:57:21 +0000391 int ret;
392 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000393
394 if( ( ret = asn1_get_tag( p, end, &len,
395 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000396 return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000397
398 end = *p + len;
399
Paul Bakker91200182010-02-18 21:26:15 +0000400 if( ( ret = x509_get_time( p, end, from ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000401 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000402
Paul Bakker91200182010-02-18 21:26:15 +0000403 if( ( ret = x509_get_time( p, end, to ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000404 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000405
406 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000407 return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker40e46942009-01-03 21:51:57 +0000408 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000409
410 return( 0 );
411}
412
413/*
414 * SubjectPublicKeyInfo ::= SEQUENCE {
415 * algorithm AlgorithmIdentifier,
416 * subjectPublicKey BIT STRING }
417 */
418static int x509_get_pubkey( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000419 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000420 x509_buf *pk_alg_oid,
421 mpi *N, mpi *E )
422{
Paul Bakker23986e52011-04-24 08:57:21 +0000423 int ret, can_handle;
424 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000425 unsigned char *end2;
426
427 if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 )
428 return( ret );
429
430 /*
431 * only RSA public keys handled at this time
432 */
Paul Bakker400ff6f2011-02-20 10:40:16 +0000433 can_handle = 0;
434
435 if( pk_alg_oid->len == 9 &&
436 memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) == 0 )
437 can_handle = 1;
438
439 if( pk_alg_oid->len == 9 &&
440 memcmp( pk_alg_oid->p, OID_PKCS1, 8 ) == 0 )
441 {
442 if( pk_alg_oid->p[8] >= 2 && pk_alg_oid->p[8] <= 5 )
443 can_handle = 1;
444
445 if ( pk_alg_oid->p[8] >= 11 && pk_alg_oid->p[8] <= 14 )
446 can_handle = 1;
447 }
448
449 if( pk_alg_oid->len == 5 &&
450 memcmp( pk_alg_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
451 can_handle = 1;
452
453 if( can_handle == 0 )
Paul Bakkered56b222011-07-13 11:26:43 +0000454 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
Paul Bakker5121ce52009-01-03 21:22:43 +0000455
456 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000457 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000458
459 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000460 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000461 POLARSSL_ERR_ASN1_OUT_OF_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000462
463 end2 = *p + len;
464
465 if( *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000466 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
Paul Bakker5121ce52009-01-03 21:22:43 +0000467
468 /*
469 * RSAPublicKey ::= SEQUENCE {
470 * modulus INTEGER, -- n
471 * publicExponent INTEGER -- e
472 * }
473 */
474 if( ( ret = asn1_get_tag( p, end2, &len,
475 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000476 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000477
478 if( *p + len != end2 )
Paul Bakker9d781402011-05-09 16:17:09 +0000479 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000480 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000481
482 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
483 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000484 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000485
486 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000487 return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
Paul Bakker40e46942009-01-03 21:51:57 +0000488 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000489
490 return( 0 );
491}
492
493static int x509_get_sig( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000494 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000495 x509_buf *sig )
496{
Paul Bakker23986e52011-04-24 08:57:21 +0000497 int ret;
498 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000499
Paul Bakker8afa70d2012-02-11 18:42:45 +0000500 if( ( end - *p ) < 1 )
501 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE +
502 POLARSSL_ERR_ASN1_OUT_OF_DATA );
503
Paul Bakker5121ce52009-01-03 21:22:43 +0000504 sig->tag = **p;
505
506 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000507 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000508
Paul Bakker74111d32011-01-15 16:57:55 +0000509
Paul Bakker5121ce52009-01-03 21:22:43 +0000510 if( --len < 1 || *(*p)++ != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000511 return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000512
513 sig->len = len;
514 sig->p = *p;
515
516 *p += len;
517
518 return( 0 );
519}
520
521/*
522 * X.509 v2/v3 unique identifier (not parsed)
523 */
524static int x509_get_uid( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000525 const unsigned char *end,
Paul Bakker5121ce52009-01-03 21:22:43 +0000526 x509_buf *uid, int n )
527{
528 int ret;
529
530 if( *p == end )
531 return( 0 );
532
533 uid->tag = **p;
534
535 if( ( ret = asn1_get_tag( p, end, &uid->len,
536 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
537 {
Paul Bakker40e46942009-01-03 21:51:57 +0000538 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker5121ce52009-01-03 21:22:43 +0000539 return( 0 );
540
541 return( ret );
542 }
543
544 uid->p = *p;
545 *p += uid->len;
546
547 return( 0 );
548}
549
550/*
Paul Bakkerd98030e2009-05-02 15:13:40 +0000551 * X.509 Extensions (No parsing of extensions, pointer should
552 * be either manually updated or extensions should be parsed!
Paul Bakker5121ce52009-01-03 21:22:43 +0000553 */
554static int x509_get_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000555 const unsigned char *end,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000556 x509_buf *ext, int tag )
Paul Bakker5121ce52009-01-03 21:22:43 +0000557{
Paul Bakker23986e52011-04-24 08:57:21 +0000558 int ret;
559 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000560
561 if( *p == end )
562 return( 0 );
563
564 ext->tag = **p;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000565
Paul Bakker5121ce52009-01-03 21:22:43 +0000566 if( ( ret = asn1_get_tag( p, end, &ext->len,
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000567 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000568 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000569
570 ext->p = *p;
571 end = *p + ext->len;
572
573 /*
574 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
575 *
576 * Extension ::= SEQUENCE {
577 * extnID OBJECT IDENTIFIER,
578 * critical BOOLEAN DEFAULT FALSE,
579 * extnValue OCTET STRING }
580 */
581 if( ( ret = asn1_get_tag( p, end, &len,
582 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000583 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000584
585 if( end != *p + len )
Paul Bakker9d781402011-05-09 16:17:09 +0000586 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +0000587 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000588
Paul Bakkerd98030e2009-05-02 15:13:40 +0000589 return( 0 );
590}
591
592/*
593 * X.509 CRL v2 extensions (no extensions parsed yet.)
594 */
595static int x509_get_crl_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000596 const unsigned char *end,
597 x509_buf *ext )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000598{
Paul Bakker23986e52011-04-24 08:57:21 +0000599 int ret;
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000600 size_t len = 0;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000601
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000602 /* Get explicit tag */
603 if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000604 {
605 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
606 return( 0 );
607
608 return( ret );
609 }
610
611 while( *p < end )
612 {
613 if( ( ret = asn1_get_tag( p, end, &len,
614 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000615 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +0000616
617 *p += len;
618 }
619
620 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000621 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerd98030e2009-05-02 15:13:40 +0000622 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
623
624 return( 0 );
625}
626
Paul Bakkerb5a11ab2011-10-12 09:58:41 +0000627/*
628 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
629 */
630static int x509_get_crl_entry_ext( unsigned char **p,
631 const unsigned char *end,
632 x509_buf *ext )
633{
634 int ret;
635 size_t len = 0;
636
637 /* OPTIONAL */
638 if (end <= *p)
639 return( 0 );
640
641 ext->tag = **p;
642 ext->p = *p;
643
644 /*
645 * Get CRL-entry extension sequence header
646 * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
647 */
648 if( ( ret = asn1_get_tag( p, end, &ext->len,
649 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
650 {
651 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
652 {
653 ext->p = NULL;
654 return( 0 );
655 }
656 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
657 }
658
659 end = *p + ext->len;
660
661 if( end != *p + ext->len )
662 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
663 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
664
665 while( *p < end )
666 {
667 if( ( ret = asn1_get_tag( p, end, &len,
668 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
669 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
670
671 *p += len;
672 }
673
674 if( *p != end )
675 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
676 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
677
678 return( 0 );
679}
680
Paul Bakker74111d32011-01-15 16:57:55 +0000681static int x509_get_basic_constraints( unsigned char **p,
682 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000683 int *ca_istrue,
684 int *max_pathlen )
685{
Paul Bakker23986e52011-04-24 08:57:21 +0000686 int ret;
687 size_t len;
Paul Bakker74111d32011-01-15 16:57:55 +0000688
689 /*
690 * BasicConstraints ::= SEQUENCE {
691 * cA BOOLEAN DEFAULT FALSE,
692 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
693 */
Paul Bakker3cccddb2011-01-16 21:46:31 +0000694 *ca_istrue = 0; /* DEFAULT FALSE */
Paul Bakker74111d32011-01-15 16:57:55 +0000695 *max_pathlen = 0; /* endless */
696
697 if( ( ret = asn1_get_tag( p, end, &len,
698 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000699 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000700
701 if( *p == end )
702 return 0;
703
Paul Bakker3cccddb2011-01-16 21:46:31 +0000704 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000705 {
706 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker3cccddb2011-01-16 21:46:31 +0000707 ret = asn1_get_int( p, end, ca_istrue );
Paul Bakker74111d32011-01-15 16:57:55 +0000708
709 if( ret != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000710 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000711
Paul Bakker3cccddb2011-01-16 21:46:31 +0000712 if( *ca_istrue != 0 )
713 *ca_istrue = 1;
Paul Bakker74111d32011-01-15 16:57:55 +0000714 }
715
716 if( *p == end )
717 return 0;
718
719 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000720 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000721
722 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +0000723 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000724 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
725
726 (*max_pathlen)++;
727
Paul Bakker74111d32011-01-15 16:57:55 +0000728 return 0;
729}
730
731static int x509_get_ns_cert_type( unsigned char **p,
732 const unsigned char *end,
733 unsigned char *ns_cert_type)
734{
735 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000736 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000737
738 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000739 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000740
741 if( bs.len != 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000742 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000743 POLARSSL_ERR_ASN1_INVALID_LENGTH );
744
745 /* Get actual bitstring */
746 *ns_cert_type = *bs.p;
747 return 0;
748}
749
750static int x509_get_key_usage( unsigned char **p,
751 const unsigned char *end,
752 unsigned char *key_usage)
753{
754 int ret;
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000755 x509_bitstring bs = { 0, 0, NULL };
Paul Bakker74111d32011-01-15 16:57:55 +0000756
757 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000758 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000759
Paul Bakkercebdf172011-11-11 15:01:31 +0000760 if( bs.len > 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000761 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000762 POLARSSL_ERR_ASN1_INVALID_LENGTH );
763
764 /* Get actual bitstring */
765 *key_usage = *bs.p;
766 return 0;
767}
768
Paul Bakkerd98030e2009-05-02 15:13:40 +0000769/*
Paul Bakker74111d32011-01-15 16:57:55 +0000770 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
771 *
772 * KeyPurposeId ::= OBJECT IDENTIFIER
773 */
774static int x509_get_ext_key_usage( unsigned char **p,
775 const unsigned char *end,
776 x509_sequence *ext_key_usage)
777{
778 int ret;
779
780 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000781 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker74111d32011-01-15 16:57:55 +0000782
783 /* Sequence length must be >= 1 */
784 if( ext_key_usage->buf.p == NULL )
Paul Bakker9d781402011-05-09 16:17:09 +0000785 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000786 POLARSSL_ERR_ASN1_INVALID_LENGTH );
787
788 return 0;
789}
790
791/*
Paul Bakkera8cd2392012-02-11 16:09:32 +0000792 * SubjectAltName ::= GeneralNames
793 *
794 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
795 *
796 * GeneralName ::= CHOICE {
797 * otherName [0] OtherName,
798 * rfc822Name [1] IA5String,
799 * dNSName [2] IA5String,
800 * x400Address [3] ORAddress,
801 * directoryName [4] Name,
802 * ediPartyName [5] EDIPartyName,
803 * uniformResourceIdentifier [6] IA5String,
804 * iPAddress [7] OCTET STRING,
805 * registeredID [8] OBJECT IDENTIFIER }
806 *
807 * OtherName ::= SEQUENCE {
808 * type-id OBJECT IDENTIFIER,
809 * value [0] EXPLICIT ANY DEFINED BY type-id }
810 *
811 * EDIPartyName ::= SEQUENCE {
812 * nameAssigner [0] DirectoryString OPTIONAL,
813 * partyName [1] DirectoryString }
814 *
815 * NOTE: PolarSSL only parses and uses dNSName at this point.
816 */
817static int x509_get_subject_alt_name( unsigned char **p,
818 const unsigned char *end,
819 x509_sequence *subject_alt_name )
820{
821 int ret;
822 size_t len, tag_len;
823 asn1_buf *buf;
824 unsigned char tag;
825 asn1_sequence *cur = subject_alt_name;
826
827 /* Get main sequence tag */
828 if( ( ret = asn1_get_tag( p, end, &len,
829 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
830 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
831
832 if( *p + len != end )
833 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
834 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
835
836 while( *p < end )
837 {
838 if( ( end - *p ) < 1 )
839 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
840 POLARSSL_ERR_ASN1_OUT_OF_DATA );
841
842 tag = **p;
843 (*p)++;
844 if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 )
845 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
846
847 if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC )
848 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
849 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
850
851 if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) )
852 {
853 *p += tag_len;
854 continue;
855 }
856
857 buf = &(cur->buf);
858 buf->tag = tag;
859 buf->p = *p;
860 buf->len = tag_len;
861 *p += buf->len;
862
863 /* Allocate and assign next pointer */
864 if (*p < end)
865 {
866 cur->next = (asn1_sequence *) malloc(
867 sizeof( asn1_sequence ) );
868
869 if( cur->next == NULL )
870 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
871 POLARSSL_ERR_ASN1_MALLOC_FAILED );
872
873 cur = cur->next;
874 }
875 }
876
877 /* Set final sequence entry's next pointer to NULL */
878 cur->next = NULL;
879
880 if( *p != end )
881 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
882 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
883
884 return( 0 );
885}
886
887/*
Paul Bakker74111d32011-01-15 16:57:55 +0000888 * X.509 v3 extensions
889 *
890 * TODO: Perform all of the basic constraints tests required by the RFC
891 * TODO: Set values for undetected extensions to a sane default?
892 *
Paul Bakkerd98030e2009-05-02 15:13:40 +0000893 */
894static int x509_get_crt_ext( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000895 const unsigned char *end,
Paul Bakker74111d32011-01-15 16:57:55 +0000896 x509_cert *crt )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000897{
Paul Bakker23986e52011-04-24 08:57:21 +0000898 int ret;
899 size_t len;
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000900 unsigned char *end_ext_data, *end_ext_octet;
Paul Bakkerd98030e2009-05-02 15:13:40 +0000901
Paul Bakkerfbc09f32011-10-12 09:56:41 +0000902 if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +0000903 {
904 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
905 return( 0 );
906
907 return( ret );
908 }
909
Paul Bakker5121ce52009-01-03 21:22:43 +0000910 while( *p < end )
911 {
Paul Bakker74111d32011-01-15 16:57:55 +0000912 /*
913 * Extension ::= SEQUENCE {
914 * extnID OBJECT IDENTIFIER,
915 * critical BOOLEAN DEFAULT FALSE,
916 * extnValue OCTET STRING }
917 */
918 x509_buf extn_oid = {0, 0, NULL};
919 int is_critical = 0; /* DEFAULT FALSE */
920
Paul Bakker5121ce52009-01-03 21:22:43 +0000921 if( ( ret = asn1_get_tag( p, end, &len,
922 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000923 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000924
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000925 end_ext_data = *p + len;
926
Paul Bakker74111d32011-01-15 16:57:55 +0000927 /* Get extension ID */
928 extn_oid.tag = **p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000929
Paul Bakker74111d32011-01-15 16:57:55 +0000930 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000931 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000932
Paul Bakker74111d32011-01-15 16:57:55 +0000933 extn_oid.p = *p;
934 *p += extn_oid.len;
935
936 if( ( end - *p ) < 1 )
Paul Bakker9d781402011-05-09 16:17:09 +0000937 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +0000938 POLARSSL_ERR_ASN1_OUT_OF_DATA );
939
940 /* Get optional critical */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000941 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
Paul Bakker40e46942009-01-03 21:51:57 +0000942 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
Paul Bakker9d781402011-05-09 16:17:09 +0000943 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000944
Paul Bakker74111d32011-01-15 16:57:55 +0000945 /* Data should be octet string type */
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000946 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
Paul Bakker5121ce52009-01-03 21:22:43 +0000947 ASN1_OCTET_STRING ) ) != 0 )
Paul Bakker9d781402011-05-09 16:17:09 +0000948 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000949
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000950 end_ext_octet = *p + len;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000951
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000952 if( end_ext_octet != end_ext_data )
Paul Bakker9d781402011-05-09 16:17:09 +0000953 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakkerc6ce8382009-07-27 21:34:45 +0000954 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000955
Paul Bakker74111d32011-01-15 16:57:55 +0000956 /*
957 * Detect supported extensions
958 */
959 if( ( OID_SIZE( OID_BASIC_CONSTRAINTS ) == extn_oid.len ) &&
960 memcmp( extn_oid.p, OID_BASIC_CONSTRAINTS, extn_oid.len ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000961 {
Paul Bakker74111d32011-01-15 16:57:55 +0000962 /* Parse basic constraints */
963 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
Paul Bakker3cccddb2011-01-16 21:46:31 +0000964 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
Paul Bakker74111d32011-01-15 16:57:55 +0000965 return ( ret );
966 crt->ext_types |= EXT_BASIC_CONSTRAINTS;
Paul Bakker5121ce52009-01-03 21:22:43 +0000967 }
Paul Bakker74111d32011-01-15 16:57:55 +0000968 else if( ( OID_SIZE( OID_NS_CERT_TYPE ) == extn_oid.len ) &&
969 memcmp( extn_oid.p, OID_NS_CERT_TYPE, extn_oid.len ) == 0 )
970 {
971 /* Parse netscape certificate type */
972 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
973 &crt->ns_cert_type ) ) != 0 )
974 return ( ret );
975 crt->ext_types |= EXT_NS_CERT_TYPE;
976 }
977 else if( ( OID_SIZE( OID_KEY_USAGE ) == extn_oid.len ) &&
978 memcmp( extn_oid.p, OID_KEY_USAGE, extn_oid.len ) == 0 )
979 {
980 /* Parse key usage */
981 if( ( ret = x509_get_key_usage( p, end_ext_octet,
982 &crt->key_usage ) ) != 0 )
983 return ( ret );
984 crt->ext_types |= EXT_KEY_USAGE;
985 }
986 else if( ( OID_SIZE( OID_EXTENDED_KEY_USAGE ) == extn_oid.len ) &&
987 memcmp( extn_oid.p, OID_EXTENDED_KEY_USAGE, extn_oid.len ) == 0 )
988 {
989 /* Parse extended key usage */
990 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
991 &crt->ext_key_usage ) ) != 0 )
992 return ( ret );
993 crt->ext_types |= EXT_EXTENDED_KEY_USAGE;
994 }
Paul Bakkera8cd2392012-02-11 16:09:32 +0000995 else if( ( OID_SIZE( OID_SUBJECT_ALT_NAME ) == extn_oid.len ) &&
996 memcmp( extn_oid.p, OID_SUBJECT_ALT_NAME, extn_oid.len ) == 0 )
997 {
998 /* Parse extended key usage */
999 if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
1000 &crt->subject_alt_names ) ) != 0 )
1001 return ( ret );
1002 crt->ext_types |= EXT_SUBJECT_ALT_NAME;
1003 }
Paul Bakker74111d32011-01-15 16:57:55 +00001004 else
1005 {
1006 /* No parser found, skip extension */
1007 *p = end_ext_octet;
Paul Bakker5121ce52009-01-03 21:22:43 +00001008
Paul Bakker5c721f92011-07-27 16:51:09 +00001009#if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
Paul Bakker74111d32011-01-15 16:57:55 +00001010 if( is_critical )
1011 {
1012 /* Data is marked as critical: fail */
Paul Bakker9d781402011-05-09 16:17:09 +00001013 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker74111d32011-01-15 16:57:55 +00001014 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
1015 }
Paul Bakker5c721f92011-07-27 16:51:09 +00001016#endif
Paul Bakker74111d32011-01-15 16:57:55 +00001017 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001018 }
1019
1020 if( *p != end )
Paul Bakker9d781402011-05-09 16:17:09 +00001021 return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
Paul Bakker40e46942009-01-03 21:51:57 +00001022 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001023
Paul Bakker5121ce52009-01-03 21:22:43 +00001024 return( 0 );
1025}
1026
1027/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001028 * X.509 CRL Entries
1029 */
1030static int x509_get_entries( unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001031 const unsigned char *end,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001032 x509_crl_entry *entry )
1033{
Paul Bakker23986e52011-04-24 08:57:21 +00001034 int ret;
1035 size_t entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001036 x509_crl_entry *cur_entry = entry;
1037
1038 if( *p == end )
1039 return( 0 );
1040
Paul Bakker9be19372009-07-27 20:21:53 +00001041 if( ( ret = asn1_get_tag( p, end, &entry_len,
Paul Bakkerd98030e2009-05-02 15:13:40 +00001042 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1043 {
1044 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
1045 return( 0 );
1046
1047 return( ret );
1048 }
1049
Paul Bakker9be19372009-07-27 20:21:53 +00001050 end = *p + entry_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001051
1052 while( *p < end )
1053 {
Paul Bakker23986e52011-04-24 08:57:21 +00001054 size_t len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001055 const unsigned char *end2;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001056
1057 if( ( ret = asn1_get_tag( p, end, &len2,
1058 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
1059 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001060 return( ret );
1061 }
1062
Paul Bakker9be19372009-07-27 20:21:53 +00001063 cur_entry->raw.tag = **p;
1064 cur_entry->raw.p = *p;
1065 cur_entry->raw.len = len2;
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001066 end2 = *p + len2;
Paul Bakker9be19372009-07-27 20:21:53 +00001067
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001068 if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001069 return( ret );
1070
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001071 if( ( ret = x509_get_time( p, end2, &cur_entry->revocation_date ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001072 return( ret );
1073
Paul Bakkerb5a11ab2011-10-12 09:58:41 +00001074 if( ( ret = x509_get_crl_entry_ext( p, end2, &cur_entry->entry_ext ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001075 return( ret );
1076
Paul Bakker74111d32011-01-15 16:57:55 +00001077 if ( *p < end )
1078 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001079 cur_entry->next = malloc( sizeof( x509_crl_entry ) );
Paul Bakkerb15b8512012-01-13 13:44:06 +00001080
1081 if( cur_entry->next == NULL )
1082 return( POLARSSL_ERR_X509_MALLOC_FAILED );
1083
Paul Bakkerd98030e2009-05-02 15:13:40 +00001084 cur_entry = cur_entry->next;
1085 memset( cur_entry, 0, sizeof( x509_crl_entry ) );
1086 }
1087 }
1088
1089 return( 0 );
1090}
1091
Paul Bakker27d66162010-03-17 06:56:01 +00001092static int x509_get_sig_alg( const x509_buf *sig_oid, int *sig_alg )
1093{
1094 if( sig_oid->len == 9 &&
1095 memcmp( sig_oid->p, OID_PKCS1, 8 ) == 0 )
1096 {
1097 if( sig_oid->p[8] >= 2 && sig_oid->p[8] <= 5 )
1098 {
1099 *sig_alg = sig_oid->p[8];
1100 return( 0 );
1101 }
1102
1103 if ( sig_oid->p[8] >= 11 && sig_oid->p[8] <= 14 )
1104 {
1105 *sig_alg = sig_oid->p[8];
1106 return( 0 );
1107 }
1108
1109 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1110 }
Paul Bakker400ff6f2011-02-20 10:40:16 +00001111 if( sig_oid->len == 5 &&
1112 memcmp( sig_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
1113 {
1114 *sig_alg = SIG_RSA_SHA1;
1115 return( 0 );
1116 }
Paul Bakker27d66162010-03-17 06:56:01 +00001117
1118 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1119}
1120
Paul Bakkerd98030e2009-05-02 15:13:40 +00001121/*
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001122 * Parse and fill a single X.509 certificate in DER format
Paul Bakker5121ce52009-01-03 21:22:43 +00001123 */
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001124int x509parse_crt_der( x509_cert *crt, const unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001125{
Paul Bakker23986e52011-04-24 08:57:21 +00001126 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001127 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00001128 unsigned char *p, *end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001129
Paul Bakker320a4b52009-03-28 18:52:39 +00001130 /*
1131 * Check for valid input
1132 */
1133 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001134 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker320a4b52009-03-28 18:52:39 +00001135
Paul Bakker96743fc2011-02-12 14:30:57 +00001136 p = (unsigned char *) malloc( len = buflen );
1137
1138 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001139 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001140
1141 memcpy( p, buf, buflen );
1142
1143 buflen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001144
1145 crt->raw.p = p;
1146 crt->raw.len = len;
1147 end = p + len;
1148
1149 /*
1150 * Certificate ::= SEQUENCE {
1151 * tbsCertificate TBSCertificate,
1152 * signatureAlgorithm AlgorithmIdentifier,
1153 * signatureValue BIT STRING }
1154 */
1155 if( ( ret = asn1_get_tag( &p, end, &len,
1156 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1157 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001158 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001159 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001160 }
1161
Paul Bakker23986e52011-04-24 08:57:21 +00001162 if( len != (size_t) ( end - p ) )
Paul Bakker5121ce52009-01-03 21:22:43 +00001163 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001164 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001165 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001166 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001167 }
1168
1169 /*
1170 * TBSCertificate ::= SEQUENCE {
1171 */
1172 crt->tbs.p = p;
1173
1174 if( ( ret = asn1_get_tag( &p, end, &len,
1175 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1176 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001177 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001178 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001179 }
1180
1181 end = p + len;
1182 crt->tbs.len = end - crt->tbs.p;
1183
1184 /*
1185 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1186 *
1187 * CertificateSerialNumber ::= INTEGER
1188 *
1189 * signature AlgorithmIdentifier
1190 */
1191 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
1192 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
1193 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
1194 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001195 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001196 return( ret );
1197 }
1198
1199 crt->version++;
1200
1201 if( crt->version > 3 )
1202 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001203 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001204 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
Paul Bakker5121ce52009-01-03 21:22:43 +00001205 }
1206
Paul Bakker27d66162010-03-17 06:56:01 +00001207 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_alg ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001208 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001209 x509_free( crt );
Paul Bakker27d66162010-03-17 06:56:01 +00001210 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001211 }
1212
1213 /*
1214 * issuer Name
1215 */
1216 crt->issuer_raw.p = p;
1217
1218 if( ( ret = asn1_get_tag( &p, end, &len,
1219 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1220 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001221 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001222 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001223 }
1224
1225 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
1226 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001227 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001228 return( ret );
1229 }
1230
1231 crt->issuer_raw.len = p - crt->issuer_raw.p;
1232
1233 /*
1234 * Validity ::= SEQUENCE {
1235 * notBefore Time,
1236 * notAfter Time }
1237 *
1238 */
1239 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
1240 &crt->valid_to ) ) != 0 )
1241 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001242 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001243 return( ret );
1244 }
1245
1246 /*
1247 * subject Name
1248 */
1249 crt->subject_raw.p = p;
1250
1251 if( ( ret = asn1_get_tag( &p, end, &len,
1252 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1253 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001254 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001255 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001256 }
1257
1258 if( ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
1259 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001260 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001261 return( ret );
1262 }
1263
1264 crt->subject_raw.len = p - crt->subject_raw.p;
1265
1266 /*
1267 * SubjectPublicKeyInfo ::= SEQUENCE
1268 * algorithm AlgorithmIdentifier,
1269 * subjectPublicKey BIT STRING }
1270 */
1271 if( ( ret = asn1_get_tag( &p, end, &len,
1272 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1273 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001274 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001275 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001276 }
1277
1278 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
1279 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
1280 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001281 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001282 return( ret );
1283 }
1284
1285 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
1286 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001287 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001288 return( ret );
1289 }
1290
1291 crt->rsa.len = mpi_size( &crt->rsa.N );
1292
1293 /*
1294 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1295 * -- If present, version shall be v2 or v3
1296 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1297 * -- If present, version shall be v2 or v3
1298 * extensions [3] EXPLICIT Extensions OPTIONAL
1299 * -- If present, version shall be v3
1300 */
1301 if( crt->version == 2 || crt->version == 3 )
1302 {
1303 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1304 if( ret != 0 )
1305 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001306 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001307 return( ret );
1308 }
1309 }
1310
1311 if( crt->version == 2 || crt->version == 3 )
1312 {
1313 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1314 if( ret != 0 )
1315 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001316 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001317 return( ret );
1318 }
1319 }
1320
1321 if( crt->version == 3 )
1322 {
Paul Bakker74111d32011-01-15 16:57:55 +00001323 ret = x509_get_crt_ext( &p, end, crt);
Paul Bakker5121ce52009-01-03 21:22:43 +00001324 if( ret != 0 )
1325 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001326 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001327 return( ret );
1328 }
1329 }
1330
1331 if( p != end )
1332 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001333 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001334 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001335 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001336 }
1337
1338 end = crt->raw.p + crt->raw.len;
1339
1340 /*
1341 * signatureAlgorithm AlgorithmIdentifier,
1342 * signatureValue BIT STRING
1343 */
1344 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
1345 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001346 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001347 return( ret );
1348 }
1349
Paul Bakker320a4b52009-03-28 18:52:39 +00001350 if( memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001351 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001352 x509_free( crt );
Paul Bakker40e46942009-01-03 21:51:57 +00001353 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001354 }
1355
1356 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1357 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001358 x509_free( crt );
Paul Bakker5121ce52009-01-03 21:22:43 +00001359 return( ret );
1360 }
1361
1362 if( p != end )
1363 {
Paul Bakker7d06ad22009-05-02 15:53:56 +00001364 x509_free( crt );
Paul Bakker9d781402011-05-09 16:17:09 +00001365 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00001366 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00001367 }
1368
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001369 return( 0 );
1370}
1371
1372/*
1373 * Parse one or more PEM certificates from a buffer and add them to the chained list
1374 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001375int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001376{
Paul Bakker69e095c2011-12-10 21:55:01 +00001377 int ret, success = 0, first_error = 0, total_failed = 0;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001378 x509_cert *crt, *prev = NULL;
1379 int buf_format = X509_FORMAT_DER;
1380
1381 crt = chain;
1382
1383 /*
1384 * Check for valid input
1385 */
1386 if( crt == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001387 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001388
1389 while( crt->version != 0 && crt->next != NULL )
1390 {
1391 prev = crt;
1392 crt = crt->next;
1393 }
1394
1395 /*
1396 * Add new certificate on the end of the chain if needed.
1397 */
1398 if ( crt->version != 0 && crt->next == NULL)
Paul Bakker320a4b52009-03-28 18:52:39 +00001399 {
1400 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1401
Paul Bakker7d06ad22009-05-02 15:53:56 +00001402 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001403 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker320a4b52009-03-28 18:52:39 +00001404
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001405 prev = crt;
Paul Bakker7d06ad22009-05-02 15:53:56 +00001406 crt = crt->next;
1407 memset( crt, 0, sizeof( x509_cert ) );
Paul Bakker320a4b52009-03-28 18:52:39 +00001408 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001409
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001410 /*
1411 * Determine buffer content. Buffer contains either one DER certificate or
1412 * one or more PEM certificates.
1413 */
1414#if defined(POLARSSL_PEM_C)
1415 if( strstr( (char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
1416 buf_format = X509_FORMAT_PEM;
1417#endif
1418
1419 if( buf_format == X509_FORMAT_DER )
1420 return x509parse_crt_der( crt, buf, buflen );
1421
1422#if defined(POLARSSL_PEM_C)
1423 if( buf_format == X509_FORMAT_PEM )
1424 {
1425 pem_context pem;
1426
1427 while( buflen > 0 )
1428 {
1429 size_t use_len;
1430 pem_init( &pem );
1431
1432 ret = pem_read_buffer( &pem,
1433 "-----BEGIN CERTIFICATE-----",
1434 "-----END CERTIFICATE-----",
1435 buf, NULL, 0, &use_len );
1436
1437 if( ret == 0 )
1438 {
1439 /*
1440 * Was PEM encoded
1441 */
1442 buflen -= use_len;
1443 buf += use_len;
1444 }
1445 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
1446 {
1447 pem_free( &pem );
1448
1449 if( first_error == 0 )
1450 first_error = ret;
1451
1452 continue;
1453 }
1454 else
1455 break;
1456
1457 ret = x509parse_crt_der( crt, pem.buf, pem.buflen );
1458
1459 pem_free( &pem );
1460
1461 if( ret != 0 )
1462 {
1463 /*
Paul Bakker69e095c2011-12-10 21:55:01 +00001464 * quit parsing on a memory error
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001465 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001466 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001467 {
1468 if( prev )
1469 prev->next = NULL;
1470
1471 if( crt != chain )
1472 free( crt );
1473
1474 return( ret );
1475 }
1476
1477 if( first_error == 0 )
1478 first_error = ret;
Paul Bakker69e095c2011-12-10 21:55:01 +00001479
1480 total_failed++;
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001481
1482 memset( crt, 0, sizeof( x509_cert ) );
1483 continue;
1484 }
1485
1486 success = 1;
1487
1488 /*
1489 * Add new certificate to the list
1490 */
1491 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
1492
1493 if( crt->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001494 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001495
1496 prev = crt;
1497 crt = crt->next;
1498 memset( crt, 0, sizeof( x509_cert ) );
1499 }
1500 }
1501#endif
1502
1503 if( crt->version == 0 )
1504 {
1505 if( prev )
1506 prev->next = NULL;
1507
1508 if( crt != chain )
1509 free( crt );
1510 }
1511
1512 if( success )
Paul Bakker69e095c2011-12-10 21:55:01 +00001513 return( total_failed );
Paul Bakker6c0ceb32011-12-04 12:24:18 +00001514 else if( first_error )
1515 return( first_error );
1516 else
1517 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
Paul Bakker5121ce52009-01-03 21:22:43 +00001518}
1519
1520/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00001521 * Parse one or more CRLs and add them to the chained list
1522 */
Paul Bakker23986e52011-04-24 08:57:21 +00001523int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001524{
Paul Bakker23986e52011-04-24 08:57:21 +00001525 int ret;
Paul Bakker5690efc2011-05-26 13:16:06 +00001526 size_t len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001527 unsigned char *p, *end;
1528 x509_crl *crl;
Paul Bakker96743fc2011-02-12 14:30:57 +00001529#if defined(POLARSSL_PEM_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00001530 size_t use_len;
Paul Bakker96743fc2011-02-12 14:30:57 +00001531 pem_context pem;
1532#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001533
1534 crl = chain;
1535
1536 /*
1537 * Check for valid input
1538 */
1539 if( crl == NULL || buf == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001540 return( POLARSSL_ERR_X509_INVALID_INPUT );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001541
1542 while( crl->version != 0 && crl->next != NULL )
1543 crl = crl->next;
1544
1545 /*
1546 * Add new CRL on the end of the chain if needed.
1547 */
1548 if ( crl->version != 0 && crl->next == NULL)
1549 {
1550 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1551
Paul Bakker7d06ad22009-05-02 15:53:56 +00001552 if( crl->next == NULL )
1553 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001554 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001555 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001556 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001557
Paul Bakker7d06ad22009-05-02 15:53:56 +00001558 crl = crl->next;
1559 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001560 }
1561
Paul Bakker96743fc2011-02-12 14:30:57 +00001562#if defined(POLARSSL_PEM_C)
1563 pem_init( &pem );
1564 ret = pem_read_buffer( &pem,
1565 "-----BEGIN X509 CRL-----",
1566 "-----END X509 CRL-----",
1567 buf, NULL, 0, &use_len );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001568
Paul Bakker96743fc2011-02-12 14:30:57 +00001569 if( ret == 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001570 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001571 /*
1572 * Was PEM encoded
1573 */
1574 buflen -= use_len;
1575 buf += use_len;
Paul Bakkerd98030e2009-05-02 15:13:40 +00001576
1577 /*
Paul Bakker96743fc2011-02-12 14:30:57 +00001578 * Steal PEM buffer
Paul Bakkerd98030e2009-05-02 15:13:40 +00001579 */
Paul Bakker96743fc2011-02-12 14:30:57 +00001580 p = pem.buf;
1581 pem.buf = NULL;
1582 len = pem.buflen;
1583 pem_free( &pem );
1584 }
1585 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
1586 {
1587 pem_free( &pem );
1588 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001589 }
1590 else
1591 {
1592 /*
1593 * nope, copy the raw DER data
1594 */
1595 p = (unsigned char *) malloc( len = buflen );
1596
1597 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001598 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001599
1600 memcpy( p, buf, buflen );
1601
1602 buflen = 0;
1603 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001604#else
1605 p = (unsigned char *) malloc( len = buflen );
1606
1607 if( p == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001608 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker96743fc2011-02-12 14:30:57 +00001609
1610 memcpy( p, buf, buflen );
1611
1612 buflen = 0;
1613#endif
Paul Bakkerd98030e2009-05-02 15:13:40 +00001614
1615 crl->raw.p = p;
1616 crl->raw.len = len;
1617 end = p + len;
1618
1619 /*
1620 * CertificateList ::= SEQUENCE {
1621 * tbsCertList TBSCertList,
1622 * signatureAlgorithm AlgorithmIdentifier,
1623 * signatureValue BIT STRING }
1624 */
1625 if( ( ret = asn1_get_tag( &p, end, &len,
1626 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1627 {
1628 x509_crl_free( crl );
1629 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
1630 }
1631
Paul Bakker23986e52011-04-24 08:57:21 +00001632 if( len != (size_t) ( end - p ) )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001633 {
1634 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001635 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001636 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1637 }
1638
1639 /*
1640 * TBSCertList ::= SEQUENCE {
1641 */
1642 crl->tbs.p = p;
1643
1644 if( ( ret = asn1_get_tag( &p, end, &len,
1645 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1646 {
1647 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001648 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001649 }
1650
1651 end = p + len;
1652 crl->tbs.len = end - crl->tbs.p;
1653
1654 /*
1655 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
1656 * -- if present, MUST be v2
1657 *
1658 * signature AlgorithmIdentifier
1659 */
Paul Bakker3329d1f2011-10-12 09:55:01 +00001660 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
Paul Bakkerd98030e2009-05-02 15:13:40 +00001661 ( ret = x509_get_alg( &p, end, &crl->sig_oid1 ) ) != 0 )
1662 {
1663 x509_crl_free( crl );
1664 return( ret );
1665 }
1666
1667 crl->version++;
1668
1669 if( crl->version > 2 )
1670 {
1671 x509_crl_free( crl );
1672 return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
1673 }
1674
Paul Bakker27d66162010-03-17 06:56:01 +00001675 if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_alg ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001676 {
1677 x509_crl_free( crl );
1678 return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
1679 }
1680
1681 /*
1682 * issuer Name
1683 */
1684 crl->issuer_raw.p = p;
1685
1686 if( ( ret = asn1_get_tag( &p, end, &len,
1687 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1688 {
1689 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001690 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001691 }
1692
1693 if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
1694 {
1695 x509_crl_free( crl );
1696 return( ret );
1697 }
1698
1699 crl->issuer_raw.len = p - crl->issuer_raw.p;
1700
1701 /*
1702 * thisUpdate Time
1703 * nextUpdate Time OPTIONAL
1704 */
Paul Bakker91200182010-02-18 21:26:15 +00001705 if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001706 {
1707 x509_crl_free( crl );
1708 return( ret );
1709 }
1710
Paul Bakker91200182010-02-18 21:26:15 +00001711 if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001712 {
Paul Bakker9d781402011-05-09 16:17:09 +00001713 if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001714 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
Paul Bakker9d781402011-05-09 16:17:09 +00001715 ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
Paul Bakker9be19372009-07-27 20:21:53 +00001716 POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
Paul Bakker635f4b42009-07-20 20:34:41 +00001717 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001718 x509_crl_free( crl );
1719 return( ret );
1720 }
1721 }
1722
1723 /*
1724 * revokedCertificates SEQUENCE OF SEQUENCE {
1725 * userCertificate CertificateSerialNumber,
1726 * revocationDate Time,
1727 * crlEntryExtensions Extensions OPTIONAL
1728 * -- if present, MUST be v2
1729 * } OPTIONAL
1730 */
1731 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
1732 {
1733 x509_crl_free( crl );
1734 return( ret );
1735 }
1736
1737 /*
1738 * crlExtensions EXPLICIT Extensions OPTIONAL
1739 * -- if present, MUST be v2
1740 */
1741 if( crl->version == 2 )
1742 {
1743 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
1744
1745 if( ret != 0 )
1746 {
1747 x509_crl_free( crl );
1748 return( ret );
1749 }
1750 }
1751
1752 if( p != end )
1753 {
1754 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001755 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001756 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1757 }
1758
1759 end = crl->raw.p + crl->raw.len;
1760
1761 /*
1762 * signatureAlgorithm AlgorithmIdentifier,
1763 * signatureValue BIT STRING
1764 */
1765 if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
1766 {
1767 x509_crl_free( crl );
1768 return( ret );
1769 }
1770
1771 if( memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
1772 {
1773 x509_crl_free( crl );
1774 return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
1775 }
1776
1777 if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
1778 {
1779 x509_crl_free( crl );
1780 return( ret );
1781 }
1782
1783 if( p != end )
1784 {
1785 x509_crl_free( crl );
Paul Bakker9d781402011-05-09 16:17:09 +00001786 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
Paul Bakkerd98030e2009-05-02 15:13:40 +00001787 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
1788 }
1789
1790 if( buflen > 0 )
1791 {
1792 crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
1793
Paul Bakker7d06ad22009-05-02 15:53:56 +00001794 if( crl->next == NULL )
1795 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00001796 x509_crl_free( crl );
Paul Bakker69e095c2011-12-10 21:55:01 +00001797 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker7d06ad22009-05-02 15:53:56 +00001798 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00001799
Paul Bakker7d06ad22009-05-02 15:53:56 +00001800 crl = crl->next;
1801 memset( crl, 0, sizeof( x509_crl ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001802
1803 return( x509parse_crl( crl, buf, buflen ) );
1804 }
1805
1806 return( 0 );
1807}
1808
Paul Bakker335db3f2011-04-25 15:28:35 +00001809#if defined(POLARSSL_FS_IO)
Paul Bakkerd98030e2009-05-02 15:13:40 +00001810/*
Paul Bakker2b245eb2009-04-19 18:44:26 +00001811 * Load all data from a file into a given buffer.
1812 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001813int load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker2b245eb2009-04-19 18:44:26 +00001814{
Paul Bakkerd98030e2009-05-02 15:13:40 +00001815 FILE *f;
Paul Bakker2b245eb2009-04-19 18:44:26 +00001816
Paul Bakkerd98030e2009-05-02 15:13:40 +00001817 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001818 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001819
Paul Bakkerd98030e2009-05-02 15:13:40 +00001820 fseek( f, 0, SEEK_END );
1821 *n = (size_t) ftell( f );
1822 fseek( f, 0, SEEK_SET );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001823
Paul Bakkerd98030e2009-05-02 15:13:40 +00001824 if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +00001825 return( POLARSSL_ERR_X509_MALLOC_FAILED );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001826
Paul Bakkerd98030e2009-05-02 15:13:40 +00001827 if( fread( *buf, 1, *n, f ) != *n )
1828 {
1829 fclose( f );
1830 free( *buf );
Paul Bakker69e095c2011-12-10 21:55:01 +00001831 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001832 }
Paul Bakker2b245eb2009-04-19 18:44:26 +00001833
Paul Bakkerd98030e2009-05-02 15:13:40 +00001834 fclose( f );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001835
Paul Bakkerd98030e2009-05-02 15:13:40 +00001836 (*buf)[*n] = '\0';
Paul Bakker2b245eb2009-04-19 18:44:26 +00001837
Paul Bakkerd98030e2009-05-02 15:13:40 +00001838 return( 0 );
Paul Bakker2b245eb2009-04-19 18:44:26 +00001839}
1840
1841/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001842 * Load one or more certificates and add them to the chained list
1843 */
Paul Bakker69e095c2011-12-10 21:55:01 +00001844int x509parse_crtfile( x509_cert *chain, const char *path )
Paul Bakker5121ce52009-01-03 21:22:43 +00001845{
1846 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001847 size_t n;
1848 unsigned char *buf;
1849
Paul Bakker69e095c2011-12-10 21:55:01 +00001850 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1851 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001852
Paul Bakker69e095c2011-12-10 21:55:01 +00001853 ret = x509parse_crt( chain, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001854
1855 memset( buf, 0, n + 1 );
1856 free( buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001857
1858 return( ret );
1859}
1860
Paul Bakkerd98030e2009-05-02 15:13:40 +00001861/*
1862 * Load one or more CRLs and add them to the chained list
1863 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001864int x509parse_crlfile( x509_crl *chain, const char *path )
Paul Bakkerd98030e2009-05-02 15:13:40 +00001865{
1866 int ret;
1867 size_t n;
1868 unsigned char *buf;
1869
Paul Bakker69e095c2011-12-10 21:55:01 +00001870 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1871 return( ret );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001872
Paul Bakker27fdf462011-06-09 13:55:13 +00001873 ret = x509parse_crl( chain, buf, n );
Paul Bakkerd98030e2009-05-02 15:13:40 +00001874
1875 memset( buf, 0, n + 1 );
1876 free( buf );
1877
1878 return( ret );
1879}
1880
Paul Bakker5121ce52009-01-03 21:22:43 +00001881/*
Paul Bakker335db3f2011-04-25 15:28:35 +00001882 * Load and parse a private RSA key
1883 */
1884int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
1885{
1886 int ret;
1887 size_t n;
1888 unsigned char *buf;
1889
Paul Bakker69e095c2011-12-10 21:55:01 +00001890 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1891 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00001892
1893 if( pwd == NULL )
Paul Bakker27fdf462011-06-09 13:55:13 +00001894 ret = x509parse_key( rsa, buf, n, NULL, 0 );
Paul Bakker335db3f2011-04-25 15:28:35 +00001895 else
Paul Bakker27fdf462011-06-09 13:55:13 +00001896 ret = x509parse_key( rsa, buf, n,
Paul Bakker335db3f2011-04-25 15:28:35 +00001897 (unsigned char *) pwd, strlen( pwd ) );
1898
1899 memset( buf, 0, n + 1 );
1900 free( buf );
1901
1902 return( ret );
1903}
1904
1905/*
1906 * Load and parse a public RSA key
1907 */
1908int x509parse_public_keyfile( rsa_context *rsa, const char *path )
1909{
1910 int ret;
1911 size_t n;
1912 unsigned char *buf;
1913
Paul Bakker69e095c2011-12-10 21:55:01 +00001914 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
1915 return( ret );
Paul Bakker335db3f2011-04-25 15:28:35 +00001916
Paul Bakker27fdf462011-06-09 13:55:13 +00001917 ret = x509parse_public_key( rsa, buf, n );
Paul Bakker335db3f2011-04-25 15:28:35 +00001918
1919 memset( buf, 0, n + 1 );
1920 free( buf );
1921
1922 return( ret );
1923}
1924#endif /* POLARSSL_FS_IO */
1925
1926/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001927 * Parse a private RSA key
1928 */
Paul Bakker23986e52011-04-24 08:57:21 +00001929int x509parse_key( rsa_context *rsa, const unsigned char *key, size_t keylen,
1930 const unsigned char *pwd, size_t pwdlen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001931{
Paul Bakker23986e52011-04-24 08:57:21 +00001932 int ret;
1933 size_t len;
Paul Bakker5121ce52009-01-03 21:22:43 +00001934 unsigned char *p, *end;
Paul Bakkered56b222011-07-13 11:26:43 +00001935 unsigned char *p_alt;
1936 x509_buf pk_alg_oid;
1937
Paul Bakker96743fc2011-02-12 14:30:57 +00001938#if defined(POLARSSL_PEM_C)
1939 pem_context pem;
Paul Bakker5121ce52009-01-03 21:22:43 +00001940
Paul Bakker96743fc2011-02-12 14:30:57 +00001941 pem_init( &pem );
1942 ret = pem_read_buffer( &pem,
1943 "-----BEGIN RSA PRIVATE KEY-----",
1944 "-----END RSA PRIVATE KEY-----",
1945 key, pwd, pwdlen, &len );
Paul Bakker5121ce52009-01-03 21:22:43 +00001946
Paul Bakkered56b222011-07-13 11:26:43 +00001947 if( ret == POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
1948 {
1949 ret = pem_read_buffer( &pem,
1950 "-----BEGIN PRIVATE KEY-----",
1951 "-----END PRIVATE KEY-----",
1952 key, pwd, pwdlen, &len );
1953 }
1954
Paul Bakker96743fc2011-02-12 14:30:57 +00001955 if( ret == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001956 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001957 /*
1958 * Was PEM encoded
1959 */
1960 keylen = pem.buflen;
Paul Bakker5121ce52009-01-03 21:22:43 +00001961 }
Paul Bakker96743fc2011-02-12 14:30:57 +00001962 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
Paul Bakkerff60ee62010-03-16 21:09:09 +00001963 {
Paul Bakker96743fc2011-02-12 14:30:57 +00001964 pem_free( &pem );
1965 return( ret );
Paul Bakkerff60ee62010-03-16 21:09:09 +00001966 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001967
Paul Bakker96743fc2011-02-12 14:30:57 +00001968 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
1969#else
Paul Bakker5690efc2011-05-26 13:16:06 +00001970 ((void) pwd);
1971 ((void) pwdlen);
Paul Bakker96743fc2011-02-12 14:30:57 +00001972 p = (unsigned char *) key;
1973#endif
1974 end = p + keylen;
1975
Paul Bakker5121ce52009-01-03 21:22:43 +00001976 /*
Paul Bakkered56b222011-07-13 11:26:43 +00001977 * Note: Depending on the type of private key file one can expect either a
1978 * PrivatKeyInfo object (PKCS#8) or a RSAPrivateKey (PKCS#1) directly.
1979 *
1980 * PrivateKeyInfo ::= SEQUENCE {
Paul Bakker5c721f92011-07-27 16:51:09 +00001981 * version Version,
Paul Bakkered56b222011-07-13 11:26:43 +00001982 * algorithm AlgorithmIdentifier,
1983 * PrivateKey BIT STRING
1984 * }
1985 *
1986 * AlgorithmIdentifier ::= SEQUENCE {
1987 * algorithm OBJECT IDENTIFIER,
1988 * parameters ANY DEFINED BY algorithm OPTIONAL
1989 * }
1990 *
Paul Bakker5121ce52009-01-03 21:22:43 +00001991 * RSAPrivateKey ::= SEQUENCE {
1992 * version Version,
1993 * modulus INTEGER, -- n
1994 * publicExponent INTEGER, -- e
1995 * privateExponent INTEGER, -- d
1996 * prime1 INTEGER, -- p
1997 * prime2 INTEGER, -- q
1998 * exponent1 INTEGER, -- d mod (p-1)
1999 * exponent2 INTEGER, -- d mod (q-1)
2000 * coefficient INTEGER, -- (inverse of q) mod p
2001 * otherPrimeInfos OtherPrimeInfos OPTIONAL
2002 * }
2003 */
2004 if( ( ret = asn1_get_tag( &p, end, &len,
2005 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2006 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002007#if defined(POLARSSL_PEM_C)
2008 pem_free( &pem );
2009#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002010 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002011 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002012 }
2013
2014 end = p + len;
2015
2016 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2017 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002018#if defined(POLARSSL_PEM_C)
2019 pem_free( &pem );
2020#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002021 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002022 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002023 }
2024
2025 if( rsa->ver != 0 )
2026 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002027#if defined(POLARSSL_PEM_C)
2028 pem_free( &pem );
2029#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002030 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002031 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002032 }
2033
Paul Bakkered56b222011-07-13 11:26:43 +00002034 p_alt = p;
2035
2036 if( ( ret = x509_get_alg( &p_alt, end, &pk_alg_oid ) ) != 0 )
2037 {
2038 // Assume that we have the PKCS#1 format if wrong
2039 // tag was encountered
2040 //
2041 if( ret != POLARSSL_ERR_X509_CERT_INVALID_ALG +
2042 POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
2043 {
2044#if defined(POLARSSL_PEM_C)
2045 pem_free( &pem );
2046#endif
2047 rsa_free( rsa );
2048 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
2049 }
2050 }
2051 else
2052 {
2053 int can_handle;
2054
2055 /*
2056 * only RSA keys handled at this time
2057 */
2058 can_handle = 0;
2059
2060 if( pk_alg_oid.len == 9 &&
2061 memcmp( pk_alg_oid.p, OID_PKCS1_RSA, 9 ) == 0 )
2062 can_handle = 1;
2063
2064 if( pk_alg_oid.len == 9 &&
2065 memcmp( pk_alg_oid.p, OID_PKCS1, 8 ) == 0 )
2066 {
2067 if( pk_alg_oid.p[8] >= 2 && pk_alg_oid.p[8] <= 5 )
2068 can_handle = 1;
2069
2070 if ( pk_alg_oid.p[8] >= 11 && pk_alg_oid.p[8] <= 14 )
2071 can_handle = 1;
2072 }
2073
2074 if( pk_alg_oid.len == 5 &&
2075 memcmp( pk_alg_oid.p, OID_RSA_SHA_OBS, 5 ) == 0 )
2076 can_handle = 1;
2077
2078 if( can_handle == 0 )
2079 return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
2080
2081 /*
2082 * Parse the PKCS#8 format
2083 */
2084
2085 p = p_alt;
2086 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
2087 {
2088#if defined(POLARSSL_PEM_C)
2089 pem_free( &pem );
2090#endif
2091 rsa_free( rsa );
2092 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2093 }
2094
2095 if( ( end - p ) < 1 )
2096 {
2097#if defined(POLARSSL_PEM_C)
2098 pem_free( &pem );
2099#endif
2100 rsa_free( rsa );
2101 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
2102 POLARSSL_ERR_ASN1_OUT_OF_DATA );
2103 }
2104
2105 end = p + len;
2106
2107 if( ( ret = asn1_get_tag( &p, end, &len,
2108 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2109 {
2110#if defined(POLARSSL_PEM_C)
2111 pem_free( &pem );
2112#endif
2113 rsa_free( rsa );
2114 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2115 }
2116
2117 end = p + len;
2118
2119 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
2120 {
2121#if defined(POLARSSL_PEM_C)
2122 pem_free( &pem );
2123#endif
2124 rsa_free( rsa );
2125 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
2126 }
2127
2128 if( rsa->ver != 0 )
2129 {
2130#if defined(POLARSSL_PEM_C)
2131 pem_free( &pem );
2132#endif
2133 rsa_free( rsa );
2134 return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
2135 }
2136 }
2137
Paul Bakker5121ce52009-01-03 21:22:43 +00002138 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
2139 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
2140 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
2141 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
2142 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
2143 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
2144 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
2145 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
2146 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002147#if defined(POLARSSL_PEM_C)
2148 pem_free( &pem );
2149#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002150 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002151 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002152 }
2153
2154 rsa->len = mpi_size( &rsa->N );
2155
2156 if( p != end )
2157 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002158#if defined(POLARSSL_PEM_C)
2159 pem_free( &pem );
2160#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002161 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002162 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker40e46942009-01-03 21:51:57 +00002163 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker5121ce52009-01-03 21:22:43 +00002164 }
2165
2166 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
2167 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002168#if defined(POLARSSL_PEM_C)
2169 pem_free( &pem );
2170#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002171 rsa_free( rsa );
2172 return( ret );
2173 }
2174
Paul Bakker96743fc2011-02-12 14:30:57 +00002175#if defined(POLARSSL_PEM_C)
2176 pem_free( &pem );
2177#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002178
2179 return( 0 );
2180}
2181
2182/*
Paul Bakker53019ae2011-03-25 13:58:48 +00002183 * Parse a public RSA key
2184 */
Paul Bakker23986e52011-04-24 08:57:21 +00002185int x509parse_public_key( rsa_context *rsa, const unsigned char *key, size_t keylen )
Paul Bakker53019ae2011-03-25 13:58:48 +00002186{
Paul Bakker23986e52011-04-24 08:57:21 +00002187 int ret;
2188 size_t len;
Paul Bakker53019ae2011-03-25 13:58:48 +00002189 unsigned char *p, *end;
2190 x509_buf alg_oid;
2191#if defined(POLARSSL_PEM_C)
2192 pem_context pem;
2193
2194 pem_init( &pem );
2195 ret = pem_read_buffer( &pem,
2196 "-----BEGIN PUBLIC KEY-----",
2197 "-----END PUBLIC KEY-----",
2198 key, NULL, 0, &len );
2199
2200 if( ret == 0 )
2201 {
2202 /*
2203 * Was PEM encoded
2204 */
2205 keylen = pem.buflen;
2206 }
2207 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
2208 {
2209 pem_free( &pem );
2210 return( ret );
2211 }
2212
2213 p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
2214#else
2215 p = (unsigned char *) key;
2216#endif
2217 end = p + keylen;
2218
2219 /*
2220 * PublicKeyInfo ::= SEQUENCE {
2221 * algorithm AlgorithmIdentifier,
2222 * PublicKey BIT STRING
2223 * }
2224 *
2225 * AlgorithmIdentifier ::= SEQUENCE {
2226 * algorithm OBJECT IDENTIFIER,
2227 * parameters ANY DEFINED BY algorithm OPTIONAL
2228 * }
2229 *
2230 * RSAPublicKey ::= SEQUENCE {
2231 * modulus INTEGER, -- n
2232 * publicExponent INTEGER -- e
2233 * }
2234 */
2235
2236 if( ( ret = asn1_get_tag( &p, end, &len,
2237 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2238 {
2239#if defined(POLARSSL_PEM_C)
2240 pem_free( &pem );
2241#endif
2242 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002243 return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002244 }
2245
2246 if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
2247 {
2248#if defined(POLARSSL_PEM_C)
2249 pem_free( &pem );
2250#endif
2251 rsa_free( rsa );
Paul Bakker9d781402011-05-09 16:17:09 +00002252 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002253 }
2254
2255 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
2256 {
2257#if defined(POLARSSL_PEM_C)
2258 pem_free( &pem );
2259#endif
2260 rsa_free( rsa );
2261 return( ret );
2262 }
2263
2264 rsa->len = mpi_size( &rsa->N );
2265
2266#if defined(POLARSSL_PEM_C)
2267 pem_free( &pem );
2268#endif
2269
2270 return( 0 );
2271}
2272
Paul Bakkereaa89f82011-04-04 21:36:15 +00002273#if defined(POLARSSL_DHM_C)
Paul Bakker53019ae2011-03-25 13:58:48 +00002274/*
Paul Bakker1b57b062011-01-06 15:48:19 +00002275 * Parse DHM parameters
2276 */
Paul Bakker23986e52011-04-24 08:57:21 +00002277int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
Paul Bakker1b57b062011-01-06 15:48:19 +00002278{
Paul Bakker23986e52011-04-24 08:57:21 +00002279 int ret;
2280 size_t len;
Paul Bakker1b57b062011-01-06 15:48:19 +00002281 unsigned char *p, *end;
Paul Bakker96743fc2011-02-12 14:30:57 +00002282#if defined(POLARSSL_PEM_C)
2283 pem_context pem;
Paul Bakker1b57b062011-01-06 15:48:19 +00002284
Paul Bakker96743fc2011-02-12 14:30:57 +00002285 pem_init( &pem );
Paul Bakker1b57b062011-01-06 15:48:19 +00002286
Paul Bakker96743fc2011-02-12 14:30:57 +00002287 ret = pem_read_buffer( &pem,
2288 "-----BEGIN DH PARAMETERS-----",
2289 "-----END DH PARAMETERS-----",
2290 dhmin, NULL, 0, &dhminlen );
2291
2292 if( ret == 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00002293 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002294 /*
2295 * Was PEM encoded
2296 */
2297 dhminlen = pem.buflen;
Paul Bakker1b57b062011-01-06 15:48:19 +00002298 }
Paul Bakker96743fc2011-02-12 14:30:57 +00002299 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
Paul Bakker1b57b062011-01-06 15:48:19 +00002300 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002301 pem_free( &pem );
2302 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002303 }
2304
Paul Bakker96743fc2011-02-12 14:30:57 +00002305 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
2306#else
2307 p = (unsigned char *) dhmin;
2308#endif
2309 end = p + dhminlen;
2310
Paul Bakker1b57b062011-01-06 15:48:19 +00002311 memset( dhm, 0, sizeof( dhm_context ) );
2312
Paul Bakker1b57b062011-01-06 15:48:19 +00002313 /*
2314 * DHParams ::= SEQUENCE {
2315 * prime INTEGER, -- P
2316 * generator INTEGER, -- g
2317 * }
2318 */
2319 if( ( ret = asn1_get_tag( &p, end, &len,
2320 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
2321 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002322#if defined(POLARSSL_PEM_C)
2323 pem_free( &pem );
2324#endif
Paul Bakker9d781402011-05-09 16:17:09 +00002325 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002326 }
2327
2328 end = p + len;
2329
2330 if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
2331 ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
2332 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002333#if defined(POLARSSL_PEM_C)
2334 pem_free( &pem );
2335#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002336 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002337 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002338 }
2339
2340 if( p != end )
2341 {
Paul Bakker96743fc2011-02-12 14:30:57 +00002342#if defined(POLARSSL_PEM_C)
2343 pem_free( &pem );
2344#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002345 dhm_free( dhm );
Paul Bakker9d781402011-05-09 16:17:09 +00002346 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
Paul Bakker1b57b062011-01-06 15:48:19 +00002347 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
2348 }
2349
Paul Bakker96743fc2011-02-12 14:30:57 +00002350#if defined(POLARSSL_PEM_C)
2351 pem_free( &pem );
2352#endif
Paul Bakker1b57b062011-01-06 15:48:19 +00002353
2354 return( 0 );
2355}
2356
Paul Bakker335db3f2011-04-25 15:28:35 +00002357#if defined(POLARSSL_FS_IO)
Paul Bakker1b57b062011-01-06 15:48:19 +00002358/*
2359 * Load and parse a private RSA key
2360 */
2361int x509parse_dhmfile( dhm_context *dhm, const char *path )
2362{
2363 int ret;
2364 size_t n;
2365 unsigned char *buf;
2366
Paul Bakker69e095c2011-12-10 21:55:01 +00002367 if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
2368 return( ret );
Paul Bakker1b57b062011-01-06 15:48:19 +00002369
Paul Bakker27fdf462011-06-09 13:55:13 +00002370 ret = x509parse_dhm( dhm, buf, n );
Paul Bakker1b57b062011-01-06 15:48:19 +00002371
2372 memset( buf, 0, n + 1 );
2373 free( buf );
2374
2375 return( ret );
2376}
Paul Bakker335db3f2011-04-25 15:28:35 +00002377#endif /* POLARSSL_FS_IO */
Paul Bakkereaa89f82011-04-04 21:36:15 +00002378#endif /* POLARSSL_DHM_C */
Paul Bakker1b57b062011-01-06 15:48:19 +00002379
Paul Bakker5121ce52009-01-03 21:22:43 +00002380#if defined _MSC_VER && !defined snprintf
Paul Bakkerd98030e2009-05-02 15:13:40 +00002381#include <stdarg.h>
2382
2383#if !defined vsnprintf
2384#define vsnprintf _vsnprintf
2385#endif // vsnprintf
2386
2387/*
2388 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
2389 * Result value is not size of buffer needed, but -1 if no fit is possible.
2390 *
2391 * This fuction tries to 'fix' this by at least suggesting enlarging the
2392 * size by 20.
2393 */
2394int compat_snprintf(char *str, size_t size, const char *format, ...)
2395{
2396 va_list ap;
2397 int res = -1;
2398
2399 va_start( ap, format );
2400
2401 res = vsnprintf( str, size, format, ap );
2402
2403 va_end( ap );
2404
2405 // No quick fix possible
2406 if ( res < 0 )
Paul Bakker23986e52011-04-24 08:57:21 +00002407 return( (int) size + 20 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002408
2409 return res;
2410}
2411
2412#define snprintf compat_snprintf
Paul Bakker5121ce52009-01-03 21:22:43 +00002413#endif
2414
Paul Bakkerd98030e2009-05-02 15:13:40 +00002415#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
2416
2417#define SAFE_SNPRINTF() \
2418{ \
2419 if( ret == -1 ) \
2420 return( -1 ); \
2421 \
Paul Bakker23986e52011-04-24 08:57:21 +00002422 if ( (unsigned int) ret > n ) { \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002423 p[n - 1] = '\0'; \
2424 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
2425 } \
2426 \
Paul Bakker23986e52011-04-24 08:57:21 +00002427 n -= (unsigned int) ret; \
2428 p += (unsigned int) ret; \
Paul Bakkerd98030e2009-05-02 15:13:40 +00002429}
2430
Paul Bakker5121ce52009-01-03 21:22:43 +00002431/*
2432 * Store the name in printable form into buf; no more
Paul Bakkerd98030e2009-05-02 15:13:40 +00002433 * than size characters will be written
Paul Bakker5121ce52009-01-03 21:22:43 +00002434 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002435int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
Paul Bakker5121ce52009-01-03 21:22:43 +00002436{
Paul Bakker23986e52011-04-24 08:57:21 +00002437 int ret;
2438 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00002439 unsigned char c;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002440 const x509_name *name;
Paul Bakker5121ce52009-01-03 21:22:43 +00002441 char s[128], *p;
2442
2443 memset( s, 0, sizeof( s ) );
2444
2445 name = dn;
2446 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002447 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002448
2449 while( name != NULL )
2450 {
Paul Bakker74111d32011-01-15 16:57:55 +00002451 if( name != dn )
2452 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002453 ret = snprintf( p, n, ", " );
2454 SAFE_SNPRINTF();
2455 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002456
2457 if( memcmp( name->oid.p, OID_X520, 2 ) == 0 )
2458 {
2459 switch( name->oid.p[2] )
2460 {
2461 case X520_COMMON_NAME:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002462 ret = snprintf( p, n, "CN=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002463
2464 case X520_COUNTRY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002465 ret = snprintf( p, n, "C=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002466
2467 case X520_LOCALITY:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002468 ret = snprintf( p, n, "L=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002469
2470 case X520_STATE:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002471 ret = snprintf( p, n, "ST=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002472
2473 case X520_ORGANIZATION:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002474 ret = snprintf( p, n, "O=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002475
2476 case X520_ORG_UNIT:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002477 ret = snprintf( p, n, "OU=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002478
2479 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002480 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002481 name->oid.p[2] );
2482 break;
2483 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002484 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002485 }
2486 else if( memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
2487 {
2488 switch( name->oid.p[8] )
2489 {
2490 case PKCS9_EMAIL:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002491 ret = snprintf( p, n, "emailAddress=" ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002492
2493 default:
Paul Bakkerd98030e2009-05-02 15:13:40 +00002494 ret = snprintf( p, n, "0x%02X=",
Paul Bakker5121ce52009-01-03 21:22:43 +00002495 name->oid.p[8] );
2496 break;
2497 }
Paul Bakkerd98030e2009-05-02 15:13:40 +00002498 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002499 }
2500 else
Paul Bakker74111d32011-01-15 16:57:55 +00002501 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002502 ret = snprintf( p, n, "\?\?=" );
Paul Bakker74111d32011-01-15 16:57:55 +00002503 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002504 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002505
2506 for( i = 0; i < name->val.len; i++ )
2507 {
Paul Bakker27fdf462011-06-09 13:55:13 +00002508 if( i >= sizeof( s ) - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002509 break;
2510
2511 c = name->val.p[i];
2512 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
2513 s[i] = '?';
2514 else s[i] = c;
2515 }
2516 s[i] = '\0';
Paul Bakkerd98030e2009-05-02 15:13:40 +00002517 ret = snprintf( p, n, "%s", s );
2518 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002519 name = name->next;
2520 }
2521
Paul Bakker23986e52011-04-24 08:57:21 +00002522 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002523}
2524
2525/*
Paul Bakkerdd476992011-01-16 21:34:59 +00002526 * Store the serial in printable form into buf; no more
2527 * than size characters will be written
2528 */
2529int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
2530{
Paul Bakker23986e52011-04-24 08:57:21 +00002531 int ret;
2532 size_t i, n, nr;
Paul Bakkerdd476992011-01-16 21:34:59 +00002533 char *p;
2534
2535 p = buf;
2536 n = size;
2537
2538 nr = ( serial->len <= 32 )
Paul Bakker03c7c252011-11-25 12:37:37 +00002539 ? serial->len : 28;
Paul Bakkerdd476992011-01-16 21:34:59 +00002540
2541 for( i = 0; i < nr; i++ )
2542 {
Paul Bakker93048802011-12-05 14:38:06 +00002543 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002544 continue;
2545
Paul Bakkerdd476992011-01-16 21:34:59 +00002546 ret = snprintf( p, n, "%02X%s",
2547 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
2548 SAFE_SNPRINTF();
2549 }
2550
Paul Bakker03c7c252011-11-25 12:37:37 +00002551 if( nr != serial->len )
2552 {
2553 ret = snprintf( p, n, "...." );
2554 SAFE_SNPRINTF();
2555 }
2556
Paul Bakker23986e52011-04-24 08:57:21 +00002557 return( (int) ( size - n ) );
Paul Bakkerdd476992011-01-16 21:34:59 +00002558}
2559
2560/*
Paul Bakkerd98030e2009-05-02 15:13:40 +00002561 * Return an informational string about the certificate.
Paul Bakker5121ce52009-01-03 21:22:43 +00002562 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002563int x509parse_cert_info( char *buf, size_t size, const char *prefix,
2564 const x509_cert *crt )
Paul Bakker5121ce52009-01-03 21:22:43 +00002565{
Paul Bakker23986e52011-04-24 08:57:21 +00002566 int ret;
2567 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002568 char *p;
Paul Bakker5121ce52009-01-03 21:22:43 +00002569
2570 p = buf;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002571 n = size;
Paul Bakker5121ce52009-01-03 21:22:43 +00002572
Paul Bakkerd98030e2009-05-02 15:13:40 +00002573 ret = snprintf( p, n, "%scert. version : %d\n",
Paul Bakker5121ce52009-01-03 21:22:43 +00002574 prefix, crt->version );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002575 SAFE_SNPRINTF();
2576 ret = snprintf( p, n, "%sserial number : ",
Paul Bakker5121ce52009-01-03 21:22:43 +00002577 prefix );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002578 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002579
Paul Bakkerdd476992011-01-16 21:34:59 +00002580 ret = x509parse_serial_gets( p, n, &crt->serial);
2581 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002582
Paul Bakkerd98030e2009-05-02 15:13:40 +00002583 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2584 SAFE_SNPRINTF();
2585 ret = x509parse_dn_gets( p, n, &crt->issuer );
2586 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002587
Paul Bakkerd98030e2009-05-02 15:13:40 +00002588 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
2589 SAFE_SNPRINTF();
2590 ret = x509parse_dn_gets( p, n, &crt->subject );
2591 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002592
Paul Bakkerd98030e2009-05-02 15:13:40 +00002593 ret = snprintf( p, n, "\n%sissued on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002594 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2595 crt->valid_from.year, crt->valid_from.mon,
2596 crt->valid_from.day, crt->valid_from.hour,
2597 crt->valid_from.min, crt->valid_from.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002598 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002599
Paul Bakkerd98030e2009-05-02 15:13:40 +00002600 ret = snprintf( p, n, "\n%sexpires on : " \
Paul Bakker5121ce52009-01-03 21:22:43 +00002601 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2602 crt->valid_to.year, crt->valid_to.mon,
2603 crt->valid_to.day, crt->valid_to.hour,
2604 crt->valid_to.min, crt->valid_to.sec );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002605 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002606
Paul Bakkerd98030e2009-05-02 15:13:40 +00002607 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2608 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002609
Paul Bakker27d66162010-03-17 06:56:01 +00002610 switch( crt->sig_alg )
Paul Bakker5121ce52009-01-03 21:22:43 +00002611 {
Paul Bakkerd98030e2009-05-02 15:13:40 +00002612 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2613 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2614 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2615 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2616 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2617 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2618 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2619 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2620 default: ret = snprintf( p, n, "???" ); break;
2621 }
2622 SAFE_SNPRINTF();
2623
2624 ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
Paul Bakkerf4f69682011-04-24 16:08:12 +00002625 (int) crt->rsa.N.n * (int) sizeof( unsigned long ) * 8 );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002626 SAFE_SNPRINTF();
2627
Paul Bakker23986e52011-04-24 08:57:21 +00002628 return( (int) ( size - n ) );
Paul Bakkerd98030e2009-05-02 15:13:40 +00002629}
2630
Paul Bakker74111d32011-01-15 16:57:55 +00002631/* Compare a given OID string with an OID x509_buf * */
2632#define OID_CMP(oid_str, oid_buf) \
2633 ( ( OID_SIZE(oid_str) == (oid_buf)->len ) && \
2634 memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0)
2635
2636/*
2637 * Return an informational string describing the given OID
2638 */
2639const char *x509_oid_get_description( x509_buf *oid )
2640{
2641 if ( oid == NULL )
2642 return ( NULL );
2643
2644 else if( OID_CMP( OID_SERVER_AUTH, oid ) )
2645 return( STRING_SERVER_AUTH );
2646
2647 else if( OID_CMP( OID_CLIENT_AUTH, oid ) )
2648 return( STRING_CLIENT_AUTH );
2649
2650 else if( OID_CMP( OID_CODE_SIGNING, oid ) )
2651 return( STRING_CODE_SIGNING );
2652
2653 else if( OID_CMP( OID_EMAIL_PROTECTION, oid ) )
2654 return( STRING_EMAIL_PROTECTION );
2655
2656 else if( OID_CMP( OID_TIME_STAMPING, oid ) )
2657 return( STRING_TIME_STAMPING );
2658
2659 else if( OID_CMP( OID_OCSP_SIGNING, oid ) )
2660 return( STRING_OCSP_SIGNING );
2661
2662 return( NULL );
2663}
2664
2665/* Return the x.y.z.... style numeric string for the given OID */
2666int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
2667{
Paul Bakker23986e52011-04-24 08:57:21 +00002668 int ret;
2669 size_t i, n;
Paul Bakker74111d32011-01-15 16:57:55 +00002670 unsigned int value;
2671 char *p;
2672
2673 p = buf;
2674 n = size;
2675
2676 /* First byte contains first two dots */
2677 if( oid->len > 0 )
2678 {
2679 ret = snprintf( p, n, "%d.%d", oid->p[0]/40, oid->p[0]%40 );
2680 SAFE_SNPRINTF();
2681 }
2682
2683 /* TODO: value can overflow in value. */
2684 value = 0;
Paul Bakker23986e52011-04-24 08:57:21 +00002685 for( i = 1; i < oid->len; i++ )
Paul Bakker74111d32011-01-15 16:57:55 +00002686 {
2687 value <<= 7;
2688 value += oid->p[i] & 0x7F;
2689
2690 if( !( oid->p[i] & 0x80 ) )
2691 {
2692 /* Last byte */
2693 ret = snprintf( p, n, ".%d", value );
2694 SAFE_SNPRINTF();
2695 value = 0;
2696 }
2697 }
2698
Paul Bakker23986e52011-04-24 08:57:21 +00002699 return( (int) ( size - n ) );
Paul Bakker74111d32011-01-15 16:57:55 +00002700}
2701
Paul Bakkerd98030e2009-05-02 15:13:40 +00002702/*
2703 * Return an informational string about the CRL.
2704 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002705int x509parse_crl_info( char *buf, size_t size, const char *prefix,
2706 const x509_crl *crl )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002707{
Paul Bakker23986e52011-04-24 08:57:21 +00002708 int ret;
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002709 size_t n;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002710 char *p;
Paul Bakkerff60ee62010-03-16 21:09:09 +00002711 const x509_crl_entry *entry;
Paul Bakkerd98030e2009-05-02 15:13:40 +00002712
2713 p = buf;
2714 n = size;
2715
2716 ret = snprintf( p, n, "%sCRL version : %d",
2717 prefix, crl->version );
2718 SAFE_SNPRINTF();
2719
2720 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
2721 SAFE_SNPRINTF();
2722 ret = x509parse_dn_gets( p, n, &crl->issuer );
2723 SAFE_SNPRINTF();
2724
2725 ret = snprintf( p, n, "\n%sthis update : " \
2726 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2727 crl->this_update.year, crl->this_update.mon,
2728 crl->this_update.day, crl->this_update.hour,
2729 crl->this_update.min, crl->this_update.sec );
2730 SAFE_SNPRINTF();
2731
2732 ret = snprintf( p, n, "\n%snext update : " \
2733 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
2734 crl->next_update.year, crl->next_update.mon,
2735 crl->next_update.day, crl->next_update.hour,
2736 crl->next_update.min, crl->next_update.sec );
2737 SAFE_SNPRINTF();
2738
2739 entry = &crl->entry;
2740
2741 ret = snprintf( p, n, "\n%sRevoked certificates:",
2742 prefix );
2743 SAFE_SNPRINTF();
2744
Paul Bakker9be19372009-07-27 20:21:53 +00002745 while( entry != NULL && entry->raw.len != 0 )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002746 {
2747 ret = snprintf( p, n, "\n%sserial number: ",
2748 prefix );
2749 SAFE_SNPRINTF();
2750
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002751 ret = x509parse_serial_gets( p, n, &entry->serial);
2752 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002753
Paul Bakkerd98030e2009-05-02 15:13:40 +00002754 ret = snprintf( p, n, " revocation date: " \
2755 "%04d-%02d-%02d %02d:%02d:%02d",
2756 entry->revocation_date.year, entry->revocation_date.mon,
2757 entry->revocation_date.day, entry->revocation_date.hour,
2758 entry->revocation_date.min, entry->revocation_date.sec );
Paul Bakkerc8ffbe72011-12-05 14:22:49 +00002759 SAFE_SNPRINTF();
Paul Bakkerd98030e2009-05-02 15:13:40 +00002760
2761 entry = entry->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00002762 }
2763
Paul Bakkerd98030e2009-05-02 15:13:40 +00002764 ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
2765 SAFE_SNPRINTF();
Paul Bakker5121ce52009-01-03 21:22:43 +00002766
Paul Bakker27d66162010-03-17 06:56:01 +00002767 switch( crl->sig_alg )
Paul Bakkerd98030e2009-05-02 15:13:40 +00002768 {
2769 case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
2770 case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
2771 case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
2772 case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
2773 case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
2774 case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
2775 case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
2776 case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
2777 default: ret = snprintf( p, n, "???" ); break;
2778 }
2779 SAFE_SNPRINTF();
2780
Paul Bakker1e27bb22009-07-19 20:25:25 +00002781 ret = snprintf( p, n, "\n" );
2782 SAFE_SNPRINTF();
2783
Paul Bakker23986e52011-04-24 08:57:21 +00002784 return( (int) ( size - n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002785}
2786
2787/*
Paul Bakker40ea7de2009-05-03 10:18:48 +00002788 * Return 0 if the x509_time is still valid, or 1 otherwise.
Paul Bakker5121ce52009-01-03 21:22:43 +00002789 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002790int x509parse_time_expired( const x509_time *to )
Paul Bakker5121ce52009-01-03 21:22:43 +00002791{
Paul Bakkercce9d772011-11-18 14:26:47 +00002792 int year, mon, day;
2793 int hour, min, sec;
2794
2795#if defined(_WIN32)
2796 SYSTEMTIME st;
2797
2798 GetLocalTime(&st);
2799
2800 year = st.wYear;
2801 mon = st.wMonth;
2802 day = st.wDay;
2803 hour = st.wHour;
2804 min = st.wMinute;
2805 sec = st.wSecond;
2806#else
Paul Bakker5121ce52009-01-03 21:22:43 +00002807 struct tm *lt;
2808 time_t tt;
2809
2810 tt = time( NULL );
2811 lt = localtime( &tt );
2812
Paul Bakkercce9d772011-11-18 14:26:47 +00002813 year = lt->tm_year + 1900;
2814 mon = lt->tm_mon + 1;
2815 day = lt->tm_mday;
2816 hour = lt->tm_hour;
2817 min = lt->tm_min;
2818 sec = lt->tm_sec;
2819#endif
2820
2821 if( year > to->year )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002822 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002823
Paul Bakkercce9d772011-11-18 14:26:47 +00002824 if( year == to->year &&
2825 mon > to->mon )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002826 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002827
Paul Bakkercce9d772011-11-18 14:26:47 +00002828 if( year == to->year &&
2829 mon == to->mon &&
2830 day > to->day )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002831 return( 1 );
2832
Paul Bakkercce9d772011-11-18 14:26:47 +00002833 if( year == to->year &&
2834 mon == to->mon &&
2835 day == to->day &&
2836 hour > to->hour )
Paul Bakkerb6194992011-01-16 21:40:22 +00002837 return( 1 );
2838
Paul Bakkercce9d772011-11-18 14:26:47 +00002839 if( year == to->year &&
2840 mon == to->mon &&
2841 day == to->day &&
2842 hour == to->hour &&
2843 min > to->min )
Paul Bakkerb6194992011-01-16 21:40:22 +00002844 return( 1 );
2845
Paul Bakkercce9d772011-11-18 14:26:47 +00002846 if( year == to->year &&
2847 mon == to->mon &&
2848 day == to->day &&
2849 hour == to->hour &&
2850 min == to->min &&
2851 sec > to->sec )
Paul Bakkerb6194992011-01-16 21:40:22 +00002852 return( 1 );
2853
Paul Bakker40ea7de2009-05-03 10:18:48 +00002854 return( 0 );
2855}
2856
2857/*
2858 * Return 1 if the certificate is revoked, or 0 otherwise.
2859 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00002860int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002861{
Paul Bakkerff60ee62010-03-16 21:09:09 +00002862 const x509_crl_entry *cur = &crl->entry;
Paul Bakker40ea7de2009-05-03 10:18:48 +00002863
2864 while( cur != NULL && cur->serial.len != 0 )
2865 {
Paul Bakkera056efc2011-01-16 21:38:35 +00002866 if( crt->serial.len == cur->serial.len &&
2867 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
Paul Bakker40ea7de2009-05-03 10:18:48 +00002868 {
2869 if( x509parse_time_expired( &cur->revocation_date ) )
2870 return( 1 );
2871 }
2872
2873 cur = cur->next;
2874 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002875
2876 return( 0 );
2877}
2878
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002879/*
2880 * Wrapper for x509 hashes.
2881 *
Paul Bakker0f5f72e2011-01-18 14:58:55 +00002882 * \param out Buffer to receive the hash (Should be at least 64 bytes)
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002883 */
Paul Bakker23986e52011-04-24 08:57:21 +00002884static void x509_hash( const unsigned char *in, size_t len, int alg,
Paul Bakker5121ce52009-01-03 21:22:43 +00002885 unsigned char *out )
2886{
2887 switch( alg )
2888 {
Paul Bakker40e46942009-01-03 21:51:57 +00002889#if defined(POLARSSL_MD2_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002890 case SIG_RSA_MD2 : md2( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002891#endif
Paul Bakker40e46942009-01-03 21:51:57 +00002892#if defined(POLARSSL_MD4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002893 case SIG_RSA_MD4 : md4( in, len, out ); break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002894#endif
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002895#if defined(POLARSSL_MD5_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002896 case SIG_RSA_MD5 : md5( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002897#endif
2898#if defined(POLARSSL_SHA1_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002899 case SIG_RSA_SHA1 : sha1( in, len, out ); break;
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002900#endif
Paul Bakker4593aea2009-02-09 22:32:35 +00002901#if defined(POLARSSL_SHA2_C)
2902 case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
2903 case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
2904#endif
Paul Bakkerfe1aea72009-10-03 20:09:14 +00002905#if defined(POLARSSL_SHA4_C)
Paul Bakker4593aea2009-02-09 22:32:35 +00002906 case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
2907 case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
2908#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002909 default:
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00002910 memset( out, '\xFF', 64 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002911 break;
2912 }
2913}
2914
2915/*
Paul Bakker76fd75a2011-01-16 21:12:10 +00002916 * Check that the given certificate is valid accoring to the CRL.
2917 */
2918static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
2919 x509_crl *crl_list)
2920{
2921 int flags = 0;
2922 int hash_id;
2923 unsigned char hash[64];
2924
2925 /*
2926 * TODO: What happens if no CRL is present?
2927 * Suggestion: Revocation state should be unknown if no CRL is present.
2928 * For backwards compatibility this is not yet implemented.
2929 */
2930
2931 while( ca != NULL && crl_list != NULL && crl_list->version != 0 )
2932 {
2933 if( crl_list->issuer_raw.len != ca->subject_raw.len ||
2934 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
2935 crl_list->issuer_raw.len ) != 0 )
2936 {
2937 crl_list = crl_list->next;
2938 continue;
2939 }
2940
2941 /*
2942 * Check if CRL is correctly signed by the trusted CA
2943 */
2944 hash_id = crl_list->sig_alg;
2945
2946 x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
2947
2948 if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, hash_id,
2949 0, hash, crl_list->sig.p ) == 0 )
2950 {
2951 /*
2952 * CRL is not trusted
2953 */
2954 flags |= BADCRL_NOT_TRUSTED;
2955 break;
2956 }
2957
2958 /*
2959 * Check for validity of CRL (Do not drop out)
2960 */
2961 if( x509parse_time_expired( &crl_list->next_update ) )
2962 flags |= BADCRL_EXPIRED;
2963
2964 /*
2965 * Check if certificate is revoked
2966 */
2967 if( x509parse_revoked(crt, crl_list) )
2968 {
2969 flags |= BADCERT_REVOKED;
2970 break;
2971 }
2972
2973 crl_list = crl_list->next;
2974 }
2975 return flags;
2976}
2977
Paul Bakker57b12982012-02-11 17:38:38 +00002978int x509_wildcard_verify( const char *cn, x509_buf *name )
Paul Bakkera8cd2392012-02-11 16:09:32 +00002979{
2980 size_t i;
2981 size_t cn_idx = 0;
2982
Paul Bakker57b12982012-02-11 17:38:38 +00002983 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
Paul Bakkera8cd2392012-02-11 16:09:32 +00002984 return( 0 );
2985
2986 for( i = 0; i < strlen( cn ); ++i )
2987 {
2988 if( cn[i] == '.' )
2989 {
2990 cn_idx = i;
2991 break;
2992 }
2993 }
2994
2995 if( cn_idx == 0 )
2996 return( 0 );
2997
Paul Bakker57b12982012-02-11 17:38:38 +00002998 if( memcmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 &&
2999 strlen( cn ) - cn_idx == name->len - 1 )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003000 {
3001 return( 1 );
3002 }
3003
3004 return( 0 );
3005}
3006
Paul Bakker76fd75a2011-01-16 21:12:10 +00003007/*
Paul Bakker5121ce52009-01-03 21:22:43 +00003008 * Verify the certificate validity
3009 */
3010int x509parse_verify( x509_cert *crt,
3011 x509_cert *trust_ca,
Paul Bakker40ea7de2009-05-03 10:18:48 +00003012 x509_crl *ca_crl,
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003013 const char *cn, int *flags,
3014 int (*f_vrfy)(void *, x509_cert *, int, int),
3015 void *p_vrfy )
Paul Bakker5121ce52009-01-03 21:22:43 +00003016{
Paul Bakker23986e52011-04-24 08:57:21 +00003017 size_t cn_len;
Paul Bakker5121ce52009-01-03 21:22:43 +00003018 int hash_id;
3019 int pathlen;
Paul Bakker76fd75a2011-01-16 21:12:10 +00003020 x509_cert *parent;
Paul Bakker5121ce52009-01-03 21:22:43 +00003021 x509_name *name;
Paul Bakker4593aea2009-02-09 22:32:35 +00003022 unsigned char hash[64];
Paul Bakkera8cd2392012-02-11 16:09:32 +00003023 x509_sequence *cur = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +00003024
Paul Bakker40ea7de2009-05-03 10:18:48 +00003025 *flags = 0;
3026
3027 if( x509parse_time_expired( &crt->valid_to ) )
3028 *flags = BADCERT_EXPIRED;
Paul Bakker5121ce52009-01-03 21:22:43 +00003029
3030 if( cn != NULL )
3031 {
3032 name = &crt->subject;
3033 cn_len = strlen( cn );
3034
3035 while( name != NULL )
3036 {
Paul Bakkera8cd2392012-02-11 16:09:32 +00003037 if( memcmp( name->oid.p, OID_CN, 3 ) == 0 )
3038 {
3039 if( memcmp( name->val.p, cn, cn_len ) == 0 &&
3040 name->val.len == cn_len )
3041 break;
3042
3043 if( memcmp( name->val.p, "*.", 2 ) == 0 &&
Paul Bakker57b12982012-02-11 17:38:38 +00003044 x509_wildcard_verify( cn, &name->val ) )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003045 break;
3046 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003047
3048 name = name->next;
3049 }
3050
3051 if( name == NULL )
Paul Bakkera8cd2392012-02-11 16:09:32 +00003052 {
3053 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
3054 {
3055 cur = &crt->subject_alt_names;
3056
3057 while( cur != NULL )
3058 {
3059 if( memcmp( cn, cur->buf.p, cn_len ) == 0 &&
3060 cur->buf.len == cn_len )
3061 break;
3062
Paul Bakker57b12982012-02-11 17:38:38 +00003063 if( memcmp( cur->buf.p, "*.", 2 ) == 0 &&
3064 x509_wildcard_verify( cn, &cur->buf ) )
3065 break;
3066
Paul Bakkera8cd2392012-02-11 16:09:32 +00003067 cur = cur->next;
3068 }
3069 }
3070
3071 if( cur == NULL )
3072 *flags |= BADCERT_CN_MISMATCH;
3073 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003074 }
3075
Paul Bakker5121ce52009-01-03 21:22:43 +00003076 /*
3077 * Iterate upwards in the given cert chain,
3078 * ignoring any upper cert with CA != TRUE.
3079 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003080 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003081
3082 pathlen = 1;
3083
Paul Bakker76fd75a2011-01-16 21:12:10 +00003084 while( parent != NULL && parent->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003085 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003086 if( parent->ca_istrue == 0 ||
3087 crt->issuer_raw.len != parent->subject_raw.len ||
3088 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
Paul Bakker5121ce52009-01-03 21:22:43 +00003089 crt->issuer_raw.len ) != 0 )
3090 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003091 parent = parent->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003092 continue;
3093 }
3094
Paul Bakker27d66162010-03-17 06:56:01 +00003095 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00003096
3097 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
3098
Paul Bakker76fd75a2011-01-16 21:12:10 +00003099 if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, hash_id, 0, hash,
3100 crt->sig.p ) != 0 )
3101 *flags |= BADCERT_NOT_TRUSTED;
3102
3103 /* Check trusted CA's CRL for the given crt */
3104 *flags |= x509parse_verifycrl(crt, parent, ca_crl);
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003105
3106 /* crt is verified to be a child of the parent cur, call verify callback */
Paul Bakker74111d32011-01-15 16:57:55 +00003107 if( NULL != f_vrfy )
3108 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003109 if( f_vrfy( p_vrfy, crt, pathlen - 1, ( *flags == 0 ) ) != 0 )
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003110 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker76fd75a2011-01-16 21:12:10 +00003111 else
3112 *flags = 0;
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003113 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00003114 else if( *flags != 0 )
3115 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00003116
3117 pathlen++;
3118
Paul Bakker76fd75a2011-01-16 21:12:10 +00003119 crt = parent;
3120 parent = crt->next;
Paul Bakker5121ce52009-01-03 21:22:43 +00003121 }
3122
3123 /*
Paul Bakker76fd75a2011-01-16 21:12:10 +00003124 * Attempt to validate topmost cert with our CA chain.
Paul Bakker5121ce52009-01-03 21:22:43 +00003125 */
Paul Bakker76fd75a2011-01-16 21:12:10 +00003126 *flags |= BADCERT_NOT_TRUSTED;
3127
Paul Bakker7c6d4a42009-03-28 20:35:47 +00003128 while( trust_ca != NULL && trust_ca->version != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003129 {
3130 if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
3131 memcmp( crt->issuer_raw.p, trust_ca->subject_raw.p,
3132 crt->issuer_raw.len ) != 0 )
3133 {
3134 trust_ca = trust_ca->next;
3135 continue;
3136 }
3137
3138 if( trust_ca->max_pathlen > 0 &&
3139 trust_ca->max_pathlen < pathlen )
3140 break;
3141
Paul Bakker27d66162010-03-17 06:56:01 +00003142 hash_id = crt->sig_alg;
Paul Bakker5121ce52009-01-03 21:22:43 +00003143
3144 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
3145
3146 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
3147 0, hash, crt->sig.p ) == 0 )
3148 {
3149 /*
3150 * cert. is signed by a trusted CA
3151 */
3152 *flags &= ~BADCERT_NOT_TRUSTED;
3153 break;
3154 }
3155
3156 trust_ca = trust_ca->next;
3157 }
3158
Paul Bakker76fd75a2011-01-16 21:12:10 +00003159 /* Check trusted CA's CRL for the given crt */
3160 *flags |= x509parse_verifycrl( crt, trust_ca, ca_crl );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003161
3162 /* Verification succeeded, call callback on top cert */
Paul Bakker74111d32011-01-15 16:57:55 +00003163 if( NULL != f_vrfy )
3164 {
Paul Bakker76fd75a2011-01-16 21:12:10 +00003165 if( f_vrfy(p_vrfy, crt, pathlen-1, ( *flags == 0 ) ) != 0 )
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003166 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakker76fd75a2011-01-16 21:12:10 +00003167 else
3168 *flags = 0;
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003169 }
Paul Bakker76fd75a2011-01-16 21:12:10 +00003170 else if( *flags != 0 )
3171 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
Paul Bakkerb63b0af2011-01-13 17:54:59 +00003172
Paul Bakker5121ce52009-01-03 21:22:43 +00003173 return( 0 );
3174}
3175
3176/*
3177 * Unallocate all certificate data
3178 */
3179void x509_free( x509_cert *crt )
3180{
3181 x509_cert *cert_cur = crt;
3182 x509_cert *cert_prv;
3183 x509_name *name_cur;
3184 x509_name *name_prv;
Paul Bakker74111d32011-01-15 16:57:55 +00003185 x509_sequence *seq_cur;
3186 x509_sequence *seq_prv;
Paul Bakker5121ce52009-01-03 21:22:43 +00003187
3188 if( crt == NULL )
3189 return;
3190
3191 do
3192 {
3193 rsa_free( &cert_cur->rsa );
3194
3195 name_cur = cert_cur->issuer.next;
3196 while( name_cur != NULL )
3197 {
3198 name_prv = name_cur;
3199 name_cur = name_cur->next;
3200 memset( name_prv, 0, sizeof( x509_name ) );
3201 free( name_prv );
3202 }
3203
3204 name_cur = cert_cur->subject.next;
3205 while( name_cur != NULL )
3206 {
3207 name_prv = name_cur;
3208 name_cur = name_cur->next;
3209 memset( name_prv, 0, sizeof( x509_name ) );
3210 free( name_prv );
3211 }
3212
Paul Bakker74111d32011-01-15 16:57:55 +00003213 seq_cur = cert_cur->ext_key_usage.next;
3214 while( seq_cur != NULL )
3215 {
3216 seq_prv = seq_cur;
3217 seq_cur = seq_cur->next;
3218 memset( seq_prv, 0, sizeof( x509_sequence ) );
3219 free( seq_prv );
3220 }
3221
Paul Bakker8afa70d2012-02-11 18:42:45 +00003222 seq_cur = cert_cur->subject_alt_names.next;
3223 while( seq_cur != NULL )
3224 {
3225 seq_prv = seq_cur;
3226 seq_cur = seq_cur->next;
3227 memset( seq_prv, 0, sizeof( x509_sequence ) );
3228 free( seq_prv );
3229 }
3230
Paul Bakker5121ce52009-01-03 21:22:43 +00003231 if( cert_cur->raw.p != NULL )
3232 {
3233 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
3234 free( cert_cur->raw.p );
3235 }
3236
3237 cert_cur = cert_cur->next;
3238 }
3239 while( cert_cur != NULL );
3240
3241 cert_cur = crt;
3242 do
3243 {
3244 cert_prv = cert_cur;
3245 cert_cur = cert_cur->next;
3246
3247 memset( cert_prv, 0, sizeof( x509_cert ) );
3248 if( cert_prv != crt )
3249 free( cert_prv );
3250 }
3251 while( cert_cur != NULL );
3252}
3253
Paul Bakkerd98030e2009-05-02 15:13:40 +00003254/*
3255 * Unallocate all CRL data
3256 */
3257void x509_crl_free( x509_crl *crl )
3258{
3259 x509_crl *crl_cur = crl;
3260 x509_crl *crl_prv;
3261 x509_name *name_cur;
3262 x509_name *name_prv;
3263 x509_crl_entry *entry_cur;
3264 x509_crl_entry *entry_prv;
3265
3266 if( crl == NULL )
3267 return;
3268
3269 do
3270 {
3271 name_cur = crl_cur->issuer.next;
3272 while( name_cur != NULL )
3273 {
3274 name_prv = name_cur;
3275 name_cur = name_cur->next;
3276 memset( name_prv, 0, sizeof( x509_name ) );
3277 free( name_prv );
3278 }
3279
3280 entry_cur = crl_cur->entry.next;
3281 while( entry_cur != NULL )
3282 {
3283 entry_prv = entry_cur;
3284 entry_cur = entry_cur->next;
3285 memset( entry_prv, 0, sizeof( x509_crl_entry ) );
3286 free( entry_prv );
3287 }
3288
3289 if( crl_cur->raw.p != NULL )
3290 {
3291 memset( crl_cur->raw.p, 0, crl_cur->raw.len );
3292 free( crl_cur->raw.p );
3293 }
3294
3295 crl_cur = crl_cur->next;
3296 }
3297 while( crl_cur != NULL );
3298
3299 crl_cur = crl;
3300 do
3301 {
3302 crl_prv = crl_cur;
3303 crl_cur = crl_cur->next;
3304
3305 memset( crl_prv, 0, sizeof( x509_crl ) );
3306 if( crl_prv != crl )
3307 free( crl_prv );
3308 }
3309 while( crl_cur != NULL );
3310}
3311
Paul Bakker40e46942009-01-03 21:51:57 +00003312#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00003313
Paul Bakker40e46942009-01-03 21:51:57 +00003314#include "polarssl/certs.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00003315
3316/*
3317 * Checkup routine
3318 */
3319int x509_self_test( int verbose )
3320{
Paul Bakker5690efc2011-05-26 13:16:06 +00003321#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
Paul Bakker23986e52011-04-24 08:57:21 +00003322 int ret;
3323 int flags;
3324 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00003325 x509_cert cacert;
3326 x509_cert clicert;
3327 rsa_context rsa;
Paul Bakker5690efc2011-05-26 13:16:06 +00003328#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003329 dhm_context dhm;
Paul Bakker5690efc2011-05-26 13:16:06 +00003330#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003331
3332 if( verbose != 0 )
3333 printf( " X.509 certificate load: " );
3334
3335 memset( &clicert, 0, sizeof( x509_cert ) );
3336
3337 ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003338 strlen( test_cli_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003339 if( ret != 0 )
3340 {
3341 if( verbose != 0 )
3342 printf( "failed\n" );
3343
3344 return( ret );
3345 }
3346
3347 memset( &cacert, 0, sizeof( x509_cert ) );
3348
3349 ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +00003350 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003351 if( ret != 0 )
3352 {
3353 if( verbose != 0 )
3354 printf( "failed\n" );
3355
3356 return( ret );
3357 }
3358
3359 if( verbose != 0 )
3360 printf( "passed\n X.509 private key load: " );
3361
3362 i = strlen( test_ca_key );
3363 j = strlen( test_ca_pwd );
3364
Paul Bakker66b78b22011-03-25 14:22:50 +00003365 rsa_init( &rsa, RSA_PKCS_V15, 0 );
3366
Paul Bakker5121ce52009-01-03 21:22:43 +00003367 if( ( ret = x509parse_key( &rsa,
3368 (unsigned char *) test_ca_key, i,
3369 (unsigned char *) test_ca_pwd, j ) ) != 0 )
3370 {
3371 if( verbose != 0 )
3372 printf( "failed\n" );
3373
3374 return( ret );
3375 }
3376
3377 if( verbose != 0 )
3378 printf( "passed\n X.509 signature verify: ");
3379
Paul Bakker23986e52011-04-24 08:57:21 +00003380 ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00003381 if( ret != 0 )
3382 {
Paul Bakker23986e52011-04-24 08:57:21 +00003383 printf("%02x", flags);
Paul Bakker5121ce52009-01-03 21:22:43 +00003384 if( verbose != 0 )
3385 printf( "failed\n" );
3386
3387 return( ret );
3388 }
3389
Paul Bakker5690efc2011-05-26 13:16:06 +00003390#if defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00003391 if( verbose != 0 )
Paul Bakker1b57b062011-01-06 15:48:19 +00003392 printf( "passed\n X.509 DHM parameter load: " );
3393
3394 i = strlen( test_dhm_params );
3395 j = strlen( test_ca_pwd );
3396
3397 if( ( ret = x509parse_dhm( &dhm, (unsigned char *) test_dhm_params, i ) ) != 0 )
3398 {
3399 if( verbose != 0 )
3400 printf( "failed\n" );
3401
3402 return( ret );
3403 }
3404
3405 if( verbose != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003406 printf( "passed\n\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00003407#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003408
3409 x509_free( &cacert );
3410 x509_free( &clicert );
3411 rsa_free( &rsa );
Paul Bakker5690efc2011-05-26 13:16:06 +00003412#if defined(POLARSSL_DHM_C)
Paul Bakker1b57b062011-01-06 15:48:19 +00003413 dhm_free( &dhm );
Paul Bakker5690efc2011-05-26 13:16:06 +00003414#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003415
3416 return( 0 );
Paul Bakkerde4d2ea2009-10-03 19:58:52 +00003417#else
3418 ((void) verbose);
3419 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
3420#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00003421}
3422
3423#endif
3424
3425#endif